]> code.citadel.org Git - citadel.git/commitdiff
* Makefile.in: add SERV_MODULES and PROXY_TARGETS to `cleaner'
authorNathan Bryant <loanshark@uncensored.citadel.org>
Thu, 17 Sep 1998 22:02:12 +0000 (22:02 +0000)
committerNathan Bryant <loanshark@uncensored.citadel.org>
Thu, 17 Sep 1998 22:02:12 +0000 (22:02 +0000)
        * dynloader.[ch], serv_{chat,test}.[ch], sysdep.c: cleaned
          up the dynamic loader interface as follows:
          - all the symbol table stuff is gone.
          - modules are loaded once at server startup and never unloaded.
          - Added a new function CtdlRegisterProtoHook() to handle the stuff
            that was being done with the symbol tables.
          - Dynamic_Module_Init() now returns a pointer to a static struct
            DLModule_Info; this structure itself has been modified to use char*
            fields instead of fixed char arrays.

citadel/ChangeLog
citadel/Makefile.in
citadel/dynloader.c
citadel/dynloader.h
citadel/serv_chat.c
citadel/serv_chat.h
citadel/serv_test.c
citadel/sysdep.c

index dbae0b1739fa918a7b9d022cecfe2aa6028f4a20..bd7b9c78acc314147193876c53e6e047ec3ea5f4 100644 (file)
@@ -1,3 +1,15 @@
+1998-09-17 Nathan Bryant <bryant@cs.usm.maine.edu>
+       * Makefile.in: add SERV_MODULES and PROXY_TARGETS to `cleaner'
+       * dynloader.[ch], serv_{chat,test}.[ch], sysdep.c: cleaned
+         up the dynamic loader interface as follows:
+         - all the symbol table stuff is gone.
+         - modules are loaded once at server startup and never unloaded.
+         - Added a new function CtdlRegisterProtoHook() to handle the stuff
+           that was being done with the symbol tables.
+         - Dynamic_Module_Init() now returns a pointer to a static struct
+           DLModule_Info; this structure itself has been modified to use char*
+           fields instead of fixed char arrays.
+
 Wed Sep 16 22:25:13 EDT 1998 Art Cancro <ajc@uncnsrd.mt-kisco.ny.us>
        * Implemented separate structs, lists, and functions for each type
          of server-side hook available.
index b5da910d5519d76234d30efea1bf35aab6b0ea0b..4f763b019fb2a7df8037eead13b52890a4450fcb 100644 (file)
@@ -207,7 +207,8 @@ clean:
        find . -name \*.[o] -print -exec rm -f {} \;
 
 cleaner: clean
-       rm -f $(CLIENT_TARGETS) $(SERVER_TARGETS) $(UTIL_TARGETS)
+       rm -f $(CLIENT_TARGETS) $(SERVER_TARGETS) $(UTIL_TARGETS) \
+               $(SERV_MODULES) $(PROXY_TARGETS)
 
 realclean: cleaner
        rm -f Makefile sysdep.h
index dc09a9ad662903fcdd32b5ff572dda6f7fc4c5fa..a827c957dde74d75468e7a54edc4d2e4fb5d2421 100644 (file)
 #include <strings.h>
 #include <syslog.h>
 #include <pthread.h>
+#include <limits.h>
 #include "dynloader.h"
 #include "citadel.h"
 #include "server.h"
 #include "sysdep_decls.h"
 
-symtab *global_symtab;
-
 struct CleanupFunctionHook *CleanupHookTable = NULL;
 struct NewRoomFunctionHook *NewRoomHookTable = NULL;
 struct SessionFunctionHook *SessionHookTable = NULL;
 struct LoginFunctionHook *LoginHookTable = NULL;
 
-int DLoader_Exec_Cmd(char *cmdbuf)
+struct ProtoFunctionHook
 {
-   symtab *t_sym;
-   void *fcn_handle;
-   char *dl_error;
-   void (*cmd_ptr)(void *);
-   
-   for (t_sym = global_symtab; ((t_sym) && (strncmp(t_sym->server_cmd, cmdbuf, strlen(t_sym->server_cmd))) ); t_sym=t_sym->next)
-      ;
-      
-   if (t_sym)
-   {
-      if (!(fcn_handle = dlopen(t_sym->module_path, RTLD_NOW)))
-      {
-         dl_error = dlerror();
-         syslog(LOG_NOTICE, "WARNING: module %s failed to load", t_sym->module_path);
-         return(0);
-      }
-      
-      cmd_ptr = dlsym(fcn_handle, t_sym->fcn_name);
-      if ((dl_error = dlerror()) != NULL)
-      {
-         syslog(LOG_NOTICE, "dlsym error: %s - %s", dl_error, t_sym->module_path);
-         return(0);
-      }
-      (*cmd_ptr)(&cmdbuf[5]);
-      dlclose(fcn_handle);
-      if ((dl_error = dlerror()) != NULL)
-      {
-         syslog(LOG_NOTICE, "dlclose error: %s", dl_error);
-         return(0);
-      }
-      return(1);
-   }  /* If symbol found */
+  void (*handler)(char *cmdbuf);
+  char *cmd;
+  char *desc;
+  struct ProtoFunctionHook *next;
+} *ProtoHookList = NULL;
 
