1 /*******************************************************
3 * Citadel Dynamic Loading Module
4 * Written by Brian Costello
7 ******************************************************/
13 #include <sys/types.h>
18 #include "dynloader.h"
21 #include "sysdep_decls.h"
23 symtab *global_symtab;
25 struct CleanupFunctionHook *CleanupHookTable = NULL;
26 struct NewRoomFunctionHook *NewRoomHookTable = NULL;
27 struct SessionFunctionHook *SessionHookTable = NULL;
28 struct LoginFunctionHook *LoginHookTable = NULL;
30 int DLoader_Exec_Cmd(char *cmdbuf)
35 void (*cmd_ptr)(void *);
37 for (t_sym = global_symtab; ((t_sym) && (strncmp(t_sym->server_cmd, cmdbuf, strlen(t_sym->server_cmd))) ); t_sym=t_sym->next)
42 if (!(fcn_handle = dlopen(t_sym->module_path, RTLD_NOW)))
45 syslog(LOG_NOTICE, "WARNING: module %s failed to load", t_sym->module_path);
49 cmd_ptr = dlsym(fcn_handle, t_sym->fcn_name);
50 if ((dl_error = dlerror()) != NULL)
52 syslog(LOG_NOTICE, "dlsym error: %s - %s", dl_error, t_sym->module_path);
55 (*cmd_ptr)(&cmdbuf[5]);
57 if ((dl_error = dlerror()) != NULL)
59 syslog(LOG_NOTICE, "dlclose error: %s", dl_error);
63 } /* If symbol found */
68 void add_symbol(char *fcn_name, char *server_cmd, char *info_msg, symtab **first_symtab)
70 symtab *new_symtab, *t_sym, *last_sym;
72 if (!(new_symtab = malloc(sizeof(symtab))))
74 perror("Malloc new symtab");
78 new_symtab->fcn_name = strdup(fcn_name);
79 new_symtab->server_cmd = strdup(server_cmd);
80 new_symtab->info_msg = strdup(info_msg);
81 new_symtab->next = NULL;
84 (*first_symtab) = new_symtab;
88 for (t_sym = (*first_symtab); (t_sym); t_sym = t_sym->next)
90 last_sym->next = new_symtab;
94 void DLoader_Init(char *pathname, symtab **my_symtab)
97 void (*h_init_fcn)(struct DLModule_Info *);
98 void (*h_get_symtab)(symtab **);
105 struct DLModule_Info dl_info;
109 global_symtab = NULL; /* Global symbol table */
111 if ((dir = opendir(pathname))==NULL)
117 while ((dptr=readdir(dir))!= NULL)
119 if (dptr->d_name[0] == '.')
122 filename = strdup(dptr->d_name);
123 snprintf(pathbuf, 512, "%s/%s", pathname, filename);
124 if (!(fcn_handle = dlopen(pathbuf, RTLD_NOW)))
126 dl_error = dlerror();
127 fprintf(stderr, "DLoader_Init dlopen failed (%s)", dl_error);
131 h_init_fcn = dlsym(fcn_handle, "Dynamic_Module_Init");
132 if ((dl_error = dlerror()) != NULL)
134 fprintf(stderr,"DLoader_Init dlsym failed (%s)", dl_error);
138 (*h_init_fcn)(&dl_info);
140 printf("Loaded module %s v%d.%d\nBy %s (%s)\n", dl_info.module_name,
141 dl_info.major_version,
142 dl_info.minor_version,
143 dl_info.module_author,
144 dl_info.module_author_email);
146 h_get_symtab = dlsym(fcn_handle, "Get_Symtab");
147 if ((dl_error = dlerror()) != NULL)
149 fprintf(stderr,"DLoader_Init dlsym failed for Get_Symtab (%s) on module %s", dl_error, dl_info.module_name);
153 /* Get the symbol table for the current module and link it on */
155 (*h_get_symtab)(&stab);
158 (*my_symtab) = global_symtab = stab;
162 for (t_sym = (*my_symtab) ; t_sym->next; t_sym=t_sym->next);
166 for (t_sym = stab; t_sym; t_sym=t_sym->next)
167 t_sym->module_path = (char *)strdup(pathbuf);
169 if ((dl_error = dlerror()) != NULL)
171 fprintf(stderr,"DLoader_Init dlclose failed (%s)", dl_error);
181 void CtdlRegisterCleanupHook(void *fcn_ptr) {
183 struct CleanupFunctionHook *newfcn;
185 newfcn = (struct CleanupFunctionHook *)
186 malloc(sizeof(struct CleanupFunctionHook));
187 newfcn->next = CleanupHookTable;
188 newfcn->h_function_pointer = fcn_ptr;
189 CleanupHookTable = newfcn;
191 lprintf(5, "Registered a new cleanup function\n");
194 void CtdlRegisterNewRoomHook(void *fcn_ptr) {
196 struct NewRoomFunctionHook *newfcn;
198 newfcn = (struct NewRoomFunctionHook *)
199 malloc(sizeof(struct NewRoomFunctionHook));
200 newfcn->next = NewRoomHookTable;
201 newfcn->h_function_pointer = fcn_ptr;
202 NewRoomHookTable = newfcn;
204 lprintf(5, "Registered a new NewRoom function\n");
207 void CtdlRegisterSessionHook(void *fcn_ptr, int StartStop) {
209 struct SessionFunctionHook *newfcn;
211 newfcn = (struct SessionFunctionHook *)
212 malloc(sizeof(struct SessionFunctionHook));
213 newfcn->next = SessionHookTable;
214 newfcn->h_function_pointer = fcn_ptr;
215 newfcn->startstop = StartStop;
216 SessionHookTable = newfcn;
218 lprintf(5, "Registered a new session %s function\n",
219 (StartStop ? "start" : "stop") );
222 void CtdlRegisterLoginHook(void *fcn_ptr) {
224 struct LoginFunctionHook *newfcn;
226 newfcn = (struct LoginFunctionHook *)
227 malloc(sizeof(struct LoginFunctionHook));
228 newfcn->next = LoginHookTable;
229 newfcn->h_function_pointer = fcn_ptr;
230 LoginHookTable = newfcn;
232 lprintf(5, "Registered a new login function\n");