summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGluzskiy Alexandr <sss@sss.chaoslab.ru>2015-03-27 16:07:27 +0300
committerGluzskiy Alexandr <sss@sss.chaoslab.ru>2015-03-27 16:07:27 +0300
commitff44c9cd55bff146c6c47277656a967045184c7b (patch)
treeb1d5d59696c8811db0badea0e6dcedca3601b183
parentf87e3320c499edccd545ff3bfc244ef5c7216bb5 (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.h11
-rw-r--r--server/include/api_module_base.h6
-rw-r--r--server/include/api_module_downloader.h2
-rw-r--r--server/include/modules_handler.h46
-rw-r--r--server/modules/metadata/flat_files/flat_files.cbp2
-rw-r--r--server/modules/metadata/flat_files/main.cpp13
-rw-r--r--server/modules/metadata/flat_files/main.h1
-rw-r--r--server/src/main.cpp106
-rw-r--r--server/src/modules_handler.cpp142
-rw-r--r--server/udm-server.cbp10
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 />