-   return(0);
+void CtdlRegisterProtoHook(void (*handler)(char *), char *cmd, char *desc)
+{
+  struct ProtoFunctionHook *p = malloc(sizeof *p);
+  
+  if (p == NULL)
+    {
+      fprintf(stderr, "can't malloc new ProtoFunctionHook\n");
+      exit(EXIT_FAILURE);
+    }
+
+  p->handler = handler;
+  p->cmd = cmd;
+  p->desc = desc;
+  p->next = ProtoHookList;
+  ProtoHookList = p;
 }
 
-void add_symbol(char *fcn_name, char *server_cmd, char *info_msg, symtab **first_symtab)
+int DLoader_Exec_Cmd(char *cmdbuf)
 {
-   symtab *new_symtab, *t_sym, *last_sym;
-   
-   if (!(new_symtab = malloc(sizeof(symtab))))
-   {
-      perror("Malloc new symtab");
-      exit(1);
-   }
-   
-   new_symtab->fcn_name = strdup(fcn_name);
-   new_symtab->server_cmd = strdup(server_cmd);
-   new_symtab->info_msg = strdup(info_msg);
-   new_symtab->next = NULL;
-   
-   if (!(*first_symtab))
-      (*first_symtab) = new_symtab;
-   else
-   {
-      last_sym = NULL;
-      for (t_sym = (*first_symtab); (t_sym); t_sym = t_sym->next)
-         last_sym = t_sym;
-      last_sym->next = new_symtab;
-   }
+  struct ProtoFunctionHook *p;
+
+  for (p = ProtoHookList; p; p = p->next)
+    {
+      if (!strncmp(cmdbuf, p->cmd, 4))
+       {
+         p->handler(&cmdbuf[5]);
+         return 1;
+       }
+    }
+  return 0;
 }
 
-void DLoader_Init(char *pathname, symtab **my_symtab)
+void DLoader_Init(char *pathname)
 {
    void *fcn_handle;
-   void (*h_init_fcn)(struct DLModule_Info *);
-   void (*h_get_symtab)(symtab **);
    char *dl_error;
-   char *filename;
    DIR *dir;
    struct dirent *dptr;
-   
-   char pathbuf[512];
-   struct DLModule_Info dl_info;
-   symtab *stab = NULL;
-   symtab *t_sym;
-   
-   global_symtab = NULL;                       /* Global symbol table */
+   struct DLModule_Info* (*h_init_fcn)(void);
+   struct DLModule_Info *dl_info;
+
+   char pathbuf[PATH_MAX];
    
    if ((dir = opendir(pathname))==NULL)
    {
@@ -119,61 +88,27 @@ void DLoader_Init(char *pathname, symtab **my_symtab)
       if (dptr->d_name[0] == '.')
          continue;
    
-      filename = strdup(dptr->d_name);
-      snprintf(pathbuf, 512, "%s/%s", pathname, filename);
+      snprintf(pathbuf, PATH_MAX, "%s/%s", pathname, dptr->d_name);
       if (!(fcn_handle = dlopen(pathbuf, RTLD_NOW)))
       {
          dl_error = dlerror();
-         fprintf(stderr, "DLoader_Init dlopen failed (%s)", dl_error);
+         fprintf(stderr, "DLoader_Init dlopen failed (%s)\n", dl_error);
          continue;
       }
       
       h_init_fcn = dlsym(fcn_handle, "Dynamic_Module_Init");
       if ((dl_error = dlerror()) != NULL)
       {
-         fprintf(stderr,"DLoader_Init dlsym failed (%s)", dl_error);
+         fprintf(stderr,"DLoader_Init dlsym failed (%s)\n", dl_error);
          continue;
       }
       
-      (*h_init_fcn)(&dl_info);
-
-      printf("Loaded module %s v%d.%d\nBy %s (%s)\n", dl_info.module_name, 
-                                                     dl_info.major_version,
-                                                     dl_info.minor_version,
-                                                     dl_info.module_author,
-                                                     dl_info.module_author_email);
+      dl_info = h_init_fcn();
 
-      h_get_symtab = dlsym(fcn_handle, "Get_Symtab");
-      if ((dl_error = dlerror()) != NULL)
-      {
-         fprintf(stderr,"DLoader_Init dlsym failed for Get_Symtab (%s) on module %s", dl_error, dl_info.module_name);
-         continue;
-      }
-      
-/* Get the symbol table for the current module and link it on */      
-      
-      (*h_get_symtab)(&stab);
-      if (!(*my_symtab))
-      {
-         (*my_symtab) = global_symtab = stab;
-      }
-      else
-      {
-         for (t_sym = (*my_symtab) ; t_sym->next; t_sym=t_sym->next);
-            ;
-         t_sym->next = stab;
-      }
-      for (t_sym = stab; t_sym; t_sym=t_sym->next)
-         t_sym->module_path = (char *)strdup(pathbuf);
-      dlclose(fcn_handle);
-      if ((dl_error = dlerror()) != NULL)
-      {
-         fprintf(stderr,"DLoader_Init dlclose failed (%s)", dl_error);
-         continue;
-      }
-      
+      printf("Loaded module %s v%d.%d\nBy %s (%s)\n", dl_info->module_name, 
+            dl_info->major_version, dl_info->minor_version,
+            dl_info->module_author, dl_info->module_author_email);
    }   /* While */
-   
 }
 
 
