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