]> git.stg.codes - stg.git/blob - projects/stargazer/plugin_runner.cpp
e57a421ef245d955d6c0dfbd9945cf9e404d6cae
[stg.git] / projects / stargazer / plugin_runner.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 : Boris Mikhailenko <stg34@stargazer.dp.ua>
19  *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
20  */
21
22 #include "plugin_runner.h"
23
24 #include "stg/common.h"
25
26 #include <dlfcn.h>
27 #include <unistd.h>
28
29 //-----------------------------------------------------------------------------
30 PLUGIN_RUNNER::PLUGIN_RUNNER(const std::string & fileName,
31                              const std::string & name,
32                              const MODULE_SETTINGS & ms,
33                              ADMINS & admins,
34                              TARIFFS & tariffs,
35                              USERS & users,
36                              SERVICES & services,
37                              CORPORATIONS & corporations,
38                              TRAFFCOUNTER & traffcounter,
39                              STORE & store,
40                              const SETTINGS & settings)
41     : pluginFileName(fileName),
42       pluginName(name),
43       libHandle(NULL),
44       m_plugin(Load(ms, admins, tariffs, users, services, corporations,
45                     traffcounter, store, settings))
46 {
47 }
48 //-----------------------------------------------------------------------------
49 PLUGIN_RUNNER::~PLUGIN_RUNNER()
50 {
51 if (dlclose(libHandle))
52     {
53     errorStr = "Failed to unload plugin '" + pluginFileName + "': " + dlerror();
54     printfd(__FILE__, "PLUGIN_RUNNER::Unload() - %s", errorStr.c_str());
55     }
56 }
57 //-----------------------------------------------------------------------------
58 int PLUGIN_RUNNER::Start()
59 {
60 int res = m_plugin.Start();
61 errorStr = m_plugin.GetStrError();
62 return res;
63 }
64 //-----------------------------------------------------------------------------
65 int PLUGIN_RUNNER::Stop()
66 {
67 int res = m_plugin.Stop();
68 errorStr = m_plugin.GetStrError();
69 return res;
70 }
71 //-----------------------------------------------------------------------------
72 int PLUGIN_RUNNER::Reload(const MODULE_SETTINGS & ms)
73 {
74 int res = m_plugin.Reload(ms);
75 errorStr = m_plugin.GetStrError();
76 return res;
77 }
78 //-----------------------------------------------------------------------------
79 PLUGIN & PLUGIN_RUNNER::Load(const MODULE_SETTINGS & ms,
80                              ADMINS & admins,
81                              TARIFFS & tariffs,
82                              USERS & users,
83                              SERVICES & services,
84                              CORPORATIONS & corporations,
85                              TRAFFCOUNTER & traffcounter,
86                              STORE & store,
87                              const SETTINGS & settings)
88 {
89 if (pluginFileName.empty())
90     {
91     const std::string msg = "Empty plugin file name.";
92     printfd(__FILE__, "PLUGIN_RUNNER::Load() - %s\n", msg.c_str());
93     throw Error(msg);
94     }
95
96 if (access(pluginFileName.c_str(), R_OK))
97     {
98     const std::string msg = "Plugin file '" + pluginFileName + "' is missing or inaccessible.";
99     printfd(__FILE__, "PLUGIN_RUNNER::Load() - %s\n", msg.c_str());
100     throw Error(msg);
101     }
102
103 libHandle = dlopen(pluginFileName.c_str(), RTLD_NOW);
104
105 if (!libHandle)
106     {
107     std::string msg = "Error loading plugin '" + pluginFileName + "'";
108     const char* error = dlerror();
109     if (error)
110         msg = msg + ": '" + error + "'";
111     printfd(__FILE__, "PLUGIN_RUNNER::Load() - %s\n", msg.c_str());
112     throw Error(msg);
113     }
114
115 PLUGIN * (*GetPlugin)();
116 GetPlugin = (PLUGIN * (*)())dlsym(libHandle, "GetPlugin");
117 if (!GetPlugin)
118     {
119     const std::string msg = "Plugin '" + pluginFileName + "' does not have GetPlugin() function. ";
120     printfd(__FILE__, "PLUGIN_RUNNER::Load() - %s\n", msg.c_str());
121     throw Error(msg);
122     }
123 PLUGIN * plugin = GetPlugin();
124
125 if (!plugin)
126     {
127     const std::string msg = "Failed to create an instance of plugin '" + pluginFileName + "'.";
128     printfd(__FILE__, "PLUGIN_RUNNER::Load() - %s\n", msg.c_str());
129     throw Error(msg);
130     }
131
132 plugin->SetSettings(ms);
133 plugin->SetTariffs(&tariffs);
134 plugin->SetAdmins(&admins);
135 plugin->SetUsers(&users);
136 plugin->SetServices(&services);
137 plugin->SetCorporations(&corporations);
138 plugin->SetTraffcounter(&traffcounter);
139 plugin->SetStore(&store);
140 plugin->SetStgSettings(&settings);
141
142 if (plugin->ParseSettings())
143     {
144     const std::string msg = "Plugin '" + pluginFileName + "' is unable to parse settings. " + plugin->GetStrError();
145     printfd(__FILE__, "PLUGIN_RUNNER::Load() - %s\n", msg.c_str());
146     throw Error(msg);
147     }
148
149 return *plugin;
150 }