]> code.citadel.org Git - citadel.git/blobdiff - citadel/dynloader.c
* Finished the "arbitrary service" registration.
[citadel.git] / citadel / dynloader.c
index f6da4d7b2dad619d57c3065ee05eace4282f1272..4d26b594526294387d3a4e628cf30bc67b62797a 100644 (file)
@@ -17,9 +17,6 @@
 #include <dirent.h>
 #include <strings.h>
 #include <syslog.h>
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
 #include <limits.h>
 #include <ctype.h>
 #include "citadel.h"
@@ -40,6 +37,7 @@ struct SessionFunctionHook *SessionHookTable = NULL;
 struct UserFunctionHook *UserHookTable = NULL;
 struct XmsgFunctionHook *XmsgHookTable = NULL;
 struct MessageFunctionHook *MessageHookTable = NULL;
+struct ServiceFunctionHook *ServiceHookTable = NULL;
 
 struct ProtoFunctionHook {
        void (*handler) (char *cmdbuf);
@@ -94,7 +92,9 @@ void DLoader_Init(char *pathname)
                exit(1);
        }
        while ((dptr = readdir(dir)) != NULL) {
-               if (dptr->d_name[0] == '.')
+               if (strlen(dptr->d_name) < 4)
+                       continue;
+               if (strcasecmp(&dptr->d_name[strlen(dptr->d_name)-3], ".so"))
                        continue;
 
                snprintf(pathbuf, PATH_MAX, "%s/%s", pathname, dptr->d_name);
@@ -228,6 +228,24 @@ void CtdlRegisterXmsgHook(int (*fcn_ptr) (char *, char *, char *), int order)
        lprintf(5, "Registered a new x-msg function (priority %d)\n", order);
 }
 
+void CtdlRegisterServiceHook(int tcp_port,
+                       void (*h_greeting_function) (void),
+                       void (*h_command_function) (void) )
+{
+       struct ServiceFunctionHook *newfcn;
+
+       newfcn = (struct ServiceFunctionHook *)
+           mallok(sizeof(struct ServiceFunctionHook));
+       newfcn->next = ServiceHookTable;
+       newfcn->tcp_port = tcp_port;
+       newfcn->h_greeting_function = h_greeting_function;
+       newfcn->h_command_function = h_command_function;
+       newfcn->msock = (-1);
+       ServiceHookTable = newfcn;
+       lprintf(5, "Registered a new service (TCP port %d)\n", tcp_port);
+}
+
+
 
 void PerformSessionHooks(int EventType)
 {
@@ -267,6 +285,18 @@ int PerformMessageHooks(struct CtdlMessage *msg, int EventType)
        struct MessageFunctionHook *fcn;
        int total_retval = 0;
 
+       /* Other code may elect to protect this message from server-side
+        * handlers; if this is the case, don't do anything.
+        */
+       lprintf(9, "** Event type is %d, flags are %d\n",
+               EventType, msg->cm_flags);
+       if (msg->cm_flags & CM_SKIP_HOOKS) {
+               lprintf(9, "Skipping hooks\n");
+               return(0);
+       }
+
+       /* Otherwise, run all the hooks appropriate to this event type.
+        */
        for (fcn = MessageHookTable; fcn != NULL; fcn = fcn->next) {
                if (fcn->eventtype == EventType) {
                        total_retval = total_retval +
@@ -274,9 +304,15 @@ int PerformMessageHooks(struct CtdlMessage *msg, int EventType)
                }
        }
 
+       /* Return the sum of the return codes from the hook functions.  If
+        * this is an EVT_BEFORESAVE event, a nonzero return code will cause
+        * the save operation to abort.
+        */
        return total_retval;
 }
 
+
+
 int PerformXmsgHooks(char *sender, char *recp, char *msg)
 {
        struct XmsgFunctionHook *fcn;