gwenhywfar
4.3.3
|
00001 /*************************************************************************** 00002 $RCSfile$ 00003 ------------------- 00004 cvs : $Id$ 00005 begin : Thu Apr 03 2003 00006 copyright : (C) 2003 by Martin Preuss 00007 email : martin@libchipcard.de 00008 00009 *************************************************************************** 00010 * * 00011 * This library is free software; you can redistribute it and/or * 00012 * modify it under the terms of the GNU Lesser General Public * 00013 * License as published by the Free Software Foundation; either * 00014 * version 2.1 of the License, or (at your option) any later version. * 00015 * * 00016 * This library is distributed in the hope that it will be useful, * 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00019 * Lesser General Public License for more details. * 00020 * * 00021 * You should have received a copy of the GNU Lesser General Public * 00022 * License along with this library; if not, write to the Free Software * 00023 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * 00024 * MA 02111-1307 USA * 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(void){ 00066 gwen_plugin_manager__list=GWEN_PluginManager_List_new(); 00067 return 0; 00068 } 00069 00070 00071 00072 int GWEN_Plugin_ModuleFini(void){ 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 } /* if refCount reaches zero */ 00116 } /* if p */ 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 /* open the key */ 00278 if (RegOpenKey(HKEY_LOCAL_MACHINE, nbuffer, &hkey)){ 00279 DBG_INFO(GWEN_LOGDOMAIN, "RegOpenKey %s failed.", keypath); 00280 return 1; 00281 } 00282 00283 /* find the variablename */ 00284 for (i=0;; i++) { 00285 nsize=sizeof(nbuffer); 00286 vsize=sizeof(vbuffer); 00287 if (ERROR_SUCCESS!=RegEnumValue(hkey, 00288 i, /* index */ 00289 nbuffer, 00290 &nsize, 00291 0, /* reserved */ 00292 &typ, 00293 vbuffer, 00294 &vsize)) 00295 break; 00296 if (strcasecmp(nbuffer, varname)==0 && typ==REG_SZ) { 00297 /* variable found */ 00298 RegCloseKey(hkey); 00299 return GWEN_PathManager_AddPath(callingLib, 00300 pm->destLib, 00301 pm->name, 00302 (char*)vbuffer); 00303 } 00304 } /* for */ 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 /* OS_WIN32 */ 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 /* OS_WIN32 */ 00323 00324 00325 00326 GWEN_PLUGIN *GWEN_PluginManager_LoadPlugin(GWEN_PLUGIN_MANAGER *pm, 00327 const char *modname){ 00328 GWEN_LIBLOADER *ll; 00329 GWEN_PLUGIN *plugin; 00330 GWEN_PLUGIN_FACTORYFN fn; 00331 void *p; 00332 GWEN_BUFFER *nbuf; 00333 const char *s; 00334 const char *fname; 00335 int err; 00336 GWEN_STRINGLIST *sl; 00337 GWEN_STRINGLISTENTRY *se; 00338 00339 assert(pm); 00340 ll=GWEN_LibLoader_new(); 00341 sl=GWEN_PathManager_GetPaths(pm->destLib, pm->name); 00342 if (sl==NULL) { 00343 DBG_ERROR(GWEN_LOGDOMAIN, "No paths for plugins (%s)", pm->name); 00344 GWEN_LibLoader_free(ll); 00345 return NULL; 00346 } 00347 nbuf=GWEN_Buffer_new(0, 128, 0, 1); 00348 s=modname; 00349 while(*s) GWEN_Buffer_AppendByte(nbuf, tolower(*(s++))); 00350 se=GWEN_StringList_FirstEntry(sl); 00351 fname=0; 00352 while(se) { 00353 fname=GWEN_StringListEntry_Data(se); 00354 assert(fname); 00355 if (GWEN_LibLoader_OpenLibraryWithPath(ll, fname, 00356 GWEN_Buffer_GetStart(nbuf))==0) 00357 break; 00358 else { 00359 DBG_DEBUG(GWEN_LOGDOMAIN, 00360 "Could not load plugin \"%s\" from \"%s\"", modname, fname); 00361 } 00362 se=GWEN_StringListEntry_Next(se); 00363 } 00364 if (!se) { 00365 DBG_ERROR(GWEN_LOGDOMAIN, "Plugin \"%s\" not found.", modname); 00366 GWEN_Buffer_free(nbuf); 00367 GWEN_StringList_free(sl); 00368 GWEN_LibLoader_free(ll); 00369 return NULL; 00370 } 00371 GWEN_Buffer_free(nbuf); 00372 00373 /* create name of init function */ 00374 nbuf=GWEN_Buffer_new(0, 128, 0, 1); 00375 s=pm->name; 00376 while(*s) GWEN_Buffer_AppendByte(nbuf, tolower(*(s++))); 00377 GWEN_Buffer_AppendByte(nbuf, '_'); 00378 s=modname; 00379 while(*s) GWEN_Buffer_AppendByte(nbuf, tolower(*(s++))); 00380 GWEN_Buffer_AppendString(nbuf, "_factory"); 00381 00382 /* resolve name of factory function */ 00383 err=GWEN_LibLoader_Resolve(ll, GWEN_Buffer_GetStart(nbuf), &p); 00384 if (err) { 00385 DBG_ERROR_ERR(GWEN_LOGDOMAIN, err); 00386 GWEN_Buffer_free(nbuf); 00387 GWEN_LibLoader_CloseLibrary(ll); 00388 GWEN_StringList_free(sl); 00389 GWEN_LibLoader_free(ll); 00390 return 0; 00391 } 00392 GWEN_Buffer_free(nbuf); 00393 00394 fn=(GWEN_PLUGIN_FACTORYFN)p; 00395 assert(fn); 00396 plugin=fn(pm, modname, fname); 00397 if (!plugin) { 00398 DBG_ERROR(GWEN_LOGDOMAIN, "Error in plugin: No plugin created"); 00399 GWEN_LibLoader_CloseLibrary(ll); 00400 GWEN_StringList_free(sl); 00401 GWEN_LibLoader_free(ll); 00402 return 0; 00403 } 00404 00405 /* store libloader */ 00406 GWEN_StringList_free(sl); 00407 GWEN_Plugin_SetLibLoader(plugin, ll); 00408 return plugin; 00409 } 00410 00411 00412 00413 GWEN_PLUGIN *GWEN_PluginManager_LoadPluginFile(GWEN_PLUGIN_MANAGER *pm, 00414 const char *modname, 00415 const char *fname){ 00416 GWEN_LIBLOADER *ll; 00417 GWEN_PLUGIN *plugin; 00418 GWEN_PLUGIN_FACTORYFN fn; 00419 void *p; 00420 GWEN_BUFFER *nbuf; 00421 const char *s; 00422 int err; 00423 00424 ll=GWEN_LibLoader_new(); 00425 if (GWEN_LibLoader_OpenLibrary(ll, fname)) { 00426 DBG_INFO(GWEN_LOGDOMAIN, 00427 "Could not load plugin \"%s\" (%s)", modname, fname); 00428 GWEN_LibLoader_free(ll); 00429 return 0; 00430 } 00431 00432 /* create name of init function */ 00433 nbuf=GWEN_Buffer_new(0, 128, 0, 1); 00434 s=pm->name; 00435 while(*s) GWEN_Buffer_AppendByte(nbuf, tolower(*(s++))); 00436 GWEN_Buffer_AppendByte(nbuf, '_'); 00437 s=modname; 00438 while(*s) GWEN_Buffer_AppendByte(nbuf, tolower(*(s++))); 00439 GWEN_Buffer_AppendString(nbuf, "_factory"); 00440 00441 /* resolve name of factory function */ 00442 err=GWEN_LibLoader_Resolve(ll, GWEN_Buffer_GetStart(nbuf), &p); 00443 if (err) { 00444 DBG_INFO_ERR(GWEN_LOGDOMAIN, err); 00445 GWEN_Buffer_free(nbuf); 00446 GWEN_LibLoader_CloseLibrary(ll); 00447 GWEN_LibLoader_free(ll); 00448 return 0; 00449 } 00450 GWEN_Buffer_free(nbuf); 00451 00452 fn=(GWEN_PLUGIN_FACTORYFN)p; 00453 assert(fn); 00454 plugin=fn(pm, modname, fname); 00455 if (!plugin) { 00456 DBG_INFO(GWEN_LOGDOMAIN, "Error in plugin: No plugin created"); 00457 GWEN_LibLoader_CloseLibrary(ll); 00458 GWEN_LibLoader_free(ll); 00459 return 0; 00460 } 00461 00462 /* store libloader */ 00463 GWEN_Plugin_SetLibLoader(plugin, ll); 00464 00465 return plugin; 00466 } 00467 00468 00469 00470 GWEN_PLUGIN *GWEN_PluginManager__FindPlugin(GWEN_PLUGIN_MANAGER *pm, 00471 const char *s){ 00472 GWEN_PLUGIN *p; 00473 00474 assert(pm); 00475 p=GWEN_Plugin_List_First(pm->plugins); 00476 while(p) { 00477 if (strcasecmp(p->name, s)==0) 00478 break; 00479 p=GWEN_Plugin_List_Next(p); 00480 } 00481 00482 return p; 00483 } 00484 00485 00486 00487 GWEN_PLUGIN *GWEN_PluginManager_GetPlugin(GWEN_PLUGIN_MANAGER *pm, 00488 const char *s){ 00489 GWEN_PLUGIN *p; 00490 00491 p=GWEN_PluginManager__FindPlugin(pm, s); 00492 if (p) 00493 return p; 00494 p=GWEN_PluginManager_LoadPlugin(pm, s); 00495 if (p) { 00496 GWEN_Plugin_List_Add(p, pm->plugins); 00497 return p; 00498 } 00499 DBG_INFO(GWEN_LOGDOMAIN, "Plugin \"%s\" not found", s); 00500 return 0; 00501 } 00502 00503 00504 00505 GWEN_PLUGIN_MANAGER *GWEN_PluginManager_FindPluginManager(const char *s){ 00506 GWEN_PLUGIN_MANAGER *pm; 00507 00508 pm=GWEN_PluginManager_List_First(gwen_plugin_manager__list); 00509 while(pm) { 00510 if (strcasecmp(pm->name, s)==0) 00511 break; 00512 pm=GWEN_PluginManager_List_Next(pm); 00513 } 00514 00515 return pm; 00516 } 00517 00518 00519 00520 int GWEN_PluginManager_Register(GWEN_PLUGIN_MANAGER *pm){ 00521 GWEN_PLUGIN_MANAGER *tpm; 00522 int rv; 00523 00524 assert(gwen_plugin_manager__list); 00525 assert(pm); 00526 tpm=GWEN_PluginManager_FindPluginManager(pm->name); 00527 if (tpm) { 00528 DBG_ERROR(GWEN_LOGDOMAIN, 00529 "Plugin type \"%s\" already registered", 00530 pm->name); 00531 return -1; 00532 } 00533 00534 rv=GWEN_PathManager_DefinePath(pm->destLib, pm->name); 00535 if (rv) { 00536 DBG_INFO(GWEN_LOGDOMAIN, "Could not define path for plugin [%s:%s]", 00537 pm->destLib, pm->name); 00538 return rv; 00539 } 00540 00541 GWEN_PluginManager_List_Add(pm, gwen_plugin_manager__list); 00542 DBG_INFO(GWEN_LOGDOMAIN, 00543 "Plugin type \"%s\" registered", 00544 pm->name); 00545 return 0; 00546 } 00547 00548 00549 00550 int GWEN_PluginManager_Unregister(GWEN_PLUGIN_MANAGER *pm){ 00551 GWEN_PLUGIN_MANAGER *tpm; 00552 int rv; 00553 00554 assert(gwen_plugin_manager__list); 00555 assert(pm); 00556 tpm=GWEN_PluginManager_FindPluginManager(pm->name); 00557 if (!tpm) { 00558 DBG_ERROR(GWEN_LOGDOMAIN, 00559 "Plugin type \"%s\" not registered", 00560 pm->name); 00561 return -1; 00562 } 00563 00564 rv=GWEN_PathManager_UndefinePath(pm->destLib, pm->name); 00565 if (rv) { 00566 DBG_INFO(GWEN_LOGDOMAIN, "Could not undefine path for plugin [%s:%s]", 00567 pm->destLib, pm->name); 00568 return rv; 00569 } 00570 00571 GWEN_PluginManager_List_Del(pm); 00572 DBG_INFO(GWEN_LOGDOMAIN, 00573 "Plugin type \"%s\" unregistered", 00574 pm->name); 00575 return 0; 00576 } 00577 00578 00579 00580 GWEN_PLUGIN_DESCRIPTION_LIST2* 00581 GWEN_PluginManager_GetPluginDescrs(GWEN_PLUGIN_MANAGER *pm){ 00582 GWEN_PLUGIN_DESCRIPTION_LIST2 *pl; 00583 GWEN_STRINGLIST *sl; 00584 GWEN_STRINGLISTENTRY *se; 00585 00586 sl=GWEN_PathManager_GetPaths(pm->destLib, pm->name); 00587 if (sl==NULL) { 00588 DBG_ERROR(GWEN_LOGDOMAIN, "No paths for plugins (%s)", pm->name); 00589 return NULL; 00590 } 00591 se=GWEN_StringList_FirstEntry(sl); 00592 if (!se) { 00593 DBG_ERROR(GWEN_LOGDOMAIN, "No paths given"); 00594 GWEN_StringList_free(sl); 00595 return 0; 00596 } 00597 00598 pl=GWEN_PluginDescription_List2_new(); 00599 while(se) { 00600 int rv; 00601 const char *path; 00602 00603 path=GWEN_StringListEntry_Data(se); 00604 assert(path); 00605 rv=GWEN_LoadPluginDescrsByType(path, pm->name, pl); 00606 if (rv) { 00607 DBG_INFO(GWEN_LOGDOMAIN, 00608 "Error loading plugin description in \"%s\"", path); 00609 } 00610 se=GWEN_StringListEntry_Next(se); 00611 } /* while */ 00612 00613 if (GWEN_PluginDescription_List2_GetSize(pl)==0) { 00614 GWEN_PluginDescription_List2_free(pl); 00615 GWEN_StringList_free(sl); 00616 return 0; 00617 } 00618 00619 GWEN_StringList_free(sl); 00620 return pl; 00621 } 00622 00623 00624 GWEN_STRINGLIST *GWEN_PluginManager_GetPaths(const GWEN_PLUGIN_MANAGER *pm){ 00625 assert(pm); 00626 return GWEN_PathManager_GetPaths(pm->destLib, pm->name); 00627 } 00628 00629 00630 00631 GWEN_PLUGIN_DESCRIPTION* 00632 GWEN_PluginManager_GetPluginDescr(GWEN_PLUGIN_MANAGER *pm, 00633 const char *modName) { 00634 GWEN_PLUGIN_DESCRIPTION_LIST2 *dl; 00635 00636 dl=GWEN_PluginManager_GetPluginDescrs(pm); 00637 if (dl==0) 00638 return 0; 00639 else { 00640 GWEN_PLUGIN_DESCRIPTION_LIST2_ITERATOR *dit; 00641 00642 dit=GWEN_PluginDescription_List2_First(dl); 00643 if (dit) { 00644 GWEN_PLUGIN_DESCRIPTION *d; 00645 00646 d=GWEN_PluginDescription_List2Iterator_Data(dit); 00647 while(d) { 00648 if (strcasecmp(GWEN_PluginDescription_GetName(d), modName)==0) 00649 break; 00650 d=GWEN_PluginDescription_List2Iterator_Next(dit); 00651 } 00652 GWEN_PluginDescription_List2Iterator_free(dit); 00653 00654 if (d) { 00655 d=GWEN_PluginDescription_dup(d); 00656 GWEN_PluginDescription_List2_freeAll(dl); 00657 return d; 00658 } 00659 } 00660 GWEN_PluginDescription_List2_freeAll(dl); 00661 } 00662 00663 return 0; 00664 } 00665 00666 00667 00668 void GWEN_PluginManager_AddPlugin(GWEN_PLUGIN_MANAGER *pm, GWEN_PLUGIN *p) { 00669 #if 0 00670 DBG_ERROR(0, "Adding plugin [%s] of type [%s]", 00671 p->name, pm->name); 00672 #endif 00673 GWEN_Plugin_List_Add(p, pm->plugins); 00674 } 00675 00676 00677 00678 00679 00680