/*
- * $Id$
- *
* Citadel Dynamic Loading Module
* Written by Brian Costello <btx@calyx.net>
- *
*/
#include "sysdep.h"
struct ProtoFunctionHook {
void (*handler) (char *cmdbuf);
- char *cmd;
- char *desc;
- struct ProtoFunctionHook *next;
-} *ProtoHookList = NULL;
-
-
-struct DirectoryServiceHook {
- int (*handler) (char *cn, char *ou, void **object);
- int cmd;
- char *module;
- struct DirectoryServiceHook *next;
-} *DirectoryServiceHookList = NULL;
-
-struct DirectoryObject {
- char *module;
- void *object;
- struct DirectoryObject *next;
+ const char *cmd;
+ const char *desc;
};
+HashList *ProtoHookList = NULL;
+
+
#define ERR_PORT (1 << 1)
char *ErrPortWhere = "Admin->System Preferences->Network.\n\nThe failed ports and sockets are: ";
char *ErrPortHint = "If you want citadel to provide you with that functionality, "
"check the output of \"netstat -lnp\" on linux Servers or \"netstat -na\" on *BSD"
-" and stop the programm, that binds these ports. You should eventually remove "
+" and stop the programm, that binds these ports.\n You should eventually remove "
" their initscripts in /etc/init.d so that you won't get this trouble once more.\n"
" After that goto Administration -> Shutdown Citadel to make Citadel retry to bind this port.\n";
int DLoader_Exec_Cmd(char *cmdbuf)
{
+ void *vP;
struct ProtoFunctionHook *p;
- for (p = ProtoHookList; p; p = p->next) {
- if (!strncasecmp(cmdbuf, p->cmd, 4)) {
- p->handler(&cmdbuf[5]);
- return 1;
- }
+ if (GetHash(ProtoHookList, cmdbuf, 4, &vP) && (vP != NULL)) {
+ p = (struct ProtoFunctionHook*) vP;
+ p->handler(&cmdbuf[5]);
+ return 1;
}
return 0;
}
+int FourHash(const char *key, long length)
+{
+ int i;
+ int ret = 0;
+ const unsigned char *ptr = (const unsigned char*)key;
+
+ for (i = 0; i < 4; i++, ptr ++)
+ ret = (ret << 8) |
+ ( ((*ptr >= 'a') &&
+ (*ptr <= 'z'))?
+ *ptr - 'a' + 'A':
+ *ptr);
+
+ return ret;
+}
void CtdlRegisterProtoHook(void (*handler) (char *), char *cmd, char *desc)
{
struct ProtoFunctionHook *p;
+ if (ProtoHookList == NULL)
+ ProtoHookList = NewHash (1, FourHash);
+
+
p = (struct ProtoFunctionHook *)
malloc(sizeof(struct ProtoFunctionHook));
p->handler = handler;
p->cmd = cmd;
p->desc = desc;
- p->next = ProtoHookList;
- ProtoHookList = p;
- CtdlLogPrintf(CTDL_INFO, "Registered server command %s (%s)\n", cmd, desc);
-}
-
-
-void CtdlUnregisterProtoHook(void (*handler) (char *), char *cmd)
-{
- struct ProtoFunctionHook *cur = NULL;
- struct ProtoFunctionHook *p = NULL;
- struct ProtoFunctionHook *lastcur = NULL;
- for (cur = ProtoHookList;
- cur != NULL;
- cur = (cur != NULL)? cur->next: NULL) {
- /* This will also remove duplicates if any */
- while (cur != NULL &&
- handler == cur->handler &&
- !strcmp(cmd, cur->cmd)) {
- CtdlLogPrintf(CTDL_INFO, "Unregistered server command %s (%s)\n",
- cmd, cur->desc);
- p = cur->next;
- if (cur == ProtoHookList) {
- ProtoHookList = p;
- }
- else if (lastcur != NULL)
- {
- lastcur->next = p;
- }
- free(cur);
- cur = p;
- }
- lastcur = cur;
- }
+ Put(ProtoHookList, cmd, 4, p, NULL);
+ CtdlLogPrintf(CTDL_INFO, "Registered server command %s (%s)\n", cmd, desc);
}
void CtdlDestroyProtoHooks(void)
{
- struct ProtoFunctionHook *cur, *p;
- cur = ProtoHookList;
- while (cur != NULL)
- {
- CtdlLogPrintf(CTDL_INFO, "Destroyed server command %s (%s)\n",
- cur->cmd, cur->desc);
- p = cur->next;
- free(cur);
- cur = p;
- }
- ProtoHookList = NULL;
+ DeleteHash(&ProtoHookList);
}
{
struct ServiceFunctionHook *newfcn;
char *message;
- char *error;
+ char error[SIZ];
- error = NULL;
- newfcn = (struct ServiceFunctionHook *)
- malloc(sizeof(struct ServiceFunctionHook));
- message = (char*) malloc (SIZ);
+ strcpy(error, "");
+ newfcn = (struct ServiceFunctionHook *) malloc(sizeof(struct ServiceFunctionHook));
+ message = (char*) malloc (SIZ + SIZ);
newfcn->next = ServiceHookTable;
newfcn->tcp_port = tcp_port;
newfcn->ServiceName = ServiceName;
if (sockpath != NULL) {
- newfcn->msock = ig_uds_server(sockpath, config.c_maxsessions, &error);
+ newfcn->msock = ctdl_uds_server(sockpath, config.c_maxsessions, error);
snprintf(message, SIZ, "Unix domain socket '%s': ", sockpath);
}
else if (tcp_port <= 0) { /* port -1 to disable */
return;
}
else {
- newfcn->msock = ig_tcp_server(config.c_ip_addr,
+ newfcn->msock = ctdl_tcp_server(config.c_ip_addr,
tcp_port,
config.c_maxsessions,
- &error);
+ error);
snprintf(message, SIZ, "TCP port %s:%d: (%s) ",
config.c_ip_addr, tcp_port, ServiceName);
}
ServiceHookTable = NULL;
}
-void CtdlRegisterSearchFuncHook(void (*fcn_ptr)(int *, long **, char *), char *name)
+void CtdlRegisterSearchFuncHook(void (*fcn_ptr)(int *, long **, const char *), char *name)
{
struct SearchFunctionHook *newfcn;
CtdlLogPrintf(CTDL_INFO, "Registered a new search function (%s)\n", name);
}
-void CtdlUnregisterSearchFuncHook(void (*fcn_ptr)(int *, long **, char *), char *name)
+void CtdlUnregisterSearchFuncHook(void (*fcn_ptr)(int *, long **, const char *), char *name)
{
struct SearchFunctionHook *cur, *p;
}
}
-void CtdlModuleDoSearch(int *num_msgs, long **search_msgs, char *search_string, char *func_name)
+void CtdlModuleDoSearch(int *num_msgs, long **search_msgs, const char *search_string, const char *func_name)
{
struct SearchFunctionHook *fcn = NULL;
for (fcn = SessionHookTable; fcn != NULL; fcn = fcn->next) {
if (fcn->eventtype == EventType) {
+ if (EventType == EVT_TIMER) {
+ citthread_setspecific(MyConKey, NULL); /* for every hook */
+ }
(*fcn->h_function_pointer) ();
}
}
}
-
-
-int CtdlRegisterDirectoryServiceFunc(int (*func)(char *cn, char *ou, void **object), int cmd, char *module)
-{
- struct DirectoryServiceHook *newfcn;
-
- newfcn = DirectoryServiceHookList;
- while (newfcn)
- {
- if (newfcn->cmd == cmd && !strcmp(newfcn->module, module))
- {
- CtdlLogPrintf(CTDL_ERR, "Directory service function already handled by module %s\n", module);
- return -1;
- }
- newfcn = newfcn->next;
- }
-
- newfcn = (struct DirectoryServiceHook *) malloc (sizeof(struct DirectoryServiceHook));
- newfcn->handler = func;
- newfcn->cmd = cmd;
- newfcn->module = module;
- newfcn->next = DirectoryServiceHookList;
- DirectoryServiceHookList = newfcn;
-
- CtdlLogPrintf(CTDL_INFO, "Registered a new directory service function from module %s\n", module);
- return 0;
-}
-
-int CtdlDoDirectoryServiceFunc(char *cn, char *ou, void **object, char *module, int cmd)
-{
- struct DirectoryServiceHook *curfcn;
- struct DirectoryObject *our_object_list = NULL;
- struct DirectoryObject *newobject = NULL;
- struct DirectoryObject *oldobject = NULL;
-
-
- curfcn = DirectoryServiceHookList;
- if (object)
- our_object_list = (struct DirectoryObject *) *object;
-
- while (curfcn)
- {
- if (curfcn->cmd == cmd)
- {
- if (!module)
- {
- if (cmd == DIRECTORY_CREATE_OBJECT)
- {
- newobject = (struct DirectoryObject*) malloc (sizeof(struct DirectoryObject));
- newobject->module = curfcn->module;
- newobject->object = NULL;
- newobject->next = our_object_list;
- our_object_list = newobject;
- }
- if (our_object_list)
- {
- for(newobject = our_object_list; newobject; newobject=newobject->next)
- {
- if (!strcmp(newobject->module, curfcn->module))
- (void) curfcn->handler(cn, ou, &newobject->object);
- }
- }
- else
- (void) curfcn->handler(cn, ou, NULL);
-
- continue;
- }
- else
- {
- if(!strcmp(curfcn->module, module))
- {
- if (cmd == DIRECTORY_CREATE_OBJECT)
- {
- newobject = (struct DirectoryObject*) malloc (sizeof(struct DirectoryObject));
- newobject->module = module;
- newobject->object = NULL;
- newobject->next = our_object_list;
- our_object_list = newobject;
- }
- if (our_object_list)
- {
- for(newobject = our_object_list; newobject; newobject=newobject->next)
- {
- if (!strcmp(newobject->module, curfcn->module))
- (void) curfcn->handler(cn, ou, &newobject->object);
- }
- }
- else
- (void) (curfcn->handler(cn, ou, NULL));
-
- break;
- }
- }
- }
- curfcn=curfcn->next;
- }
- if (our_object_list)
- {
- *object = our_object_list;
- if (cmd == DIRECTORY_FREE_OBJECT)
- { // The objects pointed to by the list should have been freed by the module that created it
- for(newobject = our_object_list; newobject; )
- {
- oldobject=newobject;
- newobject=newobject->next;
- free(oldobject);
- }
- *object=NULL;
- }
- }
- return 0;
-}
-
-void CtdlDestroyDirectoryServiceFuncs(void)
-{
- struct DirectoryServiceHook *cur, *next;
-
- cur = DirectoryServiceHookList;
- DirectoryServiceHookList = NULL;
- while (cur)
- {
- next = cur->next;
- CtdlLogPrintf(CTDL_INFO, "Destroyed directory service function for module %s.\n", cur->module);
- free(cur);
- cur = next;
- }
-}
-
/*
* Dirty hack until we impliment a hook mechanism for this
*/