Yattm - unified GTK instant-messaging client logo
   [Generated for version 0.2-17 - Mon Jan 6 19:01:23 GMT+1 2003]

Home - Main Page - Data Structures - File List - Data Fields - Globals

plugin.c File Reference

#include "intl.h"
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#include "globals.h"
#include "defaults.h"
#include "service.h"
#include "plugin.h"
#include "nomodule.h"
#include "value_pair.h"

Include dependency graph for plugin.c:

Include dependency graph

Go to the source code of this file.

Functions

gint compare_plugin_loaded_service (gconstpointer a, gconstpointer b)
gint compare_plugin_name (gconstpointer a, gconstpointer b)
gint compare_plugin_handle (gconstpointer a, gconstpointer b)
eb_PLUGIN_INFOFindLoadedPluginByService (char *service)
eb_PLUGIN_INFOFindPluginByName (char *name)
eb_PLUGIN_INFOFindPluginByHandle (lt_dlhandle *Module)
void SetPluginInfo (PLUGIN_INFO *pi, char *name, lt_dlhandle Module, PLUGIN_STATUS status, const char *status_desc, char *service, gboolean force)
int select_module_entry (const struct dirent *dent)
int unload_module (eb_PLUGIN_INFO *epi)
void unload_modules (void)
int load_module (char *path, char *name)
void load_modules ()
int load_service_plugin (lt_dlhandle Module, PLUGIN_INFO *info, char *name)
int load_utility_plugin (lt_dlhandle Module, PLUGIN_INFO *info, char *name)
int load_log_plugin (lt_dlhandle Module, PLUGIN_INFO *info, char *name)
int load_sound_plugin (lt_dlhandle Module, PLUGIN_INFO *info, char *name)
int load_gui_plugin (lt_dlhandle Module, PLUGIN_INFO *info, char *name)
int init_menu (char *menu_name, menu_func redraw_menu, ebmType type)
int init_menus ()

Variables

char * PLUGIN_TYPE_TXT [] = {"SERVICE", "UTILITY", "SOUND", "LOG", "GUI", "UNKNOWN"}
char * PLUGIN_STATUS_TXT []
PLUGIN_INFO Plugin_Cannot_Load


Function Documentation

gint compare_plugin_handle gconstpointer    a,
gconstpointer    b
 

Definition at line 66 of file plugin.c.

References eb_PLUGIN_INFO::Module.

Referenced by FindPluginByHandle().

00066                                                              {
00067     const eb_PLUGIN_INFO *epi=a;
00068     if( epi->Module && epi->Module == (lt_dlhandle )b)
00069         return(0);
00070     return(1);
00071 }

gint compare_plugin_loaded_service gconstpointer    a,
gconstpointer    b
 

Definition at line 52 of file plugin.c.

References PLUGIN_LOADED, eb_PLUGIN_INFO::service, and eb_PLUGIN_INFO::status.

Referenced by FindLoadedPluginByService().

00052                                                                      {
00053     const eb_PLUGIN_INFO *epi=a;
00054     if(epi->service && epi->status==PLUGIN_LOADED && !strcmp( epi->service, (char *)b))
00055         return(0);
00056     return(1);
00057 }

gint compare_plugin_name gconstpointer    a,
gconstpointer    b
 

Definition at line 59 of file plugin.c.

References eb_PLUGIN_INFO::name.

Referenced by FindPluginByName().

00059                                                            {
00060     const eb_PLUGIN_INFO *epi=a;
00061     if(epi->name && !strcmp( epi->name, (char *)b))
00062         return(0);
00063     return(1);
00064 }

eb_PLUGIN_INFO* FindLoadedPluginByService char *    service
 

Definition at line 74 of file plugin.c.

References compare_plugin_loaded_service(), EB_PLUGIN_LIST, and GetPref().

Referenced by load_service_plugin().

00075 {
00076     GList *plugins=GetPref(EB_PLUGIN_LIST);
00077     GList *PluginData = g_list_find_custom(plugins, service, compare_plugin_loaded_service);
00078     if(PluginData)
00079         return(PluginData->data);
00080     return(NULL);
00081 }

