00001 /******************************************************************** 00002 Description: Plugin-handling library 00003 part of the 3Dsia project 00004 created: xandi, 270200 00005 00006 History: 00007 date, name, changes, in funtion 00008 180300 StonedBones cleaned source 00009 270200 Xandi created source 00010 00011 ********************************************************************/ 00012 00013 #include <stdio.h> 00014 #include <dlfcn.h> 00015 #include <string> 00016 #include <dirent.h> 00017 #include <unistd.h> 00018 #include <sys/stat.h> 00019 00020 #include "plugin.h" 00021 #include "pluginhandling.h" 00022 #include "../common/config.h" 00023 #include "../common/options.h" 00024 00025 FEPList* FEPhead; 00026 APList* APhead; 00027 00028 /*................................................................... 00029 Description: Loads a plugin 00030 Args: pointer to filename 00031 Returns: true on success 00032 Created: StonedBon, ??0200 00033 [ToDo:] 00034 Comments: - i actually don't like the use of different lists. (so FEPList, APList.) 00035 I'll change that soon.. xandi, 270200 00036 Changes: - added support for more types of plugins, xandi 00037 - added debug ifdefs :), xandi 00038 -------------------------------------------------------------------*/ 00039 bool add_plugin (char* filename) 00040 { 00041 typedef void *(*pfnPlugIn)(void); 00042 pfnPlugIn getPlugIn; 00043 void *handler; 00044 00045 00046 #ifdef DEBUG 00047 fprintf ( stderr, "\nloading shared library" ); 00048 #endif 00049 if ( ( handler = dlopen (filename, RTLD_NOW ) ) != NULL ) // dynamic loading of the plugin 00050 { 00051 if ( ( getPlugIn = (pfnPlugIn)dlsym ( handler, "GetFrontEndPlugin" ) ) != NULL ) // search for the function 00052 { 00053 FEPList* tmp; 00054 00055 if (FEPhead == NULL) 00056 { 00057 FEPhead = new FEPList; 00058 tmp = FEPhead; 00059 } 00060 else 00061 { 00062 tmp = FEPhead; 00063 00064 while (tmp->next != NULL) tmp = tmp->next; 00065 00066 tmp->next = new FEPList; 00067 tmp = tmp->next; 00068 } 00069 00070 tmp->plug = (FrontEndPlugin *) getPlugIn (); 00071 tmp->id = tmp->plug->id; 00072 tmp->active = true; //this _has_ to be false in near future, when the plugins can be 00073 //selected using a frontend. Then the default _has_ to be false, and 00074 //LoadAllPlugins() looks into the config file to decide which plugins 00075 //will be turned on., xandi 00076 tmp->next = NULL; 00077 } 00078 00079 else if ( ( getPlugIn = (pfnPlugIn)dlsym ( handler, "GetAuthenticationPlugin" ) ) != NULL ) 00080 { 00081 00082 00083 } 00084 else 00085 { 00086 dlclose ( handler ); 00087 return false; 00088 } 00089 00090 return true; 00091 } 00092 else 00093 { 00094 #ifdef DEBUG 00095 fprintf ( stderr, "- failed!\n"); 00096 fprintf ( stderr, "Error: %s\n", dlerror() ); 00097 #endif 00098 return false; 00099 } 00100 } 00101 00102 00103 /*................................................................... 00104 Description: Gets all plugins in a directory 00105 Args: pointer to directoryname 00106 Returns: nothing 00107 Created: xandi, 270200 00108 [ToDo:] 00109 Comments: 00110 Changes: 00111 -------------------------------------------------------------------*/ 00112 void get_plugins ( char *dirname ) 00113 { 00114 string filename; 00115 00116 DIR *dir; 00117 00118 struct dirent *dent; 00119 struct stat statbuf; 00120 00121 dir = opendir(dirname); 00122 00123 if (dir) 00124 { 00125 while ( ( dent = readdir ( dir ) ) != NULL ) 00126 { 00127 filename = dirname; 00128 filename += "/"; 00129 filename += dent->d_name; 00130 00131 if ( !stat ( filename.c_str (), &statbuf ) ) 00132 { 00133 if ( S_ISREG ( statbuf.st_mode ) ) { 00134 if (filename.rfind (".so") != string::npos ) 00135 add_plugin (const_cast<char*>(filename.c_str())); 00136 } 00137 } 00138 } 00139 } 00140 } 00141 00142 00143 00144 00145 /*................................................................... 00146 Description: Loads all plugins stored in the directories defined in the config file 00147 Args: none 00148 Returns: nothing 00149 Created: xandi, 270200 00150 ToDo: lots :) 00151 lookup in config-file to decide which plugins are to be activated 00152 00153 [Comments:] 00154 Changes: 00155 -------------------------------------------------------------------*/ 00156 void LoadAllPlugins ( void ) 00157 { 00158 get_plugins (SERVER_PLUGIN_DIR); 00159 } 00160 00161 00162 00163