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