00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "PluginMgr.h"
00023 #include "vmddlopen.h"
00024 #include "Inform.h"
00025 #include <stdlib.h>
00026 #include <stdio.h>
00027
00028 #ifdef VMDSTATICPLUGINS
00029 #include "libmolfile_plugin.h"
00030 #endif
00031
00032 extern "C" {
00033 typedef int (*initfunc)(void);
00034 typedef int (*regfunc)(void *, vmdplugin_register_cb);
00035 typedef int(* finifunc)(void);
00036 }
00037
00038
00039 static int plugincmp(const vmdplugin_t *newp, const vmdplugin_t *oldp) {
00040 int issameorolder =
00041 !strcmp(newp->type, oldp->type) &&
00042 !strcmp(newp->name, oldp->name) &&
00043 (newp->majorv <= oldp->majorv) &&
00044 ((newp->majorv < oldp->majorv) ||
00045 (newp->minorv <= oldp->minorv)) &&
00046 !strcmp(newp->author, oldp->author) &&
00047 (newp->is_reentrant == oldp->is_reentrant);
00048
00049 return issameorolder;
00050 }
00051
00052 PluginMgr::PluginMgr() {
00053 #ifdef VMDSTATICPLUGINS
00054 MOLFILE_INIT_ALL
00055 #endif
00056 }
00057
00058 PluginMgr::~PluginMgr() {
00059 int i;
00060 for (i=0; i<handlelist.num(); i++) {
00061 void *ffunc = vmddlsym(handlelist[i], "vmdplugin_fini");
00062 if (ffunc) {
00063 ((finifunc)(ffunc))();
00064 }
00065 vmddlclose(handlelist[i]);
00066 }
00067 #ifdef VMDSTATICPLUGINS
00068 MOLFILE_FINI_ALL
00069 #endif
00070 }
00071
00072 int PluginMgr::load_static_plugins() {
00073 #ifdef VMDSTATICPLUGINS
00074 num_in_library = 0;
00075 curpath = "statically linked.";
00076 MOLFILE_REGISTER_ALL(this, register_cb)
00077 return 1;
00078 #else
00079 return 0;
00080 #endif
00081 }
00082
00083
00084 int PluginMgr::register_cb(void *v, vmdplugin_t *plugin) {
00085 PluginMgr *self = (PluginMgr *)v;
00086
00087
00088 if (plugin->abiversion != vmdplugin_ABIVERSION) {
00089 msgWarn << "Rejecting plugin with incorrect ABI version: "
00090 << self->curpath << sendmsg;
00091 return -1;
00092 }
00093
00094
00095 if (!plugin->type || !plugin->name || !plugin->author) {
00096 msgWarn << "Rejecting plugin with NULL header values."
00097 << self->curpath << sendmsg;
00098 return -1;
00099 }
00100
00101
00102 for (int i=0; i<self->pluginlist.num(); i++) {
00103 if (plugincmp(plugin, self->pluginlist[i])) {
00104
00105 return 0;
00106 }
00107 }
00108
00109 self->num_in_library++;
00110 self->pluginlist.append(plugin);
00111 return 0;
00112 }
00113
00114 int PluginMgr::load_sharedlibrary_plugins(const char *fullpath) {
00115
00116 void *handle = vmddlopen(fullpath);
00117 if (!handle) {
00118 msgErr << "Unable to open dynamic library '" << fullpath << "'." << sendmsg;
00119 msgErr << vmddlerror() << sendmsg;
00120 return -1;
00121 }
00122
00123 if (handlelist.find(handle) >= 0) {
00124 msgWarn << "Already have a handle to the shared library "
00125 << fullpath << "." << sendmsg;
00126 return 0;
00127 }
00128
00129 void *ifunc = vmddlsym(handle, "vmdplugin_init");
00130 if (ifunc && ((initfunc)(ifunc))()) {
00131 msgErr << "vmdplugin_init() for " << fullpath
00132 << " returned an error; plugin(s) not loaded." << sendmsg;
00133 vmddlclose(handle);
00134 return 0;
00135 }
00136 handlelist.append(handle);
00137
00138 void *registerfunc = vmddlsym(handle, "vmdplugin_register");
00139 num_in_library = 0;
00140 curpath = fullpath;
00141 if (!registerfunc) {
00142 msgWarn << "Didn't find the register function in" << fullpath
00143 << "; plugin(s) not loaded." << sendmsg;
00144 } else {
00145
00146 ((regfunc)registerfunc)(this, register_cb);
00147 }
00148 return num_in_library;
00149 }
00150
00151 int PluginMgr::plugins(PluginList &pl, const char *type, const char *name) {
00152 int nfound = 0;
00153 for (int i=0; i<pluginlist.num(); i++) {
00154 vmdplugin_t *p = pluginlist[i];
00155 if (type && strcmp(p->type, type)) continue;
00156 if (name && strcmp(p->name, name)) continue;
00157 pl.append(p);
00158 nfound++;
00159 }
00160 return nfound;
00161 }
00162
00163 #ifdef TEST_PLUGIN_MGR
00164
00165 int main(int argc, char *argv[]) {
00166 PluginMgr *mgr = new PluginMgr;
00167 for (int i=1; i<argc; i++) {
00168 int rc = mgr->load_sharedlibrary_plugins(argv[i]);
00169 printf("Scanning plugin %s returned %d\n", argv[i], rc);
00170 }
00171 PluginList *pl = mgr->plugins();
00172 printf("found %d plugins\n", pl->num());
00173 for (int i=0; i<pl->num(); i++) {
00174 Plugin *p = (*pl)[i];
00175 printf("type: %s\nname: %s\nauthor: %s\n",
00176 p->type(), p->name(), p->author());
00177 printf("version %d%d\n", p->majorv(), p->minorv());
00178 printf("is%sreentrant\n", p->is_reentrant() ? " " : " not ");
00179 }
00180 delete pl;
00181 delete mgr;
00182 return 0;
00183 }
00184
00185 #endif