Difference for server/plugins.c from version 1.38 to 1.39


version 1.38 version 1.39
Line 1
 
Line 1
 /*  /*
  * static char *rcsid_plugins_c =   * static char *rcsid_plugins_c =
  *   "$Id: plugins.c,v 1.38 2005/07/15 21:11:33 ryo_saeba Exp $";   *   "$Id: plugins.c,v 1.39 2005/07/18 19:07:07 akirschbaum Exp $";
  */   */
   
 /*****************************************************************************/  /*****************************************************************************/
Line 25
 
Line 25
 /*                                                                           */  /*                                                                           */
 /*****************************************************************************/  /*****************************************************************************/
 /* This is the server-side plugin management part.                           */  /* This is the server-side plugin management part.                           */
 /* Note that it has a lot of Win32-Specific code; this is because Windows    */  
 /* uses specific function calls to handle dynamic libraries (the DLLs), where*/  
 /* UNIX-based systems use the dlxxx functions.                               */  
 /* Note that initPlugins() also got a specific Win32 version, not because of */  
 /* the library-handling, but because scandir does not exist on Win32.        */  
 /*****************************************************************************/  /*****************************************************************************/
 /* Original code by Yann Chachkoff (yann.chachkoff@mailandnews.com).         */  /* Original code by Yann Chachkoff (yann.chachkoff@mailandnews.com).         */
 /* Special thanks to:                                                        */  /* Special thanks to:                                                        */
Line 119
 