index f9aef0411ff0b7c975dc87deb226d5eb8a0d268e..992d6469af7cb3916cee66d5602e1a0d6204b14b 100644 (file)
@@ -1,24 +1,16 @@
 struct DLModule_Info
 {
-   char module_name[30];
-   char module_author[30];
-   char module_author_email[30];
+   char *module_name;
+   char *module_author;
+   char *module_author_email;
    int major_version, minor_version;
 };
 
-typedef struct s_symtab
-{
-   char *fcn_name;
-   char *server_cmd;
-   char *info_msg;
-   char *module_path;
-   struct s_symtab *next;
-} symtab;
-
-void DLoader_Init(char *pathname, symtab **);
+void DLoader_Init(char *pathname);
 int DLoader_Exec_Cmd(char *cmdbuf);
-void add_symbol(char *fcn_name, char *server_cmd, char *info_msg, symtab **);
 void CtdlRegisterCleanupHook(void *fcn_ptr);
 void CtdlRegisterNewRoomHook(void *fcn_ptr);
 void CtdlRegisterSessionHook(void *fcn_ptr, int StartStop);
 void CtdlRegisterLoginHook(void *fcn_ptr);
+void CtdlRegisterProtoHook(void (*handler)(char *), char *cmd, char *desc);
+struct DLModule_Info *Dynamic_Module_Init(void);
index 0852b585b9c0461655e165dddea6836c9658c969..e9182d347236d3b4e52a61dba64a10f34025748f 100644 (file)
@@ -25,7 +25,6 @@
 
 struct ChatLine *ChatQueue = NULL;
 int ChatLastMsg = 0;
-symtab *My_Symtab = NULL;      /* dyn */
 
 extern struct CitContext *ContextList;
 
@@ -35,28 +34,24 @@ extern struct CitContext *ContextList;
 #define MAJOR_VERSION  0
 #define MINOR_VERSION  2
 
-
-void Dynamic_Module_Init(struct DLModule_Info *info)
+static struct DLModule_Info info =
 {
-   add_symbol("cmd_chat", "CHAT", "Initiates a real-time chat session", &My_Symtab);
-   add_symbol("cmd_pexp", "PEXP", "Poll for express messages", &My_Symtab);
-   add_symbol("cmd_sexp", "SEXP", "Send an express message", &My_Symtab);
-   strncpy(info->module_name, MODULE_NAME, 30);
-   strncpy(info->module_author, MODULE_AUTHOR, 30);
-   strncpy(info->module_author_email, MODULE_EMAIL, 30);
-   info->major_version = MAJOR_VERSION;
-   info->minor_version = MINOR_VERSION;
-
-}
-
-void Get_Symtab(symtab **the_symtab)
+  MODULE_NAME,
+  MODULE_AUTHOR,
+  MODULE_EMAIL,
+  MAJOR_VERSION,
+  MINOR_VERSION
+};
+
+struct DLModule_Info *Dynamic_Module_Init(void)
 {
-   (*the_symtab) = My_Symtab;
-   return;
+   CtdlRegisterProtoHook(cmd_chat, "CHAT",
+                        "Initiates a real-time chat session");
+   CtdlRegisterProtoHook(cmd_pexp, "PEXP", "Poll for express messages");
+   CtdlRegisterProtoHook(cmd_sexp, "SEXP", "Send an express message");
+   return &info;
 }
 
