]> git.stg.codes - stg.git/blob - projects/stargazer/plugin_runner.cpp
e43271c0fc946194e20eab2cfb9e7c7c65f946a6
[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 delete &m_plugin;
52 if (dlclose(libHandle))
53     {
54     errorStr = "Failed to unload plugin '" + pluginFileName + "': " + dlerror();
55     printfd(__FILE__, "PLUGIN_RUNNER::Unload() - %s", errorStr.c_str());
56     }
57 }
58 //-----------------------------------------------------------------------------
59 int PLUGIN_RUNNER::Start()
60 {
61 int res = m_plugin.Start();
62 errorStr = m_plugin.GetStrError();
63 return res;
64 }
65 //-----------------------------------------------------------------------------
66 int PLUGIN_RUNNER::Stop()
67 {
68 int res = m_plugin.Stop();
69 errorStr = m_plugin.GetStrError();
70 return res;
71 }
72 //-----------------------------------------------------------------------------
73 int PLUGIN_RUNNER::Reload(const MODULE_SETTINGS & ms)
74 {
75 int res = m_plugin.Reload(ms);
76 errorStr = m_plugin.GetStrError();
77 return res;
78 }
79 //-----------------------------------------------------------------------------
80 PLUGIN & PLUGIN_RUNNER::Load(const MODULE_SETTINGS & ms,
81                              ADMINS & admins,
82                              TARIFFS & tariffs,
83                              USERS & users,
84                              SERVICES & services,
85                              CORPORATIONS & corporations,
86                              TRAFFCOUNTER & traffcounter,
87                              STORE & store,
88                              const SETTINGS & settings)
89 {
90 if (pluginFileName.empty())
91     {
92     const std::string msg = "Empty plugin file name.";
93     printfd(__FILE__, "PLUGIN_RUNNER::Load() - %s\n", msg.c_str());
94     throw Error(msg);
95     }
96
97 if (access(pluginFileName.c_str(), R_OK))
98     {
99     const std::string msg = "Plugin file '" + pluginFileName + "' is missing or inaccessible.";
100     printfd(__FILE__, "PLUGIN_RUNNER::Load() - %s\n", msg.c_str());
101     throw Error(msg);
102     }
103
104 libHandle = dlopen(pluginFileName.c_str(), RTLD_NOW);
105
106 if (!libHandle)
107     {
108     std::string msg = "Error loading plugin '" + pluginFileName + "'";
109     const char* error = dlerror();
110     if (error)
111         msg = msg + ": '" + error + "'";
112     printfd(__FILE__, "PLUGIN_RUNNER::Load() - %s\n", msg.c_str());
113     throw Error(msg);
114     }
115
116 PLUGIN * (*GetPlugin)();
117 GetPlugin = (PLUGIN * (*)())dlsym(libHandle, "GetPlugin");
118 if (!GetPlugin)
119     {
120     const std::string msg = "Plugin '" + pluginFileName + "' does not have GetPlugin() function. ";
121     printfd(__FILE__, "PLUGIN_RUNNER::Load() - %s\n", msg.c_str());
122     throw Error(msg);
123     }
124 PLUGIN * plugin = GetPlugin();
125
126 if (!plugin)
127     {
128     const std::string msg = "Failed to create an instance of plugin '" + pluginFileName + "'.";
129     printfd(__FILE__, "PLUGIN_RUNNER::Load() - %s\n", msg.c_str());
130     throw Error(msg);
131     }
132
133 plugin->SetSettings(ms);
134 plugin->SetTariffs(&tariffs);
135 plugin->SetAdmins(&admins);
136 plugin->SetUsers(&users);
137 plugin->SetServices(&services);
138 plugin->SetCorporations(&corporations);
139 plugin->SetTraffcounter(&traffcounter);
140 plugin->SetStore(&store);
141 plugin->SetStgSettings(&settings);
142
143 if (plugin->ParseSettings())
144     {
145     const std::string msg = "Plugin '" + pluginFileName + "' is unable to parse settings. " + plugin->GetStrError();
146     printfd(__FILE__, "PLUGIN_RUNNER::Load() - %s\n", msg.c_str());
147     throw Error(msg);
148     }
149
150 return *plugin;
151 }