/* $Id$ */ #include "sr_module.h" #include "dprint.h" #include <dlfcn.h> #include <strings.h> #include <stdlib.h> static struct sr_module* modules=0; /* returns 0 on success , <0 on error */ int load_module(char* path) { void* handle; char* error; struct sr_module* t, *mod; struct module_exports* e; struct module_exports* (*mod_register)(); handle=dlopen(path, RTLD_NOW); /* resolve all symbols now */ if (handle==0){ LOG(L_ERR, "ERROR: load_module: could not open module <%s>: %s\n", path, dlerror() ); goto error; } for(t=modules;t; t=t->next){ if (t->handle==handle){ LOG(L_WARN, "WARNING: load_module: attempting to load the same" " module twice (%s)\n", path); goto skip; } } /* launch register */ mod_register = dlsym(handle, "mod_register"); if ( (error =dlerror())!=0 ){ LOG(L_ERR, "ERROR: load_module: %s\n", error); goto error1; } e=(*mod_register)(); if (e==0){ LOG(L_ERR, "ERROR: mod_register returned null\n"); goto error1; } /* add module to the list */ if ((mod=malloc(sizeof(struct sr_module)))==0){ LOG(L_ERR, "load_module: memory allocation failure\n"); goto error1; } memset(mod,0, sizeof(struct sr_module)); mod->path=path; mod->handle=handle; mod->exports=e; mod->next=modules; modules=mod; return 0; error1: dlclose(handle); error: skip: return -1; } /* searches the module list and returns a pointer to the "name" function or * 0 if not found */ cmd_function find_export(char* name, int param_no) { struct sr_module* t; int r; for(t=modules;t;t=t->next){ for(r=0;r<t->exports->cmd_no;r++){ if((strcmp(name, t->exports->cmd_names[r])==0)&& (t->exports->param_no[r]==param_no) ){ DBG("find_export: found <%s> in module %s [%s]\n", name, t->exports->name, t->path); return t->exports->cmd_pointers[r]; } } } DBG("find_export: <%s> not found \n", name); return 0; } /* finds a module, given a pointer to a module function * * returns pointer to module, & if i i!=0, *i=the function index */ struct sr_module* find_module(void* f, int *i) { struct sr_module* t; int r; for (t=modules;t;t=t->next){ for(r=0;r<t->exports->cmd_no;r++) if (f==t->exports->cmd_pointers[r]) { if (i) *i=r; return t; } } return 0; }