]> code.citadel.org Git - citadel.git/blob - citadel/dynloader.c
* added RCS Id keyword strings to sources
[citadel.git] / citadel / dynloader.c
1 /*******************************************************
2  *
3  * Citadel Dynamic Loading Module
4  * Written by Brian Costello
5  * btx@calyx.net
6  *
7  * $Id$
8  *
9  ******************************************************/
10
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <dlfcn.h>
15 #include <sys/types.h>
16 #include <dirent.h>
17 #include <strings.h>
18 #include <syslog.h>
19 #include <pthread.h>
20 #include <limits.h>
21 #include "dynloader.h"
22 #include "citadel.h"
23 #include "server.h"
24 #include "sysdep_decls.h"
25
26 #ifndef HAVE_SNPRINTF
27 #include <stdarg.h>
28 #include "snprintf.h"
29 #endif
30
31 struct CleanupFunctionHook *CleanupHookTable = NULL;
32 struct SessionFunctionHook *SessionHookTable = NULL;
33 struct UserFunctionHook *UserHookTable = NULL;
34
35 struct ProtoFunctionHook
36 {
37   void (*handler)(char *cmdbuf);
38   char *cmd;
39   char *desc;
40   struct ProtoFunctionHook *next;
41 } *ProtoHookList = NULL;
42
43 void CtdlRegisterProtoHook(void (*handler)(char *), char *cmd, char *desc)
44 {
45   struct ProtoFunctionHook *p = malloc(sizeof *p);
46   
47   if (p == NULL)
48     {
49       fprintf(stderr, "can't malloc new ProtoFunctionHook\n");
50       exit(EXIT_FAILURE);
51     }
52
53   p->handler = handler;
54   p->cmd = cmd;
55   p->desc = desc;
56   p->next = ProtoHookList;
57   ProtoHookList = p;
58 }
59
60 int DLoader_Exec_Cmd(char *cmdbuf)
61 {
62   struct ProtoFunctionHook *p;
63
64   for (p = ProtoHookList; p; p = p->next)
65     {
66       if (!strncasecmp(cmdbuf, p->cmd, 4))
67         {
68           p->handler(&cmdbuf[5]);
69           return 1;
70         }
71     }
72   return 0;
73 }
74
75 void DLoader_Init(char *pathname)
76 {
77    void *fcn_handle;
78    char *dl_error;
79    DIR *dir;
80    struct dirent *dptr;
81    struct DLModule_Info* (*h_init_fcn)(void);
82    struct DLModule_Info *dl_info;
83
84    char pathbuf[PATH_MAX];
85    
86    if ((dir = opendir(pathname))==NULL)
87    {
88       perror("opendir");
89       exit(1);
90    }
91    
92    while ((dptr=readdir(dir))!= NULL)
93    {
94       if (dptr->d_name[0] == '.')
95          continue;
96    
97       snprintf(pathbuf, PATH_MAX, "%s/%s", pathname, dptr->d_name);
98       if (!(fcn_handle = dlopen(pathbuf, RTLD_NOW)))
99       {
100          dl_error = dlerror();
101          fprintf(stderr, "DLoader_Init dlopen failed (%s)\n", dl_error);
102          continue;
103       }
104       
105       h_init_fcn = (struct DLModule_Info * (*)(void))
106         dlsym(fcn_handle, "Dynamic_Module_Init");
107
108       if ((dl_error = dlerror()) != NULL)
109       {
110          fprintf(stderr,"DLoader_Init dlsym failed (%s)\n", dl_error);
111          continue;
112       }
113       
114       dl_info = h_init_fcn();
115
116       printf("Loaded module %s v%d.%d\nBy %s (%s)\n", dl_info->module_name, 
117              dl_info->major_version, dl_info->minor_version,
118              dl_info->module_author, dl_info->module_author_email);
119    }    /* While */
120 }
121
122
123
124 void CtdlRegisterCleanupHook(void (*fcn_ptr)(void)) {
125
126         struct CleanupFunctionHook *newfcn;
127
128         newfcn = (struct CleanupFunctionHook *)
129                 malloc(sizeof(struct CleanupFunctionHook));
130         newfcn->next = CleanupHookTable;
131         newfcn->h_function_pointer = fcn_ptr;
132         CleanupHookTable = newfcn;
133
134         lprintf(5, "Registered a new cleanup function\n");
135         }
136
137
138 void CtdlRegisterSessionHook(void (*fcn_ptr)(void), int EventType) {
139
140         struct SessionFunctionHook *newfcn;
141
142         newfcn = (struct SessionFunctionHook *)
143                 malloc(sizeof(struct SessionFunctionHook));
144         newfcn->next = SessionHookTable;
145         newfcn->h_function_pointer = fcn_ptr;
146         newfcn->eventtype = EventType;
147         SessionHookTable = newfcn;
148
149         lprintf(5, "Registered a new session function (type %d)\n", 
150                 EventType);
151         }
152
153
154 void CtdlRegisterUserHook(void (*fcn_ptr)(char*, long), int EventType) {
155
156         struct UserFunctionHook *newfcn;
157
158         newfcn = (struct UserFunctionHook *)
159                 malloc(sizeof(struct UserFunctionHook));
160         newfcn->next = UserHookTable;
161         newfcn->h_function_pointer = fcn_ptr;
162         newfcn->eventtype = EventType;
163         UserHookTable = newfcn;
164
165         lprintf(5, "Registered a new user function (type %d)\n", 
166                 EventType);
167         }
168
169
170 void PerformSessionHooks(int EventType) {
171         struct SessionFunctionHook *fcn;
172
173         for (fcn = SessionHookTable; fcn != NULL; fcn = fcn->next) {
174                 if (fcn->eventtype == EventType) {
175                         (*fcn->h_function_pointer)();
176                         }
177                 }
178         }
179
180 void PerformUserHooks(char *username, long usernum, int EventType) {
181         struct UserFunctionHook *fcn;
182
183         for (fcn = UserHookTable; fcn != NULL; fcn = fcn->next) {
184                 if (fcn->eventtype == EventType) {
185                         (*fcn->h_function_pointer)(username, usernum);
186                         }
187                 }
188         }
189