]> git.stg.codes - stg.git/blob - projects/stargazer/store_loader.cpp
Add clang to compilers on GitHub.
[stg.git] / projects / stargazer / store_loader.cpp
1 /*
2  *    This program is free software; you can redistribute it and/or modify
3  *    it under the terms of the GNU General Public License as published by
4  *    the Free Software Foundation; either version 2 of the License, or
5  *    (at your option) any later version.
6  *
7  *    This program is distributed in the hope that it will be useful,
8  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *    GNU General Public License for more details.
11  *
12  *    You should have received a copy of the GNU General Public License
13  *    along with this program; if not, write to the Free Software
14  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15  */
16
17 /*
18  *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
19  */
20
21 #include <dlfcn.h>
22
23 #include "stg/common.h"
24 #include "stg/store.h"
25 #include "store_loader.h"
26 #include "settings_impl.h"
27
28 using STG::StoreLoader;
29
30 StoreLoader::StoreLoader(const SettingsImpl& settings) noexcept
31     : isLoaded(false),
32       handle(NULL),
33       plugin(NULL),
34       storeSettings(settings.GetStoreModuleSettings()),
35       pluginFileName(settings.GetModulesPath() + "/mod_" + storeSettings.moduleName + ".so")
36 {
37 }
38
39 StoreLoader::~StoreLoader()
40 {
41     unload();
42 }
43
44 bool StoreLoader::load() noexcept
45 {
46     if (isLoaded)
47     {
48         errorStr = "Store plugin '" + pluginFileName + "' was already loaded!";
49         printfd(__FILE__, "StoreLoader::load() - %s\n", errorStr.c_str());
50         return false;
51     }
52
53     if (pluginFileName.empty())
54     {
55         errorStr = "Empty store plugin filename";
56         printfd(__FILE__, "StoreLoader::load() - %s\n", errorStr.c_str());
57         return true;
58     }
59
60     handle = dlopen(pluginFileName.c_str(), RTLD_NOW);
61
62     if (!handle)
63     {
64         errorStr = "Error loading plugin '"
65             + pluginFileName + "': '" + dlerror() + "'";
66         printfd(__FILE__, "StoreLoader::Load() - %s\n", errorStr.c_str());
67         return true;
68     }
69
70     isLoaded = true;
71
72     using Getter = Store* (*)();
73     auto GetStore = reinterpret_cast<Getter>(dlsym(handle, "GetStore"));
74     if (!GetStore)
75     {
76         errorStr = std::string("GetStore() not found! ") + dlerror();
77         printfd(__FILE__, "StoreLoader::load() - %s\n", errorStr.c_str());
78         return true;
79     }
80
81     plugin = GetStore();
82
83     if (!plugin)
84     {
85         errorStr = "Plugin was not created!";
86         printfd(__FILE__, "StoreLoader::Load() - %s\n");
87         return true;
88     }
89
90     plugin->SetSettings(storeSettings);
91     if (plugin->ParseSettings())
92     {
93         errorStr = plugin->GetStrError();
94         printfd(__FILE__, "StoreLoader::Load() - Failed to parse settings. Plugin reports: '%s'\n", errorStr.c_str());
95         return true;
96     }
97
98     return false;
99 }
100
101 bool StoreLoader::unload() noexcept
102 {
103     if (!isLoaded)
104         return true;
105
106     delete plugin;
107
108     if (dlclose(handle))
109     {
110         errorStr = "Failed to unload plugin '";
111         errorStr += pluginFileName + "': ";
112         errorStr += dlerror();
113         printfd(__FILE__, "StoreLoader::Unload() - %s\n", errorStr.c_str());
114         return true;
115     }
116
117     isLoaded = false;
118
119     return false;
120 }