/* Copyright © 2015 Gluzskiy Alexandr (sss) This file is part of Unknown Download Manager (UDM). UDM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. UDM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with UDM. If not, see . */ #include "modules_handler.h" #include "main.h" #include #include #include #include #include namespace bpt = boost::property_tree; extern runtime_config_s runtime_config; extern core_api *module_api; void modules_handler::load_metadata_modules(const std::string &path) { if(boost::filesystem::exists(path) && boost::filesystem::is_directory(path)) { for(boost::filesystem::directory_iterator i(path), end = boost::filesystem::directory_iterator(); i != end; ++i) { void *lib = dlopen(i->path().generic_string().c_str(), RTLD_LAZY); if(!lib) { printf("failed to open library \"%s\" with error: %s\n", i->path().c_str(), dlerror()); return; } void *fptr = dlsym(lib, "udm_metadata_module_load"); if(!fptr) { printf("failed to find symbol \"udm_metadata_module_load\" in library %s with error %s\n", i->path().c_str(), dlerror()); dlclose(lib); return; } void *(*f)(void); f = (void* (*)())fptr; //TODO: aditional sanity checks module_metadata_storage *m = static_cast(f()); m->load(module_api); sync_module_settings(m); metadata_modules.push_back(m); } } } void modules_handler::load_downloader_modules(const std::string &path) { if(boost::filesystem::exists(path) && boost::filesystem::is_directory(path)) { for(boost::filesystem::directory_iterator i(path), end = boost::filesystem::directory_iterator(); i != end; ++i) { void *lib = dlopen(i->path().generic_string().c_str(), RTLD_LAZY); if(!lib) { printf("failed to open library \"%s\" with error: %s\n", i->path().c_str(), dlerror()); return; } void *fptr = dlsym(lib, "udm_downloader_module_load"); if(!fptr) { printf("failed to find symbol \"udm_downloader_module_load\" in library %s with error %s\n", i->path().c_str(), dlerror()); dlclose(lib); return; } void *(*f)(void); f = (void* (*)())fptr; //TODO: aditional sanity checks module_metadata_storage *m = static_cast(f()); m->load(module_api); sync_module_settings(m); metadata_modules.push_back(m); } } } std::string modules_handler::get_self_path() { //TODO: dynamic buffer char buf[1024]; readlink("/proc/self/exe", buf, 1023); std::string s (buf); return s; } std::string modules_handler::list_modules(short verbose_level) { std::string buf; buf += "Installed metadata modules:\n"; for(auto i = metadata_modules.begin(), end = metadata_modules.end(); i != end; ++i) { buf += "\tName: "; buf += (*i)->get_module_info().name; buf += "\n\tDescription: " +(*i)->get_module_info().description; buf += "\n\tVersion: " + (*i)->get_module_info().version; if(runtime_config.verbosity >= 1) { buf += "\n\tAvailable options:"; for(auto i1 = (*i)->get_module_info().default_settings.begin(), end = (*i)->get_module_info().default_settings.end(); i1 != end; ++i1) { buf += "\n\t\t"; buf += i1->first; buf += " = "; buf += i1->second; } } buf += "\n"; } buf += "Installed downloader modules:\n"; for(auto i = downloader_modules.begin(), end = downloader_modules.end(); i != end; ++i) { buf += "\t"; buf += (*i)->get_module_info().name; buf += " (" + (*i)->get_module_info().description + ") "; buf += "v" + (*i)->get_module_info().version; buf += "\n"; } return buf; } void modules_handler::sync_module_settings(module_base *m) { for(auto i = m->get_module_info().default_settings.begin(), end = m->get_module_info().default_settings.end(); i != end; ++i) { std::string setting = "modules." + m->get_module_info().name + "." + i->first; std::string current_val = runtime_config.config_file.get(setting, "not set"), default_val = i->second; if(current_val == "not set" || current_val != default_val) runtime_config.config_file.put(setting, i->second); } } modules_handler::modules_handler() { self_path = get_self_path(); boost::filesystem::path p(self_path); std::string self_dir = p.parent_path().generic_string(); load_metadata_modules(self_dir + "/modules/metadata"); load_metadata_modules("~/.share/udm/modules/metadata"); load_metadata_modules("/usr/lib/udm/modules/metadata"); load_downloader_modules(self_dir + "/modules/downloader"); load_downloader_modules("~/.share/udm/modules/downloader"); load_downloader_modules("/usr/lib/udm/modules/downloader"); } modules_handler::~modules_handler() { //dtor }