diff options
author | Gluzskiy Alexandr <sss@sss.chaoslab.ru> | 2015-03-27 16:07:27 +0300 |
---|---|---|
committer | Gluzskiy Alexandr <sss@sss.chaoslab.ru> | 2015-03-27 16:07:27 +0300 |
commit | ff44c9cd55bff146c6c47277656a967045184c7b (patch) | |
tree | b1d5d59696c8811db0badea0e6dcedca3601b183 | |
parent | f87e3320c499edccd545ff3bfc244ef5c7216bb5 (diff) |
working module loader
basic program options support
abitilty to print installed modules info
started config support implementation
-rw-r--r-- | server/include/api_core.h | 11 | ||||
-rw-r--r-- | server/include/api_module_base.h | 6 | ||||
-rw-r--r-- | server/include/api_module_downloader.h | 2 | ||||
-rw-r--r-- | server/include/modules_handler.h | 46 | ||||
-rw-r--r-- | server/modules/metadata/flat_files/flat_files.cbp | 2 | ||||
-rw-r--r-- | server/modules/metadata/flat_files/main.cpp | 13 | ||||
-rw-r--r-- | server/modules/metadata/flat_files/main.h | 1 | ||||
-rw-r--r-- | server/src/main.cpp | 106 | ||||
-rw-r--r-- | server/src/modules_handler.cpp | 142 | ||||
-rw-r--r-- | server/udm-server.cbp | 10 |
10 files changed, 308 insertions, 31 deletions
diff --git a/server/include/api_core.h b/server/include/api_core.h index 29e3886..1663f09 100644 --- a/server/include/api_core.h +++ b/server/include/api_core.h @@ -23,15 +23,20 @@ #define API_CORE_H_INCLUDED #include <string> #include <vector> +#include <map> class module_base; class core_api { - virtual bool metadata_set(const module_base *m, const std::string &setting_name, const std::vector<char> &data); - virtual bool metadata_get(const module_base *m, const std::string &setting_name, std::vector<char> &data); - virtual bool metadata_remove(const module_base *m, const std::string &setting_name); + //core + std::map<std::string, std::string> get_module_settings(const module_base *m); + + //metadata + bool metadata_set(const module_base *m, const std::string &setting_name, const std::vector<char> &data); + bool metadata_get(const module_base *m, const std::string &setting_name, std::vector<char> &data); + bool metadata_remove(const module_base *m, const std::string &setting_name); }; diff --git a/server/include/api_module_base.h b/server/include/api_module_base.h index 27797bc..38c9a00 100644 --- a/server/include/api_module_base.h +++ b/server/include/api_module_base.h @@ -26,6 +26,7 @@ struct module_info { std::string name, description, version; + std::map<std::string, std::string> default_settings; //to save in config file }; class module_base @@ -33,7 +34,10 @@ class module_base public: virtual void load(core_api *a) = 0; virtual const module_info &get_module_info() = 0; - virtual ~module_base() =0; + virtual void set_module_settings(const std::map<std::string, std::string> &settings) = 0; + virtual ~module_base() = 0; + protected: + std::map<std::string, std::string> settings; }; diff --git a/server/include/api_module_downloader.h b/server/include/api_module_downloader.h index 0c4bcf0..3cf8ec6 100644 --- a/server/include/api_module_downloader.h +++ b/server/include/api_module_downloader.h @@ -27,7 +27,7 @@ struct downloader_module_info : public module_info { }; -class downloader_module : public module_base +class module_downloader : public module_base { }; diff --git a/server/include/modules_handler.h b/server/include/modules_handler.h new file mode 100644 index 0000000..efcbebc --- /dev/null +++ b/server/include/modules_handler.h @@ -0,0 +1,46 @@ +/* + 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 <http://www.gnu.org/licenses/>. + +*/ + + +#ifndef MODULES_HANDLER_H +#define MODULES_HANDLER_H + +#include <api_module_metadata_storage.h> +#include <api_module_downloader.h> +#include <list> + +class modules_handler +{ + public: + modules_handler(); + std::string list_modules(); + ~modules_handler(); + private: + void load_metadata_modules(const std::string &path); + void load_downloader_modules(const std::string &path); + std::string get_self_path(); + std::string self_path; + std::list<module_metadata_storage*> metadata_modules; + std::list<module_downloader*> downloader_modules; + + +}; + +#endif // MODULES_HANDLER_H diff --git a/server/modules/metadata/flat_files/flat_files.cbp b/server/modules/metadata/flat_files/flat_files.cbp index e297909..7dd9c9f 100644 --- a/server/modules/metadata/flat_files/flat_files.cbp +++ b/server/modules/metadata/flat_files/flat_files.cbp @@ -2,7 +2,7 @@ <CodeBlocks_project_file> <FileVersion major="1" minor="6" /> <Project> - <Option title="flat_files" /> + <Option title="module_metadata_flat_files" /> <Option pch_mode="2" /> <Option compiler="gcc" /> <Build> diff --git a/server/modules/metadata/flat_files/main.cpp b/server/modules/metadata/flat_files/main.cpp index 3015cd5..78b8a58 100644 --- a/server/modules/metadata/flat_files/main.cpp +++ b/server/modules/metadata/flat_files/main.cpp @@ -27,8 +27,12 @@ void storage_impl::load(core_api *a) { api = a; + + info.name = "flat_files_metadata"; + info.description = "this module provide metadata storage in flat files"; + info.version = "0.0.0.1"; + info.default_settings["data_path"] = "~/.local/share/udm/metadata"; std::cout<<"flat_files metadata module succesfully loaded\n"; - //TODO: set module_info } @@ -37,6 +41,11 @@ const module_info &storage_impl::get_module_info() return info; } +void storage_impl::set_module_settings(const std::map<std::string, std::string> &settings) +{ + this->settings = settings; +} + bool storage_impl::set(const std::string &module_name, const std::string &setting_name, const std::vector<char> &data) { @@ -65,7 +74,7 @@ module_base::~module_base() } -extern "C" void* load() +extern "C" void* udm_metadata_module_load() { return new storage_impl; } diff --git a/server/modules/metadata/flat_files/main.h b/server/modules/metadata/flat_files/main.h index 706e21d..5604623 100644 --- a/server/modules/metadata/flat_files/main.h +++ b/server/modules/metadata/flat_files/main.h @@ -33,6 +33,7 @@ class storage_impl: public module_metadata_storage //module base void load(core_api *a); const module_info &get_module_info(); + void set_module_settings(const std::map<std::string, std::string> &settings); //metadata module bool set(const std::string &module_name, const std::string &setting_name, const std::vector<char> &data); bool get(const std::string &module_name, const std::string &setting_name, std::vector<char> &data); diff --git a/server/src/main.cpp b/server/src/main.cpp index 54bb498..67e5fa6 100644 --- a/server/src/main.cpp +++ b/server/src/main.cpp @@ -17,36 +17,100 @@ along with UDM. If not, see <http://www.gnu.org/licenses/>. */ +#include <boost/program_options.hpp> +#include <boost/property_tree/ptree.hpp> +#include <boost/property_tree/info_parser.hpp> +#include <boost/filesystem.hpp> +#include <iostream> -#include <dlfcn.h> #include <api_module_metadata_storage.h> +#include <modules_handler.h> -core_api module_api; -void module_load_test() +core_api *module_api = nullptr; + +modules_handler *modules = nullptr; + +namespace bpo = boost::program_options; +namespace bpt = boost::property_tree; + +bpt::ptree config; + + + +int main(int argc, char *argv[]) { - void *lib = dlopen("./modules/metadata/libflat_files.so", RTLD_LAZY); - if(!lib) + bpo::options_description desc("Available commands and options"); + desc.add_options() + ("help", "this message") + ("daemon", "fork to background") + ("config", bpo::value<std::string>(), "use specified config file instead of \"~/.config/udm/udm.conf\"") + ("list-modules", "list all installed modules") + ("run", "start UDM server") + ; + + bool daemon = false, run = false; + std::string config_path = "~/.config/udm/udm.conf"; + try{ + + bpo::variables_map vm; + bpo::store(bpo::parse_command_line(argc, argv, desc), vm); + bpo::notify(vm); + + //load config first, as it may be needed for other commands + if(vm.count("config")) + config_path = vm["config"].as<std::string>(); + + if(boost::filesystem::exists(config_path) && boost::filesystem::is_regular(config_path)) + bpt::read_info(config_path, config); //TODO: finish this + else + std::cerr<<"failed to load config: \"" + config_path + "\", file does not exists or is not regular file\n"; + + + if(vm.count("help")) + { + std::cout<<desc<<std::endl; + return 0; + } + if(vm.count("daemon")) + { + daemon = true; + } + if(vm.count("list-modules")) + { + if(!module_api) + module_api = new core_api; + if(!modules) + modules = new modules_handler; + std::cout<<modules->list_modules(); + return 0; + } + if(vm.count("run")) + { + run = true; + } + } + catch(std::exception &e) { - printf("%s\n", dlerror()); - return; + std::cerr<<"error: "<<e.what()<<std::endl; + std::cout<<desc<<std::endl; + return -1; } - void *fptr = dlsym(lib, "load"); - if(!fptr) + catch(...) { - printf("%s\n", dlerror()); - dlclose(lib); - return; + //noop + return -1; } - void *(*f)(void); - f = (void* (*)())fptr; - module_metadata_storage *m = static_cast<module_metadata_storage*>(f()); - m->load(&module_api); -} - + if(run) + { + if(daemon) + { + //TODO: fork here + } + } + //module_api must be created first + std::cerr<<"error: no command specified"<<std::endl; + std::cout<<desc<<std::endl; -int main(int argc, char *argv[]) -{ - module_load_test(); return 0; } diff --git a/server/src/modules_handler.cpp b/server/src/modules_handler.cpp new file mode 100644 index 0000000..a6dbcef --- /dev/null +++ b/server/src/modules_handler.cpp @@ -0,0 +1,142 @@ +/* + 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 <http://www.gnu.org/licenses/>. + +*/ + +#include "modules_handler.h" +#include <unistd.h> +#include <dlfcn.h> +#include <string> + +#include <boost/filesystem.hpp> + + +#include <iostream> + +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<module_metadata_storage*>(f()); + m->load(module_api); + 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<module_metadata_storage*>(f()); + m->load(module_api); + 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() +{ + std::string buf; + buf += "Installed metadata modules:\n"; + for(auto i = metadata_modules.begin(), end = metadata_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"; + } + 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; +} + + +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 +} diff --git a/server/udm-server.cbp b/server/udm-server.cbp index 613d1e9..de8ccd5 100644 --- a/server/udm-server.cbp +++ b/server/udm-server.cbp @@ -22,6 +22,7 @@ <Option compiler="gcc" /> <Compiler> <Add option="-O2" /> + <Add directory="server/include" /> </Compiler> <Linker> <Add option="-s" /> @@ -36,10 +37,13 @@ <Linker> <Add library="protobuf" /> <Add library="dl" /> + <Add library="boost_system" /> + <Add library="boost_filesystem" /> + <Add library="boost_program_options" /> </Linker> <ExtraCommands> - <Add before="[ -d ../protocol ] || mkdir ../protocol" /> - <Add before="protoc --cpp_out=../protocol --proto_path=../protocol ../protocol/udm.proto" /> + <Add before="#[ -d ../protocol ] || mkdir ../protocol" /> + <Add before="#protoc --cpp_out=../protocol --proto_path=../protocol ../protocol/udm.proto" /> </ExtraCommands> <Unit filename="../protocol/udm.pb.cc" /> <Unit filename="../protocol/udm.pb.h" /> @@ -47,9 +51,11 @@ <Unit filename="include/api_module_base.h" /> <Unit filename="include/api_module_downloader.h" /> <Unit filename="include/api_module_metadata_storage.h" /> + <Unit filename="include/modules_handler.h" /> <Unit filename="include/protocol.h" /> <Unit filename="src/api_core.cpp" /> <Unit filename="src/main.cpp" /> + <Unit filename="src/modules_handler.cpp" /> <Unit filename="src/protocol.cpp" /> <Extensions> <code_completion /> |