UnivesalDisassembler(2003)
|
00001 // plugins.cc 00002 // 00003 // uda - universal disassembler 00004 // Date: 2003-05-04 00005 // 00006 // Copyright (c) 2002-2003 Ales Smrcka 00007 // 00008 // This program is licensed under GNU Library GPL. See the file COPYING. 00009 // 00010 // This module contains administration of plugins (loading, syncing). 00011 // 00012 00013 #include <iostream> 00014 #include <dlfcn.h> 00015 #include <stdio.h> 00016 #include <sys/types.h> 00017 #include <sys/stat.h> 00018 #include <unistd.h> 00019 #include <dirent.h> 00020 #include <libgen.h> 00021 #include "plugins.h" 00022 #include "shared.h" 00023 #include "udaclasses.h" 00024 using namespace std; 00025 00026 const char *pluginsdir = "plugins/"; 00027 const char *configfile = "plugins/list"; 00028 00029 // plugins array (not NULL are relevant) 00030 VPlugins plugins; 00031 00032 int EvEmpty_data(void*) 00033 { 00034 return 0; 00035 } 00036 00037 int EvEmpty_void() 00038 { 00039 return 0; 00040 } 00041 00043 // Class Plugin 00044 00045 Plugin::Plugin() 00046 { 00047 dynfile=NULL; 00048 IsFileDefined=(Ev_IsFileDefined)&EvEmpty_data; 00049 LoadSections=(Ev_LoadSections)&EvEmpty_data; 00050 LoadSymbols=(Ev_LoadSymbols)&EvEmpty_void; 00051 } 00052 00053 Plugin::~Plugin() 00054 { 00055 Close(); 00056 } 00057 00059 int Plugin::Open(const char *file) 00060 { 00061 dynfile = dlopen(file, RTLD_LAZY); 00062 if (dynfile==NULL) 00063 return 0; 00064 Splugin_init plugin_init = (Splugin_init)dlsym(dynfile, "plugin_init"); 00065 const char *error; 00066 if ((error=dlerror())!=NULL) 00067 { 00068 debug("plugin_init function mistakes in "<<basename((char*)file)<<endl); 00069 dlclose(dynfile); 00070 return 0; 00071 } 00072 plugin_init(type, ident, syntax, Params); 00073 if (type&PLUGIN_SECTIONS) 00074 { 00075 IsFileDefined = (Ev_IsFileDefined)dlsym(dynfile, "is_file_defined"); 00076 if ((error=dlerror())!=NULL) 00077 { 00078 debug("is_file_defined function mistakes in "<<basename((char*)file)<<endl); 00079 dlclose(dynfile); 00080 return 0; 00081 } 00082 LoadSections = (Ev_LoadSections)dlsym(dynfile, "load_sections"); 00083 if ((error=dlerror())!=NULL) 00084 { 00085 debug("load_sections function mistakes in "<<basename((char*)file)<<endl); 00086 dlclose(dynfile); 00087 return 0; 00088 } 00089 } 00090 if (type&PLUGIN_SYMTABLE) 00091 { 00092 LoadSymbols = (Ev_LoadSymbols)dlsym(dynfile, "load_symbols"); 00093 if ((error=dlerror())!=NULL) 00094 { 00095 debug("load_symbols function mistakes in "<<basename((char*)file)<<endl); 00096 dlclose(dynfile); 00097 return 0; 00098 } 00099 } 00100 filename=basename((char*)file); 00101 debug("Loaded plugin: "<<filename<<endl); 00102 return 1; 00103 } 00104 00105 void Plugin::Close() 00106 { 00107 if (dynfile!=NULL) 00108 dlclose(dynfile); 00109 } 00110 00111 // Print plugin information 00112 void Plugin::Info() 00113 { 00114 cout<<"Plugin "<<filename<<":"<<endl; 00115 cout<<" ID="<<ident<<endl; 00116 cout<<" attributes="; 00117 if (type&PLUGIN_SECTIONS) 00118 cout<<"PLUGIN_SECTIONS"; 00119 if (type&~PLUGIN_SECTIONS) 00120 cout<<", "; 00121 if (type&PLUGIN_SYMTABLE) 00122 cout<<"PLUGIN_SYMTABLE"; 00123 cout<<endl; 00124 cout<<" options="; 00125 if (syntax!=NULL) 00126 cout<<syntax; 00127 else 00128 cout<<"<none>"; 00129 cout<<endl; 00130 } 00131 00133 // OpenPlugins() and ClosePlugins() 00134 00135 // Load all plugins 00136 int OpenPlugins() 00137 { 00138 int actualpl=0; 00139 FILE *cfg; 00140 char file[1024]; 00141 Plugin *pl; 00142 debug("Opening plugins from config file...\n"); 00143 //open config file (list of plugins) 00144 if ((cfg=fopen((basedir+configfile).c_str(), "r"))!=NULL) 00145 { 00146 while (fgets(file, 1023, cfg)!=NULL) 00147 { 00148 //get C string from line 00149 file[1023]=0; 00150 for (int i=0;i<1024;i++) 00151 if (file[i]=='\n') 00152 { 00153 file[i]=0; 00154 break; 00155 } 00156 //create plugin info 00157 pl=new Plugin; 00158 //load plugin info 00159 debug("Plugins::Open(): try to open "<<file<<endl); 00160 if (!pl->Open(file) && !pl->Open((basedir+pluginsdir+file).c_str())) 00161 { 00162 debug("Can not open plugin "<<file<<endl); 00163 delete pl; //bad plugin 00164 } 00165 else 00166 plugins.push_back(pl); 00167 } //while load line 00168 fclose(cfg); 00169 } 00170 debug("Opening plugins from plugins directory...\n"); 00171 00172 //load plugins from plugin directory 00173 DIR *dir; 00174 struct dirent *dp; 00175 struct stat buf; 00176 char olddir[1024]; 00177 getcwd(olddir, 1023); 00178 if (chdir((basedir+pluginsdir).c_str())) 00179 return actualpl; 00180 if ((dir=opendir("."))==NULL) 00181 return actualpl; 00182 file[0]='.';file[1]='/'; 00183 //read files 00184 while ((dp=readdir(dir))!=NULL) 00185 if ((stat(dp->d_name, &buf)==0) && (S_ISREG(buf.st_mode)))//is regular (symlink included) 00186 { 00187 register bool already_loaded=false; 00188 VPlugins::iterator i; 00189 for (i=plugins.begin();i!=plugins.end();i++) 00190 if ((already_loaded = (*i)->filename==dp->d_name)) 00191 break; 00192 if (!already_loaded) 00193 { 00194 strncpy(&file[2], dp->d_name, 1020); 00195 //create plugin info 00196 pl=new Plugin; 00197 //load plugin info 00198 debug("Plugins::Open(): try to open "<<&file[2]<<endl); 00199 if (!pl->Open(file)) 00200 { 00201 debug("Can not open plugin "<<file<<endl); 00202 delete pl; //bad plugin 00203 } 00204 else 00205 plugins.push_back(pl); 00206 } 00207 } 00208 closedir(dir); 00209 chdir(olddir); 00210 return plugins.size(); 00211 } //OpenPlugins 00212 00213 void ClosePlugins() 00214 { 00215 VPlugins::iterator i; 00216 for (i=plugins.begin();i!=plugins.end();i++) 00217 delete *i; 00218 plugins.clear(); 00219 } 00220 00221 void PluginsInfo() 00222 { 00223 VPlugins::iterator i; 00224 for (i=plugins.begin();i!=plugins.end();i++) 00225 (*i)->Info(); 00226 } 00227