Logo Search packages:      
Sourcecode: hitop version File versions

pluginmgr.cc

#include "pluginmgr.h"
#include "html.h"
#include "error.h"
#include "plugin.h"

#include <pwd.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#ifndef __NO_DYNAMIC_MODULES__
#include <dlfcn.h>
#endif

string PluginManager::s_loadpath; // a string seperated list of directories

void PluginManager::Init() {
  char* cenv = getenv("HITOPLIBS");
  if (NULL!=cenv) {
    s_loadpath=cenv;
  } else {
    // we need to generate a s_loadpath
    passwd *userent = getpwuid(geteuid());
    if (NULL!=userent) {
      s_loadpath = userent->pw_dir;
      s_loadpath.append("/.hitop /usr/local/lib/hitop /usr/lib/hitop");
    } else {
      s_loadpath = "/usr/local/lib/hitop /usr/lib/hitop";
      // hmm. should we also mail root and ask them to add a line into /etc/passwd for <euid>?
    }
  }
}

void PluginManager::Load(HTMLStream::iterator cur,const string& extensionname,
  const string& fnnamespace,int version) {
  if (!StaticLoad(cur,extensionname,fnnamespace,version)) {
#ifndef __NO_DYNAMIC_MODULES__
    if (!DLLoad(cur,extensionname,fnnamespace,version)) {
      Error(*cur,"Module could not be loaded");
    }; 
#else
    Error(*cur,"Module is not included in this version.");
#endif
  }
}

bool PluginManager::StaticLoad(HTMLStream::iterator cur,const string&
  extensionname,const string& fnnamespace,int version) {
  if (Plugin::s_modulemap==NULL) return false;
  map<string,Plugin*>::iterator mod=Plugin::s_modulemap->find(extensionname);
  if (mod==Plugin::s_modulemap->end()) return false;
  if (mod->second==NULL) return true; // The module is already initialised.
  if (mod->second->m_version < version) {
    Error(*cur,"Module is not of required version");
  }
  if (!fnnamespace.empty()) {
    mod->second->ForceNamespace(fnnamespace);
  }
  mod->second->Init();
  mod->second=NULL;
  return true;
}

bool PluginManager::DLLoad(HTMLStream::iterator cur, string
  extensionname,const string& fnnamespace,int version) {
#ifndef __NO_DYNAMIC_MODULES__
  string pluginname=extensionname;
  bool found=false;
  if (s_loadpath.empty()) {
    Error(*cur,"Attempted to load a plugin, but the plugin path has been explicitly unset");
  } else if (extensionname.empty()) {
    Error(*cur,"No module name given");
  } else {

#ifdef unix
   extensionname.append(".so");
#else
#error "The file extension for modules is not known for this platform"
#endif

    string::iterator i,j=s_loadpath.begin();
    i=j;
    while (!found && (i!=s_loadpath.end())) {
      i=find(j,s_loadpath.end(),' ');
      string temppath(j,i);
      temppath.append("/"+extensionname);
      found=(NULL!=dlopen(temppath.c_str(),RTLD_NOW));
      j=i;
      if (j!=s_loadpath.end()) ++j;
    }
  } 
  if (!found) {
    Error(*cur,"Unable to load module");
  }
  map<string,Plugin*>::iterator mod=Plugin::s_modulemap->find(pluginname);
  if (mod==Plugin::s_modulemap->end()) return false;
  if (mod->second->m_version < version) {
    Error(*cur,"Module is not of required version");
  }
  if (!fnnamespace.empty()) {
    mod->second->ForceNamespace(fnnamespace);
  }
  mod->second->Init();
  mod->second=NULL;
  return true;
#else
  Error(*cur,"Dynamically loaded modules are not supported on this architecture");
#endif
}


Generated by  Doxygen 1.6.0   Back to index