Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

PluginMgr.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr
00003  *cr            (C) Copyright 1995-2019 The Board of Trustees of the
00004  *cr                        University of Illinois
00005  *cr                         All Rights Reserved
00006  *cr
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *      $RCSfile: PluginMgr.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.39 $       $Date: 2020/10/16 07:11:25 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *  Plugin manager code, loads and registers static and dynamic 
00019  *  plugins, does version checks, etc.
00020  * 
00021  * LICENSE:
00022  *   UIUC Open Source License
00023  *   http://www.ks.uiuc.edu/Research/vmd/plugins/pluginlicense.html
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 // return true of a plugin is the same or older than ones we already have
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) &&           // only load new ones
00049          ((newp->majorv < oldp->majorv) ||           // only load new ones
00050           (newp->minorv <= oldp->minorv)) &&
00051          !strcmp(newp->author, oldp->author) &&
00052          (newp->is_reentrant == oldp->is_reentrant); // reentrant comes first
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   // check that the ABI version matches
00093   if (plugin->abiversion != vmdplugin_ABIVERSION) {
00094     msgWarn << "Rejecting plugin with incorrect ABI version: "
00095             << self->curpath << sendmsg;
00096     return -1;
00097   }
00098 
00099   // check that there are no null terms in the plugin
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   // check new plugin against already-loaded plugins
00107   for (int i=0; i<self->pluginlist.num(); i++) {
00108     if (plugincmp(plugin, self->pluginlist[i])) {
00109       // don't add new plugin if we already have an identical or older version
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   // Open the dll; try to execute the init function.
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     // Load plugins from the library.
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

Generated on Wed Oct 9 02:43:22 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002