Line 114
     return -1;      return -1;
 };  };
   
   static LIBPTRTYPE cf_dlopen(char *fname)
   {
 #ifdef WIN32  #ifdef WIN32
       return(LoadLibrary(fname));
   #else
       return(dlopen(fname, RTLD_NOW|RTLD_GLOBAL));
   #endif
   }
   
   static const char *cf_dlerror(void)
   {
   #ifdef WIN32
       static char buf[256];
       DWORD err;
       char *p;
   
       err = GetLastError();
       if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, buf, sizeof(buf), NULL) == 0)
    snprintf(buf, sizeof(buf), "error %lu", err);
   
       p = strchr(buf, '\0');
       while(p > buf && (p[-1] == '\r' || p[-1] == '\n'))
    p--;
       *p = '\0';
   
       return(buf);
   #else
       return(dlerror());
   #endif
   }
   
   static void cf_dlclose(LIBPTRTYPE lib)
   {
   #ifdef WIN32
       FreeLibrary(lib);
   #else
       dlclose(lib);
   #endif
   }
   
   static f_plugin cf_dlsym(LIBPTRTYPE lib, const char *name)
   {
   #ifdef WIN32
       return((f_plugin)GetProcAddress(lib, name));
   #else
       return((f_plugin)dlsym(lib, name));
   #endif
   }
   
 /*****************************************************************************/  /*****************************************************************************/
 /* WIN32 Plugins initialization. Browses the plugins directory and call      */  /* Plugins initialization. Browses the plugins directory and call            */
 /* initOnePlugin for each file found.                                        */  /* initOnePlugin for each file found.                                        */
   /* Returns 0 if at least one plugin was successfully loaded, -1 if not       */
 /*****************************************************************************/  /*****************************************************************************/
 void initPlugins(void)  int initPlugins(void)
 {  {
     struct dirent *currentfile;      struct dirent *currentfile;
     DIR *plugdir;      DIR *plugdir;
     int n;      int l;
     char buf[MAX_BUF];      char buf[MAX_BUF];
     char buf2[MAX_BUF];      char buf2[MAX_BUF];
       int result;
   
     LOG(llevInfo,"Now initializing plugins\n");      LOG(llevInfo,"Initializing plugins\n");
     strcpy(buf,LIBDIR);      strcpy(buf,LIBDIR);
     strcat(buf,"/plugins/");      strcat(buf,"/plugins/");
     LOG(llevInfo,"Plugins directory is %s\n",buf);      LOG(llevInfo,"Plugins directory is %s\n",buf);
   
     plugdir = opendir(buf);      plugdir = opendir(buf);
       if (plugdir == NULL)
    return -1;
   
     n = 0;      result = -1;
       while((currentfile = readdir(plugdir)) != NULL)
     while(currentfile = readdir(plugdir))  
     {      {
         if (strcmp(currentfile->d_name,".."))   l = strlen(currentfile->d_name);
    if (l > strlen(PLUGIN_SUFFIX))
         {          {
             if (strcmp(currentfile->d_name,"."))       if (strcmp(currentfile->d_name+l-strlen(PLUGIN_SUFFIX), PLUGIN_SUFFIX) == 0)
             {              {
                 strcpy(buf2,buf);                  strcpy(buf2,buf);
                 strcat(buf2,currentfile->d_name);                  strcat(buf2,currentfile->d_name);
                 LOG(llevInfo,"Registering plugin %s\n",currentfile->d_name);   LOG(llevInfo," -> Loading plugin : %s\n",currentfile->d_name);
                 initOnePlugin(buf2);   if (initOnePlugin(buf2) == 0)
    {
        result = 0;
    }
             }              }
         }          }
     }      }
 };  
       closedir(plugdir);
       return result;
   }
   
 /*****************************************************************************/  /*****************************************************************************/
 /* WIN32 Plugin initialization. Initializes a plugin known by its filename.  */  /* Plugin initialization. Initializes a plugin known by its filename.        */
 /* The initialization process has several stages:                            */  /* The initialization process has several stages:                            */
 /* - Loading of the DLL itself;                                              */  /* - Loading of the DLL itself;                                              */
 /* - Basical plugin information request;                                     */  /* - Basical plugin information request;                                     */
 /* - CF-Plugin specific initialization tasks (call to initPlugin());         */  /* - CF-Plugin specific initialization tasks (call to initPlugin());         */
 /* - Hook bindings;                                                          */  /* - Hook bindings;                                                          */
   /* Returns 0 if the plugin was successfully loaded, -1 if not                */
 /*****************************************************************************/  /*****************************************************************************/
 void initOnePlugin(char* pluginfile)  int initOnePlugin(char* pluginfile)
 {  {
     int i=0;      int i;
     HMODULE DLLInstance;      int j;
     void *ptr = NULL;      LIBPTRTYPE ptr;
     CFParm HookParm;      CFParm HookParm;
       CFParm *InitParm;
   
     if ((DLLInstance = LoadLibrary(pluginfile))==NULL)      if (PlugNR >= sizeof(PlugList)/sizeof(*PlugList))
     {      {
         LOG(llevError,"Error while trying to load %s\n",pluginfile);   LOG(llevError, "Error while trying to load %s: %s\n", pluginfile, "too many plugins");
         return;   return -1;
     }      }
     PlugList[PlugNR].libptr = DLLInstance;  
     PlugList[PlugNR].initfunc = (f_plugin)(GetProcAddress(DLLInstance,"initPlugin"));      ptr = cf_dlopen(pluginfile);
     if (PlugList[PlugNR].initfunc==NULL)      if (ptr == NULL)
     {      {
         LOG(llevError,"Plugin init error\n");   LOG(llevError, "Error while trying to load %s: %s\n", pluginfile, cf_dlerror());
         FreeLibrary(ptr);   return -1;
         return;  
     }      }
     else      PlugList[PlugNR].libptr = ptr;
       PlugList[PlugNR].initfunc = cf_dlsym(ptr, "initPlugin");
       if (PlugList[PlugNR].initfunc==NULL)
     {      {
         CFParm* InitParm;   LOG(llevError,"Plugin init error: %s\n", cf_dlerror());
    cf_dlclose(ptr);
    return -1;
       }
   
         InitParm = PlugList[PlugNR].initfunc(NULL);          InitParm = PlugList[PlugNR].initfunc(NULL);
         LOG(llevInfo,"Plugin name: %s, known as %s\n",          LOG(llevInfo,"Plugin name: %s, known as %s\n",
             (char *)(InitParm->Value[1]),              (char *)(InitParm->Value[1]),
Line 194
 
Line 254
             );              );
         strcpy(PlugList[PlugNR].id,(char *)(InitParm->Value[0]));          strcpy(PlugList[PlugNR].id,(char *)(InitParm->Value[0]));
         strcpy(PlugList[PlugNR].fullname,(char *)(InitParm->Value[1]));          strcpy(PlugList[PlugNR].fullname,(char *)(InitParm->Value[1]));
       if (findPlugin(PlugList[PlugNR].id) >= 0)
       {
    LOG(llevError, "Error while trying to load %s: plugin %s already loaded\n", pluginfile, PlugList[PlugNR].id);
    cf_dlclose(ptr);
    return -1;
       }
       PlugList[PlugNR].hookfunc = cf_dlsym(ptr, "registerHook");
       PlugList[PlugNR].eventfunc = cf_dlsym(ptr, "triggerEvent");
       PlugList[PlugNR].pinitfunc = cf_dlsym(ptr, "postinitPlugin");
       PlugList[PlugNR].propfunc = cf_dlsym(ptr, "getPluginProperty");
       if (PlugList[PlugNR].hookfunc==NULL)
       {
    LOG(llevError, "registerHook error: %s\n", cf_dlerror());
    cf_dlclose(ptr);
    return -1;
       }
       if (PlugList[PlugNR].eventfunc==NULL)
       {
    LOG(llevError,"triggerEvent error: %s\n", cf_dlerror());
    cf_dlclose(ptr);
    return -1;
     }      }
     PlugList[PlugNR].hookfunc = (f_plugin)(GetProcAddress(DLLInstance,"registerHook"));  
     PlugList[PlugNR].eventfunc = (f_plugin)(GetProcAddress(DLLInstance,"triggerEvent"));  
     PlugList[PlugNR].pinitfunc = (f_plugin)(GetProcAddress(DLLInstance,"postinitPlugin"));  
     PlugList[PlugNR].propfunc = (f_plugin)(GetProcAddress(DLLInstance,"getPluginProperty"));  
     if (PlugList[PlugNR].pinitfunc==NULL)      if (PlugList[PlugNR].pinitfunc==NULL)
     {      {
         LOG(llevError,"Plugin postinit error\n");   LOG(llevError,"postinitPlugin error: %s\n", cf_dlerror());
         FreeLibrary(ptr);   cf_dlclose(ptr);
         return;   return -1;
       }
       if (PlugList[PlugNR].propfunc==NULL)
       {
    LOG(llevError,"getPluginProperty error: %s\n", cf_dlerror());
    cf_dlclose(ptr);
    return -1;
     }      }
   
     for(i=0;i<NR_EVENTS;i++)      for(i=0;i<NR_EVENTS;i++)
         PlugList[PlugNR].gevent[i] = 0;          PlugList[PlugNR].gevent[i] = 0;
     if (PlugList[PlugNR].hookfunc==NULL)  
     {  
         LOG(llevError, "Plugin hook error\n");  
         FreeLibrary(ptr);  
         return;  
     }  
     else  
     {  
         int j;  
         i = 0;  
   
         for(j=1; j<NR_OF_HOOKS;j++)          for(j=1; j<NR_OF_HOOKS;j++)
         {          {
Line 225
 
Line 298
             HookParm.Value[0] = &tmp;              HookParm.Value[0] = &tmp;
             HookParm.Value[1] = HookList[j];              HookParm.Value[1] = HookList[j];
             PlugList[PlugNR].hookfunc(&HookParm);              PlugList[PlugNR].hookfunc(&HookParm);
         };      }
     };  
     if (PlugList[PlugNR].eventfunc==NULL)  
     {  
         LOG(llevError,"Event plugin error\n");  
         FreeLibrary(ptr);  
         return;  
     };  
     PlugNR++;      PlugNR++;
     PlugList[PlugNR-1].pinitfunc(NULL);      PlugList[PlugNR-1].pinitfunc(NULL);
     LOG(llevInfo,"Done\n");      LOG(llevInfo,"[Done]\n");
 };  
   
 /*****************************************************************************/  
 /* Removes one plugin from memory. The plugin is identified by its keyname.  */  
 /*****************************************************************************/  
 void removeOnePlugin(char *id)  
 {  
     int plid;  
     int j;  
     LOG(llevDebug,"Warning - removeOnePlugin non-canon under Win32\n");  
     plid = findPlugin(id);  
     if (plid<0)  
         return;  
     /* We unload the library... */  
     FreeLibrary(PlugList[plid].libptr);  
     /* Then we copy the rest on the list back one position */  
     PlugNR--;  
     if (plid==31) return;  
     for (j=plid+1;j<32;j++)  
     {  
         PlugList[j-1] = PlugList[j];  
     };  
 };  
   
 #else  
   
 #ifndef HAVE_ALPHASORT  
   
 extern int alphasort( struct dirent **a, struct dirent **b);  
 #endif  
   
 /*****************************************************************************/  
 /* UNIX Plugins initialization. Browses the plugins directory and call       */  
 /* initOnePlugin for each file found.                                        */  
 /*****************************************************************************/  
 void initPlugins(void)  
 {  
         struct dirent **namelist=NULL;  
         int n,l;  
         char buf[MAX_BUF];  
         char buf2[MAX_BUF];  
   
         LOG(llevInfo,"Initializing plugins :\n");      return 0;
         strcpy(buf,LIBDIR);  
         strcat(buf,"/plugins/");  
         n = scandir(buf, &namelist, 0, alphasort);  
         if (n < 0)  
             perror("scandir");  
         else  
             while(n--)  
             {  
  l=strlen(namelist[n]->d_name);  
  if (l>strlen(PLUGIN_SUFFIX))  
  {  
      if (!strcmp(namelist[n]->d_name+l-strlen(PLUGIN_SUFFIX),PLUGIN_SUFFIX))  
                     {  
                         strcpy(buf2,buf);  
                         strcat(buf2,namelist[n]->d_name);  
                         LOG(llevInfo," -> Loading plugin : %s\n",namelist[n]->d_name);  
                         initOnePlugin(buf2);  
                     };  
                 }                  }
             };  
         if (namelist != NULL) free(namelist);  
 };  
   
 /*****************************************************************************/  /*****************************************************************************/
 /* Removes one plugin from memory. The plugin is identified by its keyname.  */  /* Removes one plugin from memory. The plugin is identified by its keyname.  */
   /* Returns 0 if the plugin was removed, -1 if not.                           */
 /*****************************************************************************/  /*****************************************************************************/
 void removeOnePlugin(char *id)  int removeOnePlugin(char *id)
 {  {
     int plid;      int plid;
     int j;      int j;
     plid = findPlugin(id);      plid = findPlugin(id);
     if (plid<0)      if (plid<0)
         return;   return -1;
     /* We unload the library... */      /* We unload the library... */
     dlclose(PlugList[plid].libptr);      cf_dlclose(PlugList[plid].libptr);
     /* Then we copy the rest on the list back one position */      /* Then we copy the rest on the list back one position */
     PlugNR--;      PlugNR--;
     if (plid==31) return;      for (j=plid+1;j<sizeof(PlugList)/sizeof(*PlugList);j++)
     LOG(llevInfo,"plid=%i, PlugNR=%i\n",plid,PlugNR);  
     for (j=plid+1;j<32;j++)  
     {      {
         PlugList[j-1] = PlugList[j];          PlugList[j-1] = PlugList[j];
     };  
 };  
   
 /*****************************************************************************/  
 /* UNIX Plugin initialization. Initializes a plugin known by its filename.   */  
 /* The initialization process has several stages:                            */  
 /* - Loading of the DLL itself;                                              */  
 /* - Basical plugin information request;                                     */  
 /* - CF-Plugin specific initialization tasks (call to initPlugin());         */  
 /* - Hook bindings;                                                          */  
 /*****************************************************************************/  
 void initOnePlugin(char* pluginfile)  
 {  
         int i=0;  
         void *ptr = NULL;  
         CFParm HookParm;  
         if ((ptr=dlopen(pluginfile,RTLD_NOW|RTLD_GLOBAL))==NULL)  
         {  
                 LOG(llevInfo,"Plugin error: %s\n", dlerror());  
                 return;  
         };  
         PlugList[PlugNR].libptr = ptr;  
         PlugList[PlugNR].initfunc = (f_plugin)(dlsym(ptr,"initPlugin"));  
         if (PlugList[PlugNR].initfunc==NULL)  
         {  
                 LOG(llevInfo,"Plugin init error: %s\n", dlerror());  
         }  
         else  
         {  
             CFParm* InitParm;  
             InitParm = PlugList[PlugNR].initfunc(NULL);  
             LOG(llevInfo,"    Plugin %s loaded under the name of %s\n",  
                 (char *)(InitParm->Value[1]),  
                 (char *)(InitParm->Value[0])  
             );  
             strcpy(PlugList[PlugNR].id,(char *)(InitParm->Value[0]));  
             strcpy(PlugList[PlugNR].fullname,(char *)(InitParm->Value[1]));  
         };  
         PlugList[PlugNR].hookfunc = (f_plugin)(dlsym(ptr,"registerHook"));  
         PlugList[PlugNR].eventfunc = (f_plugin)(dlsym(ptr,"triggerEvent"));  
         PlugList[PlugNR].pinitfunc = (f_plugin)(dlsym(ptr,"postinitPlugin"));  
         PlugList[PlugNR].propfunc = (f_plugin)(dlsym(ptr,"getPluginProperty"));  
         LOG(llevInfo,"Done\n");  
         if (PlugList[PlugNR].pinitfunc==NULL)  
         {  
                 LOG(llevInfo,"Plugin postinit error: %s\n", dlerror());  
         }          }
   
         for(i=0;i<NR_EVENTS;i++)      return 0;
         {  
             PlugList[PlugNR].gevent[i] = 0;  
         };  
         if (PlugList[PlugNR].hookfunc==NULL)  
         {  
                 LOG(llevInfo,"Plugin hook error: %s\n", dlerror());  
         }          }
         else  
         {  
                 int j;  
                 i = 0;  
   
                 for(j=1; j<NR_OF_HOOKS;j++)  
                 {  
                     int tmp = j;  
                     HookParm.Value[0] = &tmp;  
                     HookParm.Value[1] = HookList[j];  
                     PlugList[PlugNR].hookfunc(&HookParm);  
                 };  
         };  
         if (PlugList[PlugNR].eventfunc==NULL)  
         {  
                 LOG(llevError,"Event plugin error %s\n", dlerror());  
         };  
         PlugNR++;  
         PlugList[PlugNR-1].pinitfunc(NULL);  
         LOG(llevInfo,"[Done]\n");  
 };  
 #endif /*WIN32*/  
   
 /*****************************************************************************/  /*****************************************************************************/
 /* Hook functions. Those are wrappers to crosslib functions, used by plugins.*/  /* Hook functions. Those are wrappers to crosslib functions, used by plugins.*/


Legend:
line(s) removed in v.1.38 
line(s) changed
 line(s) added in v.1.39

File made using version 1.98 of cvs2html by leaf at 2011-07-21 17:43