/* 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 "utilities.h" #include #include #include #include #include #include "config.h" 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 |RTLD_GLOBAL); if(!lib) { printf("failed to open library \"%s\" with error: %s\n", i->path().c_str(), dlerror()); continue; } 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); continue; } module_metadata_storage *(*f)(void); f = (module_metadata_storage *(*)(void))fptr; //TODO: aditional sanity checks module_metadata_storage *m = 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 |RTLD_GLOBAL); if(!lib) { printf("failed to open library \"%s\" with error: %s\n", i->path().c_str(), dlerror()); continue; } 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); continue; } module_downloader *(*f)(void); f = (module_downloader *(*)(void))fptr; //TODO: aditional sanity checks module_downloader *m = f(); m->load(module_api); sync_module_settings(m); downloader_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() { std::string buf; buf += "Installed metadata modules:\n"; buf += list_modules_single_type_internal(metadata_modules); buf += "\nInstalled downloader modules:\n"; buf += list_modules_single_type_internal(downloader_modules); return buf; } std::string modules_handler::list_modules_single_type_internal(const std::list &modules) { std::string buf; for(auto i = modules.begin(), end = 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.settings.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\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(); } void modules_handler::load_modules() { 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(replace_home_var("~/.share/udm/modules/metadata")); load_metadata_modules("/usr/lib/udm/modules/metadata"); load_downloader_modules(self_dir + "/modules/downloaders"); load_downloader_modules(replace_home_var("~/.share/udm/modules/downloaders")); load_downloader_modules("/usr/lib/udm/modules/downloaders"); load_modules_settings(); } void modules_handler::on_modules_loaded() { for(auto i = metadata_modules.begin(), end = metadata_modules.end(); i != end; ++i) { if(!(*i)->get_module_info().on_modules_loaded.empty()) (*i)->get_module_info().on_modules_loaded(); } for(auto i = downloader_modules.begin(), end = downloader_modules.end(); i != end; ++i) { if(!(*i)->get_module_info().on_modules_loaded.empty()) (*i)->get_module_info().on_modules_loaded(); } } void modules_handler::load_modules_settings() { for(auto i = metadata_modules.begin(), end = metadata_modules.end(); i != end; ++i) (*i)->set_module_settings(module_api->get_module_settings(*i)); for(auto i = downloader_modules.begin(), end = downloader_modules.end(); i != end; ++i) (*i)->set_module_settings(module_api->get_module_settings(*i)); } std::list &modules_handler::get_metadata_modules() { return metadata_modules; } std::list &modules_handler::get_downloader_modules() { return downloader_modules; } modules_handler::~modules_handler() { //dtor }