Back to index

nordugrid-arc-nox  1.1.0~rc6
arcplugin.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <fstream>
00006 
00007 #include <glibmm/module.h>
00008 #include <glibmm/fileutils.h>
00009 #include <glibmm/miscutils.h>
00010 
00011 #include <arc/loader/Plugin.h>
00012 #include <arc/StringConv.h>
00013 
00014 static std::string encode_for_var(uint32_t v) {
00015     return "\"" + Arc::tostring(v) + "\"";
00016 }
00017 
00018 static std::string encode_for_var(const char* str) {
00019     std::string stro = "\"";
00020     stro += str;
00021     std::string::size_type p = 1;
00022     for(;;++p) {
00023         p = stro.find_first_of("\"\\",p);
00024         if(p == std::string::npos) break;
00025         stro.insert(p, "\\");
00026         ++p;
00027     }
00028     stro += "\"";
00029     return stro;
00030 }
00031 
00032 static std::string replace_file_suffix(const std::string& path,const std::string& newsuffix) {
00033     std::string newpath = path;
00034     std::string::size_type name_p = newpath.rfind(G_DIR_SEPARATOR_S);
00035     if(name_p == std::string::npos) {
00036         name_p = 0;
00037     } else {
00038         ++name_p;
00039     }
00040     std::string::size_type suffix_p = newpath.find('.',name_p);
00041     if(suffix_p != std::string::npos) {
00042         newpath.resize(suffix_p);
00043     }
00044     newpath += "." + newsuffix;
00045     return newpath;
00046 }
00047 
00048 static bool process_module(const std::string& plugin_filename, bool create_apd) {
00049     std::string descriptor_filename = replace_file_suffix(plugin_filename,"apd");
00050     Glib::ModuleFlags flags = Glib::ModuleFlags(0);
00051     flags|=Glib::MODULE_BIND_LAZY;
00052     Glib::Module *module = new Glib::Module(plugin_filename,flags);
00053     if ((!module) || (!(*module))) {
00054         std::cerr << "Failed to load module " << plugin_filename << ": " << Glib::Module::get_last_error() << std::endl;
00055         return false;
00056     }
00057 
00058     std::cout << "Loaded module " << plugin_filename << std::endl;
00059     std::cout << std::endl;
00060 
00061     void *ptr = NULL;
00062     if(!module->get_symbol(PLUGINS_TABLE_SYMB,ptr)) {
00063         std::cerr << "Module " << plugin_filename << " is not an ARC plugin: " << Glib::Module::get_last_error() << std::endl;
00064         if(create_apd) {
00065           std::cerr << "Empty descriptor file will be created to avoid loading this module at all" << std::endl;
00066         }
00067         //delete module;
00068         //return -1;
00069     };
00070 
00071     Arc::PluginDescriptor* desc = (Arc::PluginDescriptor*)ptr;
00072 
00073     std::ofstream apd;
00074     if(create_apd) {
00075         apd.open(descriptor_filename.c_str());
00076         if(!apd) {
00077             std::cerr << "Failed to create descriptor file " << descriptor_filename << std::endl;
00078             return false;
00079         };
00080     };
00081 
00082     for(;desc;++desc) {
00083         if(desc->name == NULL) break;
00084         if(desc->kind == NULL) break;
00085         if(desc->instance == NULL) break;
00086         if(create_apd) {
00087             apd << "name=" << encode_for_var(desc->name) << std::endl;
00088             apd << "kind=" << encode_for_var(desc->kind) << std::endl;
00089             apd << "version=" << encode_for_var(desc->version) << std::endl;
00090             apd << std::endl; // end of description mark
00091         } else {
00092             std::cout << "name: " << desc->name << std::endl;
00093             std::cout << "kind: " << desc->kind << std::endl;
00094             std::cout << "version: " << desc->version << std::endl;
00095             std::cout << std::endl;
00096         };
00097     };
00098 
00099     if(create_apd) {
00100         apd.close();
00101         std::cout << "Created descriptor " << descriptor_filename << std::endl;
00102     };
00103 
00104     // We are not unloading module because it may be not suitable 
00105     // for unloading or it may be library which may fail unloading
00106     // after it was loaded with dlopen().
00107     //delete module;
00108 
00109     return true;
00110 }
00111 
00112 int main(int argc, char **argv)
00113 {
00114     const std::string modsuffix("." G_MODULE_SUFFIX);
00115     bool create_apd = false;
00116     bool recursive = false;
00117 
00118     while (argc > 1) {
00119         if (strcmp(argv[1],"-c") == 0) {
00120             create_apd = true;
00121             --argc; ++argv;
00122         } else if(strcmp(argv[1],"-r") == 0) {
00123             recursive = true;
00124         } else {
00125             break;
00126         };
00127     };
00128    
00129     if (argc < 2) {
00130         std::cerr << "Invalid arguments" << std::endl;        
00131         return -1;
00132     };
00133 
00134     std::list<std::string> paths;
00135     for(int n = 1; n < argc; ++n) paths.push_back(argv[n]);
00136     int user_paths = paths.size();
00137 
00138     int num = 0;
00139     for(std::list<std::string>::iterator path = paths.begin();
00140                   path != paths.end(); ++path) {
00141         try {
00142           Glib::Dir dir(*path);
00143           if((!recursive) && (num >= user_paths)) continue;
00144           for (Glib::DirIterator file = dir.begin();
00145                                 file != dir.end(); file++) {
00146             std::string name = *file;
00147             if(name == ".") continue;
00148             if(name == "..") continue;
00149             paths.push_back(Glib::build_filename(*path, name));
00150           }
00151         } catch (Glib::FileError) {
00152           if(path->length() <= modsuffix.length()) continue;
00153           if(path->substr(path->length()-modsuffix.length()) != modsuffix) continue;
00154           process_module(*path, create_apd);
00155         }
00156         ++num;
00157     }
00158 
00159     //return 0;
00160     // Do quick exit to avoid possible problems with module unloading
00161     _exit(0);
00162 }
00163