source: nscp/service/NSCPlugin.cpp @ 60375ed

0.4.00.4.10.4.2
Last change on this file since 60375ed was 60375ed, checked in by Michael Medin <michael@…>, 3 years ago

Fixed *nix compatiblity issues

  • Property mode set to 100644
File size: 15.2 KB
Line 
1/**************************************************************************
2*   Copyright (C) 2004-2007 by Michael Medin <michael@medin.name>         *
3*                                                                         *
4*   This code is part of NSClient++ - http://trac.nakednuns.org/nscp      *
5*                                                                         *
6*   This program is free software; you can redistribute it and/or modify  *
7*   it under the terms of the GNU General Public License as published by  *
8*   the Free Software Foundation; either version 2 of the License, or     *
9*   (at your option) any later version.                                   *
10*                                                                         *
11*   This program is distributed in the hope that it will be useful,       *
12*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14*   GNU General Public License for more details.                          *
15*                                                                         *
16*   You should have received a copy of the GNU General Public License     *
17*   along with this program; if not, write to the                         *
18*   Free Software Foundation, Inc.,                                       *
19*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
20***************************************************************************/
21#include "StdAfx.h"
22#include "NSCPlugin.h"
23#include "core_api.h"
24
25unsigned int NSCPlugin::last_plugin_id_ = 0;
26
27
28/**
29 * Default c-tor
30 * Initializes the plug in name but does not load the actual plug in.<br>
31 * To load the plug in use function load() that loads an initializes the plug in.
32 *
33 * @param file The file (DLL) to load as a NSC plug in.
34 */
35NSCPlugin::NSCPlugin(const boost::filesystem::wpath file)
36        : module_(file.string())
37        ,fLoadModule(NULL)
38        ,fGetName(NULL)
39        ,fHasCommandHandler(NULL)
40        ,fUnLoadModule(NULL)
41        ,fHasMessageHandler(NULL)
42        ,fHandleMessage(NULL)
43        ,fDeleteBuffer(NULL)
44        ,fGetDescription(NULL)
45        ,fGetConfigurationMeta(NULL)
46        ,fGetVersion(NULL)
47        ,fCommandLineExec(NULL)
48        ,fShowTray(NULL)
49        ,fHideTray(NULL)
50        ,fHasNotificationHandler(NULL)
51        ,fHandleNotification(NULL)
52        ,bLoaded_(false)
53        ,lastIsMsgPlugin_(false)
54        ,broken_(false)
55        ,plugin_id_(0)
56{
57        plugin_id_ = ++last_plugin_id_;
58}
59/*
60NSCPlugin::NSCPlugin(NSCPlugin &other)
61        :module_()
62        ,fLoadModule(NULL)
63        ,fGetName(NULL)
64        ,fHasCommandHandler(NULL)
65        ,fUnLoadModule(NULL)
66        ,fHasMessageHandler(NULL)
67        ,fHandleMessage(NULL)
68        ,fGetDescription(NULL)
69        ,fGetConfigurationMeta(NULL)
70        ,fGetVersion(NULL)
71        ,fCommandLineExec(NULL)
72        ,fShowTray(NULL)
73        ,fHideTray(NULL)
74        ,bLoaded_(false)
75        ,lastIsMsgPlugin_(false)
76        ,broken_(false)
77{
78        if (other.bLoaded_) {
79                file_ = other.file_;
80                hModule_ = LoadLibrary(file_.c_str());
81                if (!hModule_)
82                        throw NSPluginException(file_, _T("Could not load library: ") + error::lookup::last_error());
83                loadRemoteProcs_();
84                if (!fLoadModule)
85                        throw NSPluginException(file_, _T("Critical error (fLoadModule)"));
86                bLoaded_ = other.bLoaded_;
87        }
88}
89*/
90/**
91 * Default d-tor
92 */
93NSCPlugin::~NSCPlugin() {
94        if (isLoaded())
95                unload();
96}
97/**
98 * Returns the name of the plug in.
99 *
100 * @return Name of the plug in.
101 *
102 * @throws NSPluginException if the module is not loaded.
103 */
104std::wstring NSCPlugin::getName() {
105        wchar_t *buffer = new wchar_t[1024];
106        if (!getName_(buffer, 1023)) {
107                return _T("Could not get name");
108        }
109        std::wstring ret = buffer;
110        delete [] buffer;
111        return ret;
112}
113std::wstring NSCPlugin::getDescription() {
114        wchar_t *buffer = new wchar_t[4096];
115        if (!getDescription_(buffer, 4095)) {
116                throw NSPluginException(module_, _T("Could not get description"));
117        }
118        std::wstring ret = buffer;
119        delete [] buffer;
120        return ret;
121}
122
123/**
124 * Loads the plug in (DLL) and initializes the plug in by calling NSLoadModule
125 *
126 * @throws NSPluginException when exceptions occur.
127 * Exceptions include but are not limited to: DLL fails to load, DLL is not a correct plug in.
128 */
129void NSCPlugin::load_dll() {
130        if (module_.is_loaded())
131                throw NSPluginException(module_, _T("Module already loaded"));
132        try {
133                module_.load_library();
134        } catch (dll::dll_exception &e) {
135                throw NSPluginException(module_, e.what());
136        }
137        loadRemoteProcs_();
138        bLoaded_ = true;
139}
140
141bool NSCPlugin::load_plugin(NSCAPI::moduleLoadMode mode) {
142        if (!fLoadModule)
143                throw NSPluginException(module_, _T("Critical error (fLoadModule)"));
144        return fLoadModule(mode);
145}
146
147void NSCPlugin::setBroken(bool broken) {
148        broken_ = broken;
149}
150bool NSCPlugin::isBroken() {
151        return broken_;
152}
153
154
155/**
156 * Get the plug in version.
157 *
158 * @bug Not implemented as of yet
159 *
160 * @param *major
161 * @param *minor
162 * @param *revision
163 * @return False
164 */
165bool NSCPlugin::getVersion(int *major, int *minor, int *revision) {
166        if (!isLoaded())
167                throw NSPluginException(module_, _T("Library is not loaded"));
168        if (!fGetVersion)
169                throw NSPluginException(module_, _T("Critical error (fGetVersion)"));
170        try {
171                return fGetVersion(major, minor, revision)?true:false;
172        } catch (...) {
173                throw NSPluginException(module_, _T("Unhandled exception in getVersion."));
174        }
175}
176/**
177 * Returns true if the plug in has a command handler.
178 * @return true if the plug in has a command handler.
179 * @throws NSPluginException if the module is not loaded.
180 */
181bool NSCPlugin::hasCommandHandler() {
182        if (!isLoaded())
183                throw NSPluginException(module_, _T("Module not loaded"));
184        try {
185                if (fHasCommandHandler())
186                        return true;
187                return false;
188        } catch (...) {
189                throw NSPluginException(module_, _T("Unhandled exception in hasCommandHandler."));
190        }
191}
192/**
193* Returns true if the plug in has a message (log) handler.
194* @return true if the plug in has a message (log) handler.
195* @throws NSPluginException if the module is not loaded.
196*/
197bool NSCPlugin::hasMessageHandler() {
198        if (!isLoaded())
199                throw NSPluginException(module_, _T("Module not loaded"));
200        try {
201                if (fHasMessageHandler()) {
202                        lastIsMsgPlugin_ = true;
203                        return true;
204                }
205                return false;
206        } catch (...) {
207                throw NSPluginException(module_, _T("Unhandled exception in hasMessageHandler."));
208        }
209}
210bool NSCPlugin::hasNotificationHandler() {
211        if (!isLoaded())
212                throw NSPluginException(module_, _T("Module not loaded"));
213        if (!fHasNotificationHandler)
214                return false;
215        try {
216                if (fHasNotificationHandler()) {
217                        return true;
218                }
219                return false;
220        } catch (...) {
221                throw NSPluginException(module_, _T("Unhandled exception in hasMessageHandler."));
222        }
223}
224/**
225 * Allow for the plug in to handle a command from the input core.
226 *
227 * Plug ins may refuse to handle the plug in (if not applicable) by returning an empty string.
228 *
229 * @param command The command name (is a string encoded number for legacy commands)
230 * @param argLen The length of the argument buffer.
231 * @param **arguments The arguments for this command
232 * @param returnMessageBuffer Return buffer for plug in to store the result of the executed command.
233 * @param returnMessageBufferLen Size of returnMessageBuffer
234 * @param returnPerfBuffer Return buffer for performance data
235 * @param returnPerfBufferLen Size of returnPerfBuffer
236 * @return Status of execution. Could be error codes, buffer length messages etc.
237 * @throws NSPluginException if the module is not loaded.
238 */
239NSCAPI::nagiosReturn NSCPlugin::handleCommand(const wchar_t* command, const char* dataBuffer, unsigned int dataBuffer_len, char** returnBuffer, unsigned int *returnBuffer_len) {
240        if (!isLoaded())
241                throw NSPluginException(module_, _T("Library is not loaded"));
242        try {
243                return fHandleCommand(command, dataBuffer, dataBuffer_len, returnBuffer, returnBuffer_len);
244        } catch (...) {
245                throw NSPluginException(module_, _T("Unhandled exception in handleCommand."));
246        }
247}
248
249bool NSCPlugin::handleNotification(const wchar_t *channel, const wchar_t* command, NSCAPI::nagiosReturn code, char* result, unsigned int result_len) {
250        if (!isLoaded() || fHandleNotification == NULL)
251                throw NSPluginException(module_, _T("Library is not loaded"));
252        try {
253                return fHandleNotification(channel, command, code, result, result_len);
254        } catch (...) {
255                throw NSPluginException(module_, _T("Unhandled exception in handleCommand."));
256        }
257}
258
259
260
261void NSCPlugin::deleteBuffer(char** buffer) {
262        if (!isLoaded())
263                throw NSPluginException(module_, _T("Library is not loaded"));
264        try {
265                fDeleteBuffer(buffer);
266        } catch (...) {
267                throw NSPluginException(module_, _T("Unhandled exception in deleteBuffer."));
268        }
269}
270NSCAPI::nagiosReturn NSCPlugin::handleCommand(const wchar_t *command, std::string &request, std::string &reply) {
271        char *buffer = NULL;
272        unsigned int len = 0;
273        NSCAPI::nagiosReturn ret = handleCommand(command, request.c_str(), request.size(), &buffer, &len);
274        if (buffer != NULL) {
275                reply = std::string(buffer, len);
276                deleteBuffer(&buffer);
277        }
278        return ret;
279}
280
281/**
282 * Handle a message from the core (or any other (or even potentially self) plug in).
283 * A message may be anything really errors, log messages etc.
284 *
285 * @param msgType Type of message (error, warning, debug, etc.)
286 * @param file The file that generated this message generally __FILE__.
287 * @param line The line in the file that generated the message generally __LINE__
288 * @throws NSPluginException if the module is not loaded.
289 */
290void NSCPlugin::handleMessage(int msgType, const wchar_t* file, const int line, const wchar_t *message) {
291        if (!fHandleMessage)
292                throw NSPluginException(module_, _T("Library is not loaded"));
293        try {
294                fHandleMessage(msgType, file, line, message);
295        } catch (...) {
296                throw NSPluginException(module_, _T("Unhandled exception in handleMessage."));
297        }
298}
299/**
300 * Unload the plug in
301 * @throws NSPluginException if the module is not loaded and/or cannot be unloaded (plug in remains loaded if so).
302 */
303void NSCPlugin::unload() {
304        if (!isLoaded())
305                return;
306        bLoaded_ = false;
307        if (!fUnLoadModule)
308                throw NSPluginException(module_, _T("Critical error (fUnLoadModule)"));
309        try {
310                fUnLoadModule();
311        } catch (...) {
312                throw NSPluginException(module_, _T("Unhandled exception in handleMessage."));
313        }
314        module_.unload_library();
315}
316bool NSCPlugin::getName_(wchar_t* buf, unsigned int buflen) {
317        if (fGetName == NULL)
318                return false;//throw NSPluginException(module_, _T("Critical error (fGetName)"));
319        try {
320                return fGetName(buf, buflen)?true:false;
321        } catch (...) {
322                return false; //throw NSPluginException(module_, _T("Unhandled exception in getName."));
323        }
324}
325bool NSCPlugin::getDescription_(wchar_t* buf, unsigned int buflen) {
326        if (fGetDescription == NULL)
327                throw NSPluginException(module_, _T("Critical error (fGetDescription)"));
328        try {
329                return fGetDescription(buf, buflen)?true:false;
330        } catch (...) {
331                throw NSPluginException(module_, _T("Unhandled exception in getDescription."));
332        }
333}
334
335void NSCPlugin::showTray() {
336        if (fShowTray == NULL)
337                throw NSPluginException(module_, _T("Critical error (ShowTray)"));
338        try {
339                fShowTray();
340        } catch (...) {
341                throw NSPluginException(module_, _T("Unhandled exception in ShowTray."));
342        }
343}
344void NSCPlugin::hideTray() {
345        if (fHideTray == NULL)
346                throw NSPluginException(module_, _T("Critical error (HideTray)"));
347        try {
348                fHideTray();
349        } catch (...) {
350                throw NSPluginException(module_, _T("Unhandled exception in HideTray."));
351        }
352}
353
354/**
355 * Load all remote function pointers from the loaded module.
356 * These pointers are cached for "speed" which might (?) be dangerous if something changes.
357 * @throws NSPluginException if any of the function pointers fail to load.
358 * If NSPluginException  is thrown the loaded might remain partially loaded and crashes might occur if plug in is used in this state.
359 */
360void NSCPlugin::loadRemoteProcs_(void) {
361
362        try {
363                fLoadModule = (lpLoadModule)module_.load_proc("NSLoadModule");
364                if (!fLoadModule)
365                        throw NSPluginException(module_, _T("Could not load NSLoadModule"));
366
367                fModuleHelperInit = (lpModuleHelperInit)module_.load_proc("NSModuleHelperInit");
368                if (!fModuleHelperInit)
369                        throw NSPluginException(module_, _T("Could not load NSModuleHelperInit"));
370
371                try {
372                        fModuleHelperInit(get_id(), NSAPILoader);
373                } catch (...) {
374                        throw NSPluginException(module_, _T("Unhandled exception in getDescription."));
375                }
376
377                fGetName = (lpGetName)module_.load_proc("NSGetModuleName");
378                if (!fGetName)
379                        throw NSPluginException(module_, _T("Could not load NSGetModuleName"));
380
381                fGetVersion = (lpGetVersion)module_.load_proc("NSGetModuleVersion");
382                if (!fGetVersion)
383                        throw NSPluginException(module_, _T("Could not load NSGetModuleVersion"));
384
385                fGetDescription = (lpGetDescription)module_.load_proc("NSGetModuleDescription");
386                if (!fGetDescription)
387                        throw NSPluginException(module_, _T("Could not load NSGetModuleDescription"));
388
389                fHasCommandHandler = (lpHasCommandHandler)module_.load_proc("NSHasCommandHandler");
390                if (!fHasCommandHandler)
391                        throw NSPluginException(module_, _T("Could not load NSHasCommandHandler"));
392
393                fHasMessageHandler = (lpHasMessageHandler)module_.load_proc("NSHasMessageHandler");
394                if (!fHasMessageHandler)
395                        throw NSPluginException(module_, _T("Could not load NSHasMessageHandler"));
396
397                fHandleCommand = (lpHandleCommand)module_.load_proc("NSHandleCommand");
398                //if (!fHandleCommand)
399                //      throw NSPluginException(module_, _T("Could not load NSHandleCommand"));
400
401                fDeleteBuffer = (lpDeleteBuffer)module_.load_proc("NSDeleteBuffer");
402                if (!fDeleteBuffer)
403                        throw NSPluginException(module_, _T("Could not load NSDeleteBuffer"));
404
405                fHandleMessage = (lpHandleMessage)module_.load_proc("NSHandleMessage");
406                if (!fHandleMessage)
407                        throw NSPluginException(module_, _T("Could not load NSHandleMessage"));
408
409                fUnLoadModule = (lpUnLoadModule)module_.load_proc("NSUnloadModule");
410                if (!fUnLoadModule)
411                        throw NSPluginException(module_, _T("Could not load NSUnloadModule"));
412
413                fGetConfigurationMeta = (lpGetConfigurationMeta)module_.load_proc("NSGetConfigurationMeta");
414                fCommandLineExec = (lpCommandLineExec)module_.load_proc("NSCommandLineExec");
415                fHandleNotification = (lpHandleNotification)module_.load_proc("NSHandleNotification");
416                fHasNotificationHandler = (lpHasNotificationHandler)module_.load_proc("NSHasNotificationHandler");
417               
418                fShowTray = (lpShowTray)module_.load_proc("ShowIcon");
419                fHideTray = (lpHideTray)module_.load_proc("HideIcon");
420               
421        } catch (NSPluginException &e) {
422                throw e;
423        } catch (dll::dll_exception &e) {
424                throw NSPluginException(module_, _T("Unhandled exception when loading proces: ") + e.what());
425        } catch (...) {
426                throw NSPluginException(module_, _T("Unhandled exception when loading proces: <UNKNOWN>"));
427        }
428
429}
430
431
432std::wstring NSCPlugin::getCongifurationMeta()
433{
434        wchar_t *buffer = new wchar_t[4097];
435        if (!getConfigurationMeta_(buffer, 4096)) {
436                throw NSPluginException(module_, _T("Could not get metadata"));
437        }
438        std::wstring ret = buffer;
439        delete [] buffer;
440        return ret;
441}
442bool NSCPlugin::getConfigurationMeta_(wchar_t* buf, unsigned int buflen) {
443        if (fGetConfigurationMeta == NULL)
444                throw NSPluginException(module_, _T("Critical error (getCongifurationMeta)"));
445        try {
446                return fGetConfigurationMeta(buflen, buf)?true:false;
447        } catch (...) {
448                throw NSPluginException(module_, _T("Unhandled exception in getConfigurationMeta."));
449        }
450}
451
452int NSCPlugin::commandLineExec(const unsigned int argLen, wchar_t **arguments) {
453        if (fCommandLineExec== NULL)
454                throw NSPluginException(module_, _T("Module does not support CommandLineExec"));
455        try {
456                return fCommandLineExec(argLen, arguments);
457        } catch (...) {
458                throw NSPluginException(module_, _T("Unhandled exception in commandLineExec."));
459        }
460}
Note: See TracBrowser for help on using the repository browser.