-
-
 void allwrite(char *cmdbuf, int flag, char *roomname, char *username)
 {      
        FILE *fp;
@@ -358,7 +353,7 @@ void cmd_chat(char *argbuf)
 /*
  * poll for express messages
  */
-void cmd_pexp(void) {
+void cmd_pexp(char *argbuf) /* arg unused */ {
        struct ExpressMessage *emptr;
 
        if (CC->FirstExpressMessage == NULL) {
index b2c24103a3bbd79b7e6d18dc67d1b9bafa3eaa48..b9d5e6cb6564aca7402c268f3488efc57b042207 100644 (file)
@@ -3,6 +3,6 @@ void allwrite (char *cmdbuf, int flag, char *roomname, char *username);
 t_context *find_context (char **unstr);
 void do_chat_listing (int allflag);
 void cmd_chat (char *argbuf);
-void cmd_pexp (void);
+void cmd_pexp (char *argbuf); /* arg unused */
 char check_express (void);
 void cmd_sexp (char *argbuf);
index 57002db5dc9eb0393e55b980bab934e2130b349a..44b65677b224d3354f2cb5c6febde6cb3e3b5aaf 100644 (file)
@@ -19,8 +19,6 @@
 #include "config.h"
 #include "dynloader.h"
 
-symtab *My_Symtab = NULL;      /* dyn */
-
 extern struct CitContext *ContextList;
 
 #define MODULE_NAME    "Dummy test module"
@@ -29,6 +27,14 @@ extern struct CitContext *ContextList;
 #define MAJOR_VERSION  0
 #define MINOR_VERSION  1
 
+static struct DLModule_Info info = {
+  MODULE_NAME,
+  MODULE_AUTHOR,
+  MODULE_EMAIL,
+  MAJOR_VERSION,
+  MINOR_VERSION
+};
+
 void CleanupTest(void) {
        lprintf(9, "--- test of adding an unload hook --- \n");
        }
@@ -49,24 +55,12 @@ void LoginTest(void) {
        lprintf(9, "--- Hello, %s ---\n", CC->curr_user);
        }
 
-void Dynamic_Module_Init(struct DLModule_Info *info)
+struct DLModule_Info *Dynamic_Module_Init(void)
 {
-   strncpy(info->module_name, MODULE_NAME, 30);
-   strncpy(info->module_author, MODULE_AUTHOR, 30);
-   strncpy(info->module_author_email, MODULE_EMAIL, 30);
-   info->major_version = MAJOR_VERSION;
-   info->minor_version = MINOR_VERSION;
-
    CtdlRegisterCleanupHook(CleanupTest);
    CtdlRegisterNewRoomHook(NewRoomTest);
    CtdlRegisterSessionHook(SessionStartTest, 1);
    CtdlRegisterSessionHook(SessionStopTest, 0);
    CtdlRegisterLoginHook(LoginTest);
-
-}
-
-void Get_Symtab(symtab **the_symtab)
-{
-   (*the_symtab) = My_Symtab;
-   return;
+   return &info;
 }
index dee294066b4f4d65b14d3f87345e9e20bda70089..87ca119fd3a0896a9610ece6dbf9dbe62d4d091a 100644 (file)
@@ -45,7 +45,6 @@
 
 pthread_mutex_t Critters[MAX_SEMAPHORES];      /* Things needing locking */
 pthread_key_t MyConKey;                                /* TSD key for MyContext() */
-symtab *my_symtab;                             /* Dynamic modules symbol table */
 
 int msock;                                     /* master listening socket */
 int verbosity = 3;                             /* Logging level */
@@ -646,7 +645,7 @@ int main(int argc, char **argv)
        openlog("citserver",LOG_PID,LOG_USER);
         lprintf(1, "Initting modules...\n");
         snprintf(modpath, 128, "%s/modules", BBSDIR);
-        DLoader_Init(modpath, &my_symtab);
+        DLoader_Init(modpath);
         lprintf(1, "Modules done initializing...\n");
 /*
         lprintf(1, "First symtab item:");