+void CtdlDestroyServiceHook(void)
+{
+ struct ServiceFunctionHook *cur, *p;
+
+ cur = ServiceHookTable;
+ while (cur != NULL)
+ {
+ close(cur->msock);
+ if (cur->sockpath) {
+ syslog(LOG_INFO, "Closed UNIX domain socket %s\n",
+ cur->sockpath);
+ } else if (cur->tcp_port) {
+ syslog(LOG_INFO, "Closed TCP port %d\n", cur->tcp_port);
+ } else {
+ syslog(LOG_INFO, "Destroyed service \"%s\"\n", cur->ServiceName);
+ }
+ p = cur->next;
+ free(cur);
+ cur = p;
+ }
+ ServiceHookTable = NULL;
+}
+
+void CtdlRegisterSearchFuncHook(void (*fcn_ptr)(int *, long **, const char *), char *name)
+{
+ struct SearchFunctionHook *newfcn;
+
+ if (!name || !fcn_ptr) {
+ return;
+ }
+
+ newfcn = (struct SearchFunctionHook *)
+ malloc(sizeof(struct SearchFunctionHook));
+ newfcn->next = SearchFunctionHookTable;
+ newfcn->name = name;
+ newfcn->fcn_ptr = fcn_ptr;
+ SearchFunctionHookTable = newfcn;
+
+ syslog(LOG_INFO, "Registered a new search function (%s)\n", name);
+}
+
+void CtdlUnregisterSearchFuncHook(void (*fcn_ptr)(int *, long **, const char *), char *name)
+{
+ struct SearchFunctionHook *cur, *p;
+
+ for (cur = SearchFunctionHookTable; cur != NULL; cur = cur->next) {
+ while (fcn_ptr && (cur->fcn_ptr == fcn_ptr) && name && !strcmp(name, cur->name)) {
+ syslog(LOG_INFO, "Unregistered search function(%s)\n", name);
+ p = cur->next;
+ if (cur == SearchFunctionHookTable) {
+ SearchFunctionHookTable = p;
+ }
+ free (cur);
+ cur = p;
+ }
+ }
+}
+
+void CtdlDestroySearchHooks(void)
+{
+ struct SearchFunctionHook *cur, *p;
+
+ cur = SearchFunctionHookTable;
+ SearchFunctionHookTable = NULL;
+ while (cur != NULL) {
+ p = cur->next;
+ free(cur);
+ cur = p;
+ }
+}
+
+void CtdlModuleDoSearch(int *num_msgs, long **search_msgs, const char *search_string, const char *func_name)
+{
+ struct SearchFunctionHook *fcn = NULL;
+
+ for (fcn = SearchFunctionHookTable; fcn != NULL; fcn = fcn->next) {
+ if (!func_name || !strcmp(func_name, fcn->name)) {
+ (*fcn->fcn_ptr) (num_msgs, search_msgs, search_string);
+ return;