1 /*******************************************************
3 * Citadel Dynamic Loading Module
4 * Written by Brian Costello
7 ******************************************************/
13 #include <sys/types.h>
18 #include "dynloader.h"
22 symtab *global_symtab;
24 struct FunctionHook *HookTable = NULL;
26 int DLoader_Exec_Cmd(char *cmdbuf)
31 void (*cmd_ptr)(void *);
33 for (t_sym = global_symtab; ((t_sym) && (strncmp(t_sym->server_cmd, cmdbuf, strlen(t_sym->server_cmd))) ); t_sym=t_sym->next)
38 if (!(fcn_handle = dlopen(t_sym->module_path, RTLD_LAZY)))
41 syslog(LOG_NOTICE, "WARNING: module %s failed to load", t_sym->module_path);
45 cmd_ptr = dlsym(fcn_handle, t_sym->fcn_name);
46 if ((dl_error = dlerror()) != NULL)
48 syslog(LOG_NOTICE, "dlsym error: %s - %s", dl_error, t_sym->module_path);
51 (*cmd_ptr)(&cmdbuf[5]);
53 if ((dl_error = dlerror()) != NULL)
55 syslog(LOG_NOTICE, "dlclose error: %s", dl_error);
59 } /* If symbol found */
64 void add_symbol(char *fcn_name, char *server_cmd, char *info_msg, symtab **first_symtab)
66 symtab *new_symtab, *t_sym, *last_sym;
68 if (!(new_symtab = malloc(sizeof(symtab))))
70 perror("Malloc new symtab");
74 new_symtab->fcn_name = strdup(fcn_name);
75 new_symtab->server_cmd = strdup(server_cmd);
76 new_symtab->info_msg = strdup(info_msg);
77 new_symtab->next = NULL;
80 (*first_symtab) = new_symtab;
84 for (t_sym = (*first_symtab); (t_sym); t_sym = t_sym->next)
86 last_sym->next = new_symtab;
90 void DLoader_Init(char *pathname, symtab **my_symtab)
93 void (*h_init_fcn)(struct DLModule_Info *);
94 void (*h_get_symtab)(symtab **);
101 struct DLModule_Info dl_info;
105 global_symtab = NULL; /* Global symbol table */
107 if ((dir = opendir(pathname))==NULL)
113 while ((dptr=readdir(dir))!= NULL)
115 if (dptr->d_name[0] == '.')
118 filename = strdup(dptr->d_name);
119 snprintf(pathbuf, 512, "%s/%s", pathname, filename);
120 if (!(fcn_handle = dlopen(pathbuf, RTLD_LAZY)))
122 dl_error = dlerror();
123 fprintf(stderr, "DLoader_Init dlopen failed (%s)", dl_error);
127 h_init_fcn = dlsym(fcn_handle, "Dynamic_Module_Init");
128 if ((dl_error = dlerror()) != NULL)
130 fprintf(stderr,"DLoader_Init dlsym failed (%s)", dl_error);
134 (*h_init_fcn)(&dl_info);
136 printf("Loaded module %s v%d.%d\nBy %s (%s)\n", dl_info.module_name,
137 dl_info.major_version,
138 dl_info.minor_version,
139 dl_info.module_author,
140 dl_info.module_author_email);
142 h_get_symtab = dlsym(fcn_handle, "Get_Symtab");
143 if ((dl_error = dlerror()) != NULL)
145 fprintf(stderr,"DLoader_Init dlsym failed for Get_Symtab (%s) on module %s", dl_error, dl_info.module_name);
149 /* Get the symbol table for the current module and link it on */
151 (*h_get_symtab)(&stab);
154 (*my_symtab) = global_symtab = stab;
158 for (t_sym = (*my_symtab) ; t_sym->next; t_sym=t_sym->next);
162 for (t_sym = stab; t_sym; t_sym=t_sym->next)
163 t_sym->module_path = (char *)strdup(pathbuf);
165 if ((dl_error = dlerror()) != NULL)
167 fprintf(stderr,"DLoader_Init dlclose failed (%s)", dl_error);
177 void CtdlRegisterHook(void *fcn_ptr, int fcn_type) {
179 struct FunctionHook *newfcn;
181 newfcn = (struct FunctionHook *) malloc(sizeof(struct FunctionHook));
182 newfcn->next = HookTable;
183 newfcn->h_function_pointer = fcn_ptr;
184 newfcn->h_type = fcn_type;
188 lprintf(5, "Registered a new function (type %d)\n", fcn_type);