1 /* 2 * Copyright (c) 2005 William Pitcock, et al. 3 * The rights to this code are as documented in doc/LICENSE. 4 * 5 * This file contains data structures concerning modules. 6 * 7 */ 8 9 #ifndef MODULE_H 10 #define MODULE_H 11 12 #include "privs.h" 13 #include "abirev.h" 14 15 typedef enum { 16 MODULE_UNLOAD_INTENT_PERM, 17 MODULE_UNLOAD_INTENT_RELOAD, 18 } module_unload_intent_t; 19 20 typedef enum { 21 MODULE_UNLOAD_CAPABILITY_OK, 22 MODULE_UNLOAD_CAPABILITY_NEVER, 23 MODULE_UNLOAD_CAPABILITY_RELOAD_ONLY, 24 } module_unload_capability_t; 25 26 typedef struct module_ module_t; 27 typedef struct v4_moduleheader_ v4_moduleheader_t; 28 29 typedef void (*module_unload_handler_t)(module_t *, module_unload_intent_t); 30 31 /* Module structure. Might be a loaded .so module, or something else that 32 * behaves as a module for dependency purposes (perl script, etc). 33 */ 34 struct module_ { 35 char name[BUFSIZE]; 36 char modpath[BUFSIZE]; 37 module_unload_capability_t can_unload; 38 39 unsigned int mflags; 40 41 /* These three are real-module-specific. Either all will be set, or all 42 * will be null. 43 */ 44 v4_moduleheader_t *header; 45 void *address; 46 mowgli_module_t *handle; 47 48 /* If this module is not a loaded .so (the above three are null), and 49 * can_unload is not never, then * this must be set to a working unload 50 * function. 51 */ 52 module_unload_handler_t unload_handler; 53 54 mowgli_list_t dephost; 55 mowgli_list_t deplist; 56 57 mowgli_list_t symlist; /* MAPIv2 symbol dependencies. */ 58 }; 59 60 #define MODTYPE_STANDARD 0 61 #define MODTYPE_CORE 1 /* Can't be unloaded. */ 62 #define MODTYPE_FAIL 0x8000 /* modinit failed */ 63 64 #define MAPI_ATHEME_MAGIC 0xdeadbeef 65 #define MAPI_ATHEME_V4 4 66 67 #define MAX_CMD_PARC 20 68 69 struct v4_moduleheader_ { 70 unsigned int atheme_mod; 71 unsigned int abi_ver; 72 unsigned int abi_rev; 73 const char *serial; 74 const char *name; 75 module_unload_capability_t can_unload; 76 void (*modinit)(module_t *m); 77 void (*deinit)(module_unload_intent_t intent); 78 const char *vendor; 79 const char *version; 80 }; 81 82 /* name is the module name we're searching for. 83 * path is the likely full path name, which may be ignored. 84 * If it is found, set module to the loaded module_t pointer 85 */ 86 typedef struct { 87 const char *name; 88 const char *path; 89 module_t *module; 90 int handled; 91 } hook_module_load_t; 92 93 #define DECLARE_MODULE_V1(name, norestart, modinit, deinit, ver, ven) \ 94 v4_moduleheader_t _header = { \ 95 MAPI_ATHEME_MAGIC, MAPI_ATHEME_V4, \ 96 CURRENT_ABI_REVISION, "unknown", \ 97 name, norestart, modinit, deinit, ven, ver \ 98 } 99 100 E void _modinit(module_t *m); 101 E void _moddeinit(module_unload_intent_t intent); 102 103 E void modules_init(void); 104 E module_t *module_load(const char *filespec); 105 E void module_load_dir(const char *dirspec); 106 E void module_load_dir_match(const char *dirspec, const char *pattern); 107 E void *module_locate_symbol(const char *modname, const char *sym); 108 E void module_unload(module_t *m, module_unload_intent_t intent); 109 E module_t *module_find(const char *name); 110 E module_t *module_find_published(const char *name); 111 E bool module_request(const char *name); 112 113 #define MODULE_TRY_REQUEST_DEPENDENCY(self, modname) \ 114 if (module_request(modname) == false) \ 115 { \ 116 (self)->mflags = MODTYPE_FAIL; \ 117 return; \ 118 } 119 120 #define MODULE_TRY_REQUEST_SYMBOL(self, dest, modname, sym) \ 121 if ((dest = module_locate_symbol(modname, sym)) == NULL) \ 122 { \ 123 MODULE_TRY_REQUEST_DEPENDENCY(self, modname); \ 124 if ((dest = module_locate_symbol(modname, sym)) == NULL) \ 125 { \ 126 (self)->mflags = MODTYPE_FAIL; \ 127 return; \ 128 } \ 129 } 130 131 #define MODULE_CONFLICT(self, modname) \ 132 if (module_find_published(modname)) \ 133 { \ 134 slog(LG_ERROR, "module %s conflicts with %s, unloading", \ 135 self->name, modname); \ 136 (self)->mflags = MODTYPE_FAIL; \ 137 return; \ 138 } 139 140 typedef struct module_dependency_ { 141 char *name; 142 module_unload_capability_t can_unload; 143 } module_dependency_t; 144 145 #endif 146 147 /* vim:cinoptions=>s,e0,n0,f0,{0,}0,^0,=s,ps,t0,c3,+s,(2s,us,)20,*30,gs,hs 148 * vim:ts=8 149 * vim:sw=8 150 * vim:noexpandtab 151 */ 152