eb_PLUGIN_INFO* FindPluginByHandle lt_dlhandle *    Module
 

Definition at line 92 of file plugin.c.

References compare_plugin_handle(), EB_PLUGIN_LIST, and GetPref().

00093 {
00094     GList *plugins=GetPref(EB_PLUGIN_LIST);
00095     GList *PluginData = g_list_find_custom(plugins, Module, compare_plugin_handle);
00096     if(PluginData)
00097         return(PluginData->data);
00098     return(NULL);
00099 }

eb_PLUGIN_INFO* FindPluginByName char *    name
 

Definition at line 83 of file plugin.c.

References compare_plugin_name(), EB_PLUGIN_LIST, and GetPref().

Referenced by load_module(), plugin_selected(), and SetPluginInfo().

00084 {
00085     GList *plugins=GetPref(EB_PLUGIN_LIST);
00086     GList *PluginData = g_list_find_custom(plugins, name, compare_plugin_name);
00087     if(PluginData)
00088         return(PluginData->data);
00089     return(NULL);
00090 }

int init_menu char *    menu_name,
menu_func    redraw_menu,
ebmType    type
 

Definition at line 417 of file plugin.c.

References ebmType, menu_func, menu_data::menu_items, menu_data::redraw_menu, SetPref(), and menu_data::type.

Referenced by init_menus().

00418 {
00419     menu_data *md=NULL;
00420 
00421     md=g_new0(menu_data, 1);
00422     md->menu_items=NULL;
00423     md->redraw_menu=redraw_menu;
00424     md->type=type;
00425     SetPref(menu_name, md);
00426     return(0);
00427 }

int init_menus  
 

Definition at line 430 of file plugin.c.

References EB_CHAT_WINDOW_MENU, EB_CONTACT_MENU, EB_IMPORT_MENU, EB_PROFILE_MENU, ebmCONTACTDATA, ebmIMPORTDATA, ebmPROFILEDATA, and init_menu().

Referenced by main().

00431 {
00432     init_menu(EB_PROFILE_MENU, rebuild_profile_menu, ebmPROFILEDATA);
00433     init_menu(EB_IMPORT_MENU, rebuild_import_menu, ebmIMPORTDATA);
00434     /* The chat window menu is dynamically redrawn */
00435     init_menu(EB_CHAT_WINDOW_MENU, NULL, ebmCONTACTDATA);
00436     init_menu(EB_CONTACT_MENU, NULL, ebmCONTACTDATA);
00437     return(0);
00438 }

int load_gui_plugin lt_dlhandle    Module,
PLUGIN_INFO   info,
char *    name
 

Definition at line 411 of file plugin.c.

Referenced by load_module().

00412 {
00413     return(1);
00414 }

int load_log_plugin lt_dlhandle    Module,
PLUGIN_INFO   info,
char *    name
 

Definition at line 401 of file plugin.c.

Referenced by load_module().

00402 {
00403     return(1);
00404 }

int load_module char *    path,
char *    name
 

Definition at line 200 of file plugin.c.

References _, DBG_CORE, eb_debug, FindPluginByName(), load_gui_plugin(), load_log_plugin(), load_service_plugin(), load_sound_plugin(), load_utility_plugin(), PLUGIN_CANNOT_LOAD, PLUGIN_GUI, PLUGIN_LOADED, PLUGIN_LOG, PLUGIN_SERVICE, PLUGIN_SOUND, PLUGIN_UTILITY, SetPluginInfo(), eb_PLUGIN_INFO::status, and PLUGIN_INFO::type.

Referenced by load_modules(), and reload_plugin_callback().

00201 {
00202     char full_path[1024];
00203     lt_dlhandle Module;
00204     PLUGIN_INFO *plugin_info=NULL;
00205     eb_PLUGIN_INFO *epi=NULL;
00206 
00207     sprintf(full_path, "%s/%s", path, name);
00208     eb_debug(DBG_CORE, "Opening module: %s\n", full_path);
00209     Module = lt_dlopen(full_path);
00210     eb_debug(DBG_CORE, "Module: %p\n", Module);
00211 
00212     /* Find out if this plugin is already loaded */
00213     if(!Module) {
00214         /* Only update status on a plugin that is not already loaded */
00215         SetPluginInfo(NULL, full_path, NULL, PLUGIN_CANNOT_LOAD, lt_dlerror(), NULL, FALSE);
00216         return(-1);
00217     }
00218     plugin_info = (PLUGIN_INFO *)lt_dlsym(Module, "plugin_info");
00219     if(!plugin_info) {
00220         lt_dlclose(Module);
00221         /* Only update status on a plugin that is not already loaded */
00222         SetPluginInfo(NULL, full_path, NULL, PLUGIN_CANNOT_LOAD, _("Cannot resolve symbol plugin_info"), NULL, FALSE);
00223         return(-1);
00224     }
00225     epi=FindPluginByName(full_path);
00226     if(epi && epi->status==PLUGIN_LOADED) {
00227         lt_dlclose(Module);
00228         eb_debug(DBG_CORE, "Not loading already loaded module %s\n", name);
00229         return(-1);
00230     }
00231     switch(plugin_info->type) {
00232     case PLUGIN_SERVICE:
00233         load_service_plugin(Module, plugin_info, full_path);
00234         break;
00235     case PLUGIN_UTILITY:
00236         load_utility_plugin(Module, plugin_info, full_path);
00237         break;
00238     case PLUGIN_SOUND:
00239         load_sound_plugin(Module, plugin_info, full_path);
00240         break;
00241     case PLUGIN_LOG:
00242         load_log_plugin(Module, plugin_info, full_path);
00243         break;
00244     case PLUGIN_GUI:
00245         load_gui_plugin(Module, plugin_info, full_path);
00246         break;
00247     default:
00248         break;
00249     }
00250     return(0);
00251 }

void load_modules  
 

Definition at line 254 of file plugin.c.

References _, cGetLocalPref(), DBG_CORE, do_error_dialog(), eb_debug, load_module(), MODULE_DIR, and select_module_entry().

Referenced by main(), and reload_modules().

00255 {
00256     /* UNUSED struct dirent **namelist=NULL; */
00257     char buf[1024], *modules_path=NULL, *cur_path=NULL;
00258     char *tok_buf=NULL, *tok_buf_old=NULL;
00259     int n=0, success=0;
00260     struct dirent *dp;
00261     DIR *dirp;
00262 
00263     eb_debug(DBG_CORE, ">Entering\n");
00264     modules_path=g_strdup(cGetLocalPref("modules_path"));
00265     tok_buf = g_new0(char, strlen(modules_path)+1);
00266     /* Save the old pointer, because strtok_r will change it */
00267     tok_buf_old=tok_buf;
00268     lt_dlinit();
00269     lt_dlsetsearchpath(modules_path);
00270 
00271     /* Use a thread-safe strtok */
00272 #ifdef HAVE_STRTOK_R
00273     cur_path=strtok_r(modules_path, ":", &tok_buf);
00274 #else
00275     cur_path=strtok(modules_path, ":");
00276 #endif
00277     if(!cur_path)
00278         cur_path=MODULE_DIR;
00279     do {
00280         if((dirp = opendir(cur_path)) == NULL)
00281         {
00282             sprintf(buf, _("Cannot open module directory \"%s\""), cur_path);
00283             do_error_dialog(buf, _("Warning"));
00284             buf[0] = '\0';
00285             break;
00286         }
00287         n = 0;
00288         while((dp = readdir(dirp)) != NULL)
00289         {
00290             if( dp == NULL )
00291             {
00292                 sprintf(buf, _("Looking for modules in %s"), cur_path);
00293                 perror(buf);
00294                 continue;
00295             }
00296             else if( select_module_entry( dp ) )
00297             {
00298                 n++;
00299                 success = load_module(cur_path, dp->d_name);
00300             }
00301         }
00302         if( n == 0 )
00303         {
00304             eb_debug(DBG_CORE, "<No modules found in %s, returning.\n", cur_path);
00305         }
00306         else
00307         {
00308             eb_debug(DBG_CORE, "Loaded %d modules from %s.\n", n, cur_path);
00309         }
00310         closedir(dirp);
00311 #ifdef HAVE_STRTOK_R
00312     } while((cur_path=strtok_r(NULL, ":", &tok_buf)));
00313 #else
00314     } while((cur_path=strtok(NULL, ":")));
00315 #endif
00316 
00317     g_free(modules_path);
00318     g_free(tok_buf_old);
00319     eb_debug(DBG_CORE, "Adding idle_check\n");
00320     add_idle_check();
00321     eb_debug(DBG_CORE, "<End services_init\n");
00322 }

int load_service_plugin lt_dlhandle    Module,
PLUGIN_INFO   info,
char *    name
 

Definition at line 324 of file plugin.c.

References _, add_service(), PLUGIN_INFO::brief_desc, DBG_CORE, DBG_MOD, eb_debug, eb_update_from_value_pair(), FindLoadedPluginByService(), GetPref(), PLUGIN_INFO::init, service::name, PLUGIN_CANNOT_LOAD, PLUGIN_LOADED, PLUGIN_INFO::prefs, service::sc, SetPluginInfo(), eb_PLUGIN_INFO::status, and _input_list::widget.

Referenced by load_module().

00325 {
00326     struct service *Service_Info=NULL;
00327     struct service_callbacks *(*query_callbacks)();
00328     int service_id=-1;
00329     eb_PLUGIN_INFO *epi=NULL;
00330     GList *user_prefs=NULL;
00331 
00332     Service_Info = lt_dlsym(Module, "SERVICE_INFO");
00333     eb_debug(DBG_CORE, "SERVICE_INFO: %p\n", Service_Info);
00334     if(!Service_Info) {
00335         SetPluginInfo(info, name, NULL, PLUGIN_CANNOT_LOAD, _("Unable to resolve symbol SERVICE_INFO"), NULL, FALSE);
00336         lt_dlclose(Module);
00337         return(-1);
00338     }
00339     /* Don't load this module if there's a service of this type already loaded */
00340     epi=FindLoadedPluginByService(Service_Info->name);
00341     if(epi && epi->status==PLUGIN_LOADED) {
00342         fprintf(stderr, _("Not loading module %s, a module for that service is already loaded!\n"), name);
00343         SetPluginInfo(info, name, NULL, PLUGIN_CANNOT_LOAD, _("Service provided by an already loaded plugin"), Service_Info->name, FALSE);
00344         lt_dlclose(Module);
00345         return(-1);
00346     }
00347     /* No more hard-coded service_id numbers */
00348     query_callbacks = lt_dlsym(Module, "query_callbacks");
00349     if(!query_callbacks) {
00350         SetPluginInfo(info, name, NULL, PLUGIN_CANNOT_LOAD, "Unable to resolve symbol query_callbacks", Service_Info->name, FALSE);
00351         lt_dlclose(Module);
00352         return(-1);
00353     }
00354     if(info->init) {
00355         eb_debug(DBG_CORE, "Executing init for %s\n", info->brief_desc);
00356         info->init();
00357     }
00358     if(info->prefs) {
00359         user_prefs=GetPref(name);
00360         if(user_prefs) {
00361             eb_update_from_value_pair(info->prefs, user_prefs);
00362         }
00363         eb_debug(DBG_MOD, "prefs name: %s\n", info->prefs->widget.entry.name);
00364     }
00365     Service_Info->sc=query_callbacks();
00366     /* The callbacks are defined by the SERVICE_INFO struct in each module */
00367     service_id = add_service(Service_Info);
00368     SetPluginInfo(info, name, Module, PLUGIN_LOADED, "", Service_Info->name, TRUE);
00369     eb_debug(DBG_CORE, "Added module:%s, service: %s\n", name, eb_services[service_id].name);
00370     eb_debug(DBG_CORE, "eb_services[%i].sc->read_local_account_config: %p\n", service_id, eb_services[service_id].sc->read_local_account_config);
00371     return(0);
00372 }

int load_sound_plugin lt_dlhandle    Module,
PLUGIN_INFO   info,
char *    name
 

Definition at line 406 of file plugin.c.

Referenced by load_module().

00407 {
00408     return(1);
00409 }

int load_utility_plugin lt_dlhandle    Module,
PLUGIN_INFO   info,
char *    name
 

Definition at line 374 of file plugin.c.

References _, PLUGIN_INFO::brief_desc, DBG_CORE, DBG_MOD, do_error_dialog(), eb_debug, eb_update_from_value_pair(), GetPref(), PLUGIN_INFO::init, PLUGIN_CANNOT_LOAD, PLUGIN_LOADED, PLUGIN_INFO::prefs, SetPluginInfo(), and _input_list::widget.

Referenced by load_module().

00375 {
00376     char buf[1024];
00377     GList *user_prefs=NULL;
00378 
00379     eb_debug(DBG_CORE, ">\n");
00380     if(!info->init) {
00381         SetPluginInfo(info, name, NULL, PLUGIN_CANNOT_LOAD, _("No init function defined"), NULL, FALSE);
00382         lt_dlclose(Module);
00383         sprintf(buf, _("init function not defined for utility module %s, unloading module\n"), name);
00384         do_error_dialog(buf, _("Warning"));
00385         return(-1);
00386     }
00387     eb_debug(DBG_CORE, "Executing init for %s\n", info->brief_desc);
00388     info->init();
00389     if(info->prefs) {
00390         user_prefs=GetPref(name);
00391         if(user_prefs) {
00392             eb_update_from_value_pair(info->prefs, user_prefs);
00393         }
00394         eb_debug(DBG_MOD, "prefs name: %s\n", info->prefs->widget.entry.name);
00395     }
00396     SetPluginInfo(info, name, Module, PLUGIN_LOADED, "", NULL, TRUE);
00397     eb_debug(DBG_CORE, "<\n");
00398     return(0);
00399 }

int select_module_entry const struct dirent *    dent
 

Definition at line 144 of file plugin.c.

References DBG_CORE, and eb_debug.

Referenced by load_modules().

00144                                                    {
00145     int len=0;
00146     char *ext;
00147 
00148     len=strlen(dent->d_name);
00149     if(len<4)
00150        return(0);
00151     ext=(char *)dent->d_name;
00152     ext+=(len-3);
00153     eb_debug(DBG_CORE, "select_module_entry: %s[%s]\n", dent->d_name, ext);
00154     if(!strncmp(ext, ".la", 3))
00155        return(1);
00156     return(0);
00157 }

void SetPluginInfo PLUGIN_INFO   pi,
char *    name,
lt_dlhandle    Module,
PLUGIN_STATUS    status,
const char *    status_desc,
char *    service,
gboolean    force
 

Definition at line 102 of file plugin.c.

References PLUGIN_INFO::brief_desc, PLUGIN_INFO::date, EB_PLUGIN_LIST, FindPluginByName(), PLUGIN_INFO::finish, PLUGIN_INFO::full_desc, GetPref(), PLUGIN_INFO::init, eb_PLUGIN_INFO::Module, eb_PLUGIN_INFO::name, eb_PLUGIN_INFO::pi, PLUGIN_LOADED, PLUGIN_STATUS, PLUGIN_INFO::prefs, eb_PLUGIN_INFO::service, SetPref(), eb_PLUGIN_INFO::status, eb_PLUGIN_INFO::status_desc, PLUGIN_INFO::type, and PLUGIN_INFO::version.

Referenced by load_module(), load_service_plugin(), and load_utility_plugin().

00103 {
00104     GList *plugins=NULL;
00105     eb_PLUGIN_INFO *epi=NULL;
00106 
00107     epi=FindPluginByName(name);
00108     if(!epi) {
00109         epi=g_new0(eb_PLUGIN_INFO, 1);
00110         plugins=GetPref(EB_PLUGIN_LIST);
00111         plugins=g_list_append(plugins, epi);
00112         SetPref(EB_PLUGIN_LIST, plugins);
00113     }
00114     else if(force==TRUE || epi->status!=PLUGIN_LOADED) {
00115         if(epi->service)
00116             free(epi->service);
00117         free(epi->name);
00118         free(epi->pi.brief_desc);
00119         free(epi->pi.full_desc);
00120         free(epi->pi.version);
00121         free(epi->pi.date);
00122     }
00123     else    /* A plugin is already succesfully load */
00124         return;
00125     epi->status=status;
00126     epi->status_desc=status_desc;
00127     if(!pi)
00128         pi=&Plugin_Cannot_Load;
00129     epi->pi.type=pi->type;
00130     epi->pi.brief_desc=strdup(pi->brief_desc);
00131     epi->pi.full_desc=strdup(pi->full_desc);
00132     epi->pi.version=strdup(pi->version);
00133     epi->pi.date=strdup(pi->date);
00134     epi->pi.init=pi->init;
00135     epi->pi.finish=pi->finish;
00136     epi->pi.prefs=pi->prefs;
00137     epi->name=strdup(name);
00138     if(service)
00139         epi->service=strdup(service);
00140     epi->Module=Module;
00141 }

int unload_module eb_PLUGIN_INFO   epi
 

Definition at line 159 of file plugin.c.

References _, add_service(), DBG_CORE, do_error_dialog(), eb_debug, eb_nomodule_query_callbacks(), PLUGIN_INFO::finish, eb_PLUGIN_INFO::Module, eb_PLUGIN_INFO::name, eb_PLUGIN_INFO::pi, PLUGIN_NOT_LOADED, PLUGIN_INFO::prefs, service::sc, eb_PLUGIN_INFO::service, and eb_PLUGIN_INFO::status.

Referenced by reload_plugin_callback(), unload_modules(), and unload_plugin_callback().

00160 {
00161     int error=0;
00162     char buf[1024];
00163 
00164     eb_debug(DBG_CORE, ">Unloading plugin %s\n", epi->name);
00165     /* This is a service plugin, special handling required */
00166     if(epi->pi.finish) {
00167         eb_debug(DBG_CORE, "Calling plugins finish function\n");
00168         error=epi->pi.finish();
00169         if(error) {
00170             sprintf(buf, _("Unable to unload plugin %s, still in use?\n"), epi->name);
00171             do_error_dialog(buf, _("Error"));
00172             eb_debug(DBG_CORE, "<Plugin failed to unload\n");
00173             return(-1);
00174         }
00175     }
00176     if(epi->service) {
00177         struct service SERVICE_INFO = { strdup(epi->service), -1, FALSE, FALSE, FALSE, FALSE, NULL };
00178 
00179         SERVICE_INFO.sc=eb_nomodule_query_callbacks();
00180         add_service(&SERVICE_INFO);
00181     }
00182     epi->status=PLUGIN_NOT_LOADED;
00183     epi->pi.prefs=NULL;
00184     eb_debug(DBG_CORE, "Closing plugin\n");
00185     if(lt_dlclose(epi->Module)) {
00186         fprintf(stderr, "Error closing plugin: %s\n", lt_dlerror());
00187     }
00188     eb_debug(DBG_CORE, "<Plugin unloaded\n");
00189     return(0);
00190 
00191 }

void unload_modules void   
 

Definition at line 193 of file plugin.c.

References EB_PLUGIN_LIST, GetPref(), and unload_module().

Referenced by main().

00193                           {
00194     GList *plugins=GetPref(EB_PLUGIN_LIST);
00195     for(plugins=GetPref(EB_PLUGIN_LIST); plugins; plugins=plugins->next) {
00196         unload_module(plugins->data);
00197     }
00198 }


Variable Documentation

PLUGIN_INFO Plugin_Cannot_Load
 

Initial value:

 {PLUGIN_UNKNOWN, 
                  "Unknown",
                  "Unknown", 
                  "Unknown", 
                  "Unknown", NULL, NULL, NULL, NULL}

Definition at line 46 of file plugin.c.

char* PLUGIN_STATUS_TXT[]
 

Initial value:

{"Not Loaded", 
               "Loaded", 
               "Cannot Load"}

Definition at line 42 of file plugin.c.

char* PLUGIN_TYPE_TXT[] = {"SERVICE", "UTILITY", "SOUND", "LOG", "GUI", "UNKNOWN"}
 

Definition at line 41 of file plugin.c.


Contact: Andy Maloney     [Documentation generated by doxygen]