lib/eggdrop/module.h File Reference

Go to the source code of this file.

Data Structures

struct  egg_module

Defines

#define MODULE_USER   0
#define MODULE_SHUTDOWN   1
#define MODULE_RESTART   2
#define BTN_LOAD_MODULE   "load"
#define BTN_UNLOAD_MODULE   "unload"
#define EXPORT_SCOPE

Typedefs

typedef struct egg_module egg_module_t
typedef int(* egg_start_func_t )(egg_module_t *modinfo)
typedef int(* egg_close_func_t )(int why)
typedef void(* egg_unload_func_t )(void)
typedef void(* egg_cleanup_hook_t )(egg_module_t *mod)

Functions

int module_init (void)
int module_shutdown (void)
 Shuts down the module interface.
int module_add_dir (const char *moddir)
int module_load (const char *name)
 Load a module.
int module_loaded (const char *name)
int module_unload (const char *name, int why)
 Unload a module.
egg_module_tmodule_lookup (const char *name)
void * module_get_api (const char *name, int major, int minor)
int module_addref (const char *name)
int module_decref (const char *name)
int module_list (const char ***names)


Define Documentation

#define BTN_LOAD_MODULE   "load"

Definition at line 31 of file module.h.

Referenced by module_init().

#define BTN_UNLOAD_MODULE   "unload"

Definition at line 32 of file module.h.

Referenced by module_init().

#define EXPORT_SCOPE

Definition at line 75 of file module.h.

#define MODULE_RESTART   2

Definition at line 28 of file module.h.

Referenced by module_shutdown().

#define MODULE_SHUTDOWN   1

Definition at line 27 of file module.h.

Referenced by module_unload().

#define MODULE_USER   0

Definition at line 26 of file module.h.

Referenced by module_unload(), party_unloadmod(), and script_module_unload().


Typedef Documentation

typedef void(* egg_cleanup_hook_t)(egg_module_t *mod)

Definition at line 40 of file module.h.

typedef int(* egg_close_func_t)(int why)

Definition at line 38 of file module.h.

typedef struct egg_module egg_module_t

Definition at line 35 of file module.h.

typedef int(* egg_start_func_t)(egg_module_t *modinfo)

Definition at line 37 of file module.h.

typedef void(* egg_unload_func_t)(void)

Definition at line 39 of file module.h.


Function Documentation

int module_add_dir ( const char *  moddir  ) 

Definition at line 95 of file module.c.

References egg_mprintf().

Referenced by core_init().

00096 {
00097   char *fixed_moddir;
00098 
00099   if (*moddir != '/') {
00100     char cwd[1024];
00101 
00102     cwd[0] = 0;
00103     getcwd(cwd, sizeof(cwd));
00104     cwd[sizeof(cwd)-1] = 0;
00105     fixed_moddir = egg_mprintf("%s/%s", cwd, moddir);
00106   }
00107   else fixed_moddir = (char *)moddir;
00108 
00109   lt_dladdsearchdir(fixed_moddir);
00110   if (fixed_moddir != moddir) free(fixed_moddir);
00111   return(0);
00112 }

int module_addref ( const char *  name  ) 

Definition at line 320 of file module.c.

References find_active_module, and module_list::refcount.

00321 {
00322   module_list_t *entry;
00323 
00324   entry = find_active_module(name);
00325   if (!entry) return(-1);
00326   entry->refcount++;
00327   return(0);
00328 }

int module_decref ( const char *  name  ) 

Definition at line 330 of file module.c.

References find_active_module, and module_list::refcount.

00331 {
00332   module_list_t *entry;
00333 
00334   entry = find_active_module(name);
00335   if (!entry) return(-1);
00336   entry->refcount--;
00337   return(0);
00338 }

void* module_get_api ( const char *  name,
int  major,
int  minor 
)

Definition at line 310 of file module.c.

References find_active_module, module_list::modinfo, egg_module::module_api, NULL, and module_list::refcount.

Referenced by chanserv_init().

00311 {
00312   module_list_t *entry;
00313 
00314   entry = find_active_module(name);
00315   if (!entry) return(NULL);
00316   entry->refcount++;
00317   return entry->modinfo.module_api;
00318 }

int module_init ( void   ) 

Definition at line 54 of file module.c.

References bind_table_add(), BTN_LOAD_MODULE, BTN_UNLOAD_MODULE, and MATCH_MASK.

Referenced by eggdrop_init().

00055 {
00056   BT_load = bind_table_add(BTN_LOAD_MODULE, 1, "s", MATCH_MASK, 0);   /* DDD  */
00057   BT_unload = bind_table_add(BTN_UNLOAD_MODULE, 2, "ss", MATCH_MASK, 0);    /* DDD  */
00058   return(0);
00059 }

int module_list ( const char ***  names  ) 

Definition at line 340 of file module.c.

References module_list::modinfo, egg_module::name, module_list::next, and NULL.

Referenced by party_modules().

00341 {
00342   module_list_t *entry;
00343   int i = 0;
00344 
00345   for (entry = module_list_head; entry; entry = entry->next) i++;
00346   *names = malloc((i + 1) * sizeof(char **));
00347   i = 0;
00348   for (entry = module_list_head; entry; entry = entry->next) {
00349     (*names)[i] = entry->modinfo.name;
00350     i++;
00351   }
00352   (*names)[i] = NULL;
00353   return(i);
00354 }

int module_load ( const char *  name  ) 

Load a module.

This function loads a module and executes its start function. If the module name does not contain a path the default paths will be searched. If it does have an extenteion the plattforms default library extentions will be added.

Parameters:
name The name of the module to load.
Returns:
0 on success. (This will be logged.)

-1 if the module is already loaded. (Nothing will be logged.)

-2 if the module could not be opened. (This will be logged.)

-3 if no start function is present. (Nothing will be logged.)

-4 if the start function returned an error. (Nothing will be logged.)

-5 if the module can't be loaded because it's marked for unloading. (Nothing will be logged.)

Definition at line 131 of file module.c.

References bind_check(), egg_mprintf(), find_active_module, find_deleted_module, module_list::hand, LOG_MISC, module_list::modinfo, module_list::next, NULL, module_list::prev, putlog(), and module_list::refcount.

Referenced by core_init(), and party_loadmod().

00132 {
00133   lt_dlhandle hand;
00134   module_list_t *entry;
00135   egg_start_func_t startfunc;
00136   char *startname;
00137 
00138 
00139   /* See if it's already loaded. */
00140   entry = find_active_module(name);
00141   if (entry) return(-1);
00142   entry = find_deleted_module(name);
00143   if (entry) return(-5);
00144 
00145   hand = lt_dlopenext(name);
00146   if (!hand) {
00147     const char *err = lt_dlerror();
00148     putlog(LOG_MISC, "*", "Error loading module %s: %s", name, err);
00149     return(-2);
00150   }
00151 
00152   startname = egg_mprintf("%s_LTX_start", name);
00153   startfunc = (egg_start_func_t)lt_dlsym(hand, startname);
00154   free(startname);
00155   if (!startfunc) {
00156     startfunc = (egg_start_func_t)lt_dlsym(hand, "start");
00157     if (!startfunc) {
00158       lt_dlclose(hand);
00159       return(-3);
00160     }
00161   }
00162 
00163   /* Create an entry for it. */
00164   entry = calloc(1, sizeof(*entry));
00165   entry->prev = NULL;
00166   entry->next = module_list_head;
00167   entry->refcount = 0;
00168   entry->hand = hand;
00169   module_list_head = entry;
00170 
00171   if (startfunc(&entry->modinfo)) {
00172     module_list_head = module_list_head->next;
00173     free(entry);
00174     return(-4);
00175   }
00176 
00177   putlog(LOG_MISC, "*", "Module loaded: %s", name);
00178   bind_check(BT_load, NULL, name, name);
00179 
00180   return(0);
00181 }

int module_loaded ( const char *  name  ) 

Definition at line 303 of file module.c.

References find_active_module, and NULL.

00304 {
00305   if (name == NULL) return 0;
00306 
00307   return (find_active_module(name) != NULL);
00308 }

egg_module_t* module_lookup ( const char *  name  ) 

Definition at line 294 of file module.c.

References find_active_module, module_list::modinfo, and NULL.

00295 {
00296   module_list_t *entry;
00297 
00298   entry = find_active_module(name);
00299   if (entry) return(&entry->modinfo);
00300   return(NULL);
00301 }

int module_shutdown ( void   ) 

Shuts down the module interface.

This function unloads all loaded modules and deletes the load and unload bind tables.

The module_unload() function is called for every module that is currently loaded. If there is still a module loaded, for example because of dependencies, module_unload() is called again. This is done until either all modules have been unloaded or no more modules could be unloaded.

Returns:
Always 0.

Definition at line 75 of file module.c.

References bind_table_del(), garbage_run(), module_list::modinfo, MODULE_RESTART, module_unload(), egg_module::name, and module_list::next.

Referenced by eggdrop_shutdown().

00076 {
00077   int unloaded;
00078   module_list_t *entry, *next;
00079 
00080   do {
00081     unloaded = 0;
00082     for (entry = module_list_head; entry; entry = next) {
00083       next = entry->next;
00084       if (!module_unload(entry->modinfo.name, MODULE_RESTART)) unloaded = 1;
00085     }
00086   } while (unloaded);
00087 
00088   bind_table_del(BT_load);
00089   bind_table_del(BT_unload);
00090 
00091   garbage_run();
00092   return (0);
00093 }

int module_unload ( const char *  name,
int  why 
)

Unload a module.

If a module's reference count is 0 its closing function will be executed. If the closing function did not veto the unloading it will be removed from the list of active modules, the "unload" bind is triggered and a cleanup run is sceduled.

Parameters:
name The name of the module to unload.
why The reason this function was called: MODULE_USER, MODULE_RESTART or MODULE_SHUTDOWN.
Returns:
0 on success. (This will be logged.)

-1 if the module is not loaded. (Nothing will be logged.)

-2 if the module is in use by another module. (Nothing will be logged.)

-3 if the module's closing function vetoed. (Nothing will be logged.)

Definition at line 201 of file module.c.

References bind_check(), egg_module::close_func, deleted_head, find_active_module, garbage_add(), GARBAGE_ONCE, LOG_MISC, module_list::modinfo, module_cleanup(), MODULE_SHUTDOWN, MODULE_USER, module_list::next, NULL, module_list::prev, putlog(), and module_list::refcount.

Referenced by module_shutdown(), party_unloadmod(), and script_module_unload().

00202 {
00203   module_list_t *entry;
00204   int retval;
00205 
00206   entry = find_active_module(name);
00207   if (!entry) return(-1);
00208   if (entry->refcount > 0) return(-2);
00209   if (entry->modinfo.close_func) {
00210     retval = entry->modinfo.close_func(why);
00211     if (retval) return(-3);
00212   }
00213 
00214   if (entry->prev) entry->prev->next = entry->next;
00215   else module_list_head = entry->next;
00216   if (entry->next) entry->next->prev = entry->prev;
00217 
00218   entry->next = NULL;
00219   if (!deleted_head) {
00220     deleted_head = entry;
00221     entry->prev = NULL;
00222   } else {
00223     module_list_t *tail;
00224 
00225     for (tail = deleted_head; tail->next; tail = tail->next);
00226     tail->next = entry;
00227     entry->prev = tail;
00228   }
00229 
00230   bind_check(BT_unload, NULL, name, name, why == MODULE_USER ? "request" : why == MODULE_SHUTDOWN ? "shutdown" : "restart");
00231   putlog(LOG_MISC, "*", "Module unloaded: %s", name);
00232   garbage_add(module_cleanup, NULL, GARBAGE_ONCE);
00233   return 0;
00234 }


Generated on Sun Nov 30 18:43:34 2008 for eggdrop1.9 by  doxygen 1.5.6