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