]> code.citadel.org Git - citadel.git/blob - citadel/dynloader.c
* server.h, dynloader.c, citserver.c, user_ops.c: reduced the number
[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 SessionFunctionHook *SessionHookTable = NULL;
26
27 struct ProtoFunctionHook
28 {
29   void (*handler)(char *cmdbuf);
30   char *cmd;
31   char *desc;
32   struct ProtoFunctionHook *next;
33 } *ProtoHookList = NULL;
34
35 void CtdlRegisterProtoHook(void (*handler)(char *), char *cmd, char *desc)
36 {
37   struct ProtoFunctionHook *p = malloc(sizeof *p);
38   
39   if (p == NULL)
40     {
41       fprintf(stderr, "can't malloc new ProtoFunctionHook\n");
42       exit(EXIT_FAILURE);
43     }
44
45   p->handler = handler;
46   p->cmd = cmd;
47   p->desc = desc;
48   p->next = ProtoHookList;
49   ProtoHookList = p;
50 }
51
52 int DLoader_Exec_Cmd(char *cmdbuf)
53 {
54   struct ProtoFunctionHook *p;
55
56   for (p = ProtoHookList; p; p = p->next)
57     {
58       if (!strncmp(cmdbuf, p->cmd, 4))
59         {
60           p->handler(&cmdbuf[5]);
61           return 1;
62         }
63     }
64   return 0;
65 }
66
67 void DLoader_Init(char *pathname)
68 {
69    void *fcn_handle;
70    char *dl_error;
71    DIR *dir;
72    struct dirent *dptr;
73    struct DLModule_Info* (*h_init_fcn)(void);
74    struct DLModule_Info *dl_info;
75
76    char pathbuf[PATH_MAX];
77    
78    if ((dir = opendir(pathname))==NULL)
79    {
80       perror("opendir");
81       exit(1);
82    }
83    
84    while ((dptr=readdir(dir))!= NULL)
85    {
86       if (dptr->d_name[0] == '.')
87          continue;
88    
89       snprintf(pathbuf, PATH_MAX, "%s/%s", pathname, dptr->d_name);
90       if (!(fcn_handle = dlopen(pathbuf, RTLD_NOW)))
91       {
92          dl_error = dlerror();
93          fprintf(stderr, "DLoader_Init dlopen failed (%s)\n", dl_error);
94          continue;
95       }
96       
97       h_init_fcn = dlsym(fcn_handle, "Dynamic_Module_Init");
98       if ((dl_error = dlerror()) != NULL)
99       {
100          fprintf(stderr,"DLoader_Init dlsym failed (%s)\n", dl_error);
101          continue;
102       }
103       
104       dl_info = h_init_fcn();
105
106       printf("Loaded module %s v%d.%d\nBy %s (%s)\n", dl_info->module_name, 
107              dl_info->major_version, dl_info->minor_version,
108              dl_info->module_author, dl_info->module_author_email);
109    }    /* While */
110 }
111
112
113
114 void CtdlRegisterCleanupHook(void *fcn_ptr) {
115
116         struct CleanupFunctionHook *newfcn;
117
118         newfcn = (struct CleanupFunctionHook *)
119                 malloc(sizeof(struct CleanupFunctionHook));
120         newfcn->next = CleanupHookTable;
121         newfcn->h_function_pointer = fcn_ptr;
122         CleanupHookTable = newfcn;
123
124         lprintf(5, "Registered a new cleanup function\n");
125         }
126
127
128 void CtdlRegisterSessionHook(void *fcn_ptr, int EventType) {
129
130         struct SessionFunctionHook *newfcn;
131
132         newfcn = (struct SessionFunctionHook *)
133                 malloc(sizeof(struct SessionFunctionHook));
134         newfcn->next = SessionHookTable;
135         newfcn->h_function_pointer = fcn_ptr;
136         newfcn->eventtype = EventType;
137         SessionHookTable = newfcn;
138
139         lprintf(5, "Registered a new session function (type %d)\n", 
140                 EventType);
141         }
142
143
144 void PerformSessionHooks(int EventType) {
145         struct SessionFunctionHook *fcn;
146
147         for (fcn = SessionHookTable; fcn != NULL; fcn = fcn->next) {
148                 if (fcn->eventtype == EventType) {
149                         (*fcn->h_function_pointer)();
150                         }
151                 }
152         }