source: nscp/include/NSCHelper.cpp @ 1eef1ee

0.4.00.4.10.4.2stable
Last change on this file since 1eef1ee was 1eef1ee, checked in by Michael Medin <michael@…>, 8 years ago

*OBS* This might no longer work! (expect updated code in the next few days if things are broken)

  • Fundamental API changes (due to NRPE compatibility)
    • HandleCommand? has changed
    • Inject has changed
    • Most API calls have new "return codes" (typedef:ed INT to allow for return code compiler checks)
    • A lot of the old return codes have changed
  • Preliminary NRPE support (can parse and execute incoming requests, cant return data yet, and no encryption)
  • New SimpleSocket? in include/ will be used as base class for Listeners
  • A lot of rewrite to the NSC API
  • Property mode set to 100644
File size: 17.0 KB
Line 
1#include "stdafx.h"
2#include <NSCHelper.h>
3#include <assert.h>
4
5#define BUFF_LEN 4096
6
7
8/**
9* Wrap a return string.
10* This function copies a string to a char buffer making sure the buffer has the correct length.
11*
12* @param *buffer Buffer to copy the string to.
13* @param bufLen Length of the buffer
14* @param str Th string to copy
15* @return NSCAPI::success unless the buffer is to short then it will be NSCAPI::invalidBufferLen
16*/
17/*
18int NSCHelper::wrapReturnString(char *buffer, unsigned int bufLen, std::string str, int defaultReturnCode ) {
19        // @todo deprecate this
20        if (str.length() >= bufLen)
21                return -1;
22        strncpy(buffer, str.c_str(), bufLen);
23        return defaultReturnCode;
24}
25*/
26NSCAPI::nagiosReturn NSCHelper::wrapReturnString(char *buffer, unsigned int bufLen, std::string str, NSCAPI::nagiosReturn defaultReturnCode /* = NSCAPI::success */) {
27        if (str.length() >= bufLen)
28                return NSCAPI::returnInvalidBufferLen;
29        strncpy(buffer, str.c_str(), bufLen);
30        return defaultReturnCode;
31}
32NSCAPI::errorReturn NSCHelper::wrapReturnString(char *buffer, unsigned int bufLen, std::string str, NSCAPI::errorReturn defaultReturnCode /* = NSCAPI::success */) {
33        if (str.length() >= bufLen)
34                return NSCAPI::isInvalidBufferLen;
35        strncpy(buffer, str.c_str(), bufLen);
36        return defaultReturnCode;
37}
38/**
39 * Make a list out of a array of char arrays (arguments type)
40 * @param argLen Length of argument array
41 * @param *argument[] Argument array
42 * @return Argument wrapped as a list
43 */
44std::list<std::string> NSCHelper::arrayBuffer2list(const unsigned int argLen, char *argument[]) {
45        std::list<std::string> ret;
46        int i=0;
47        for (unsigned int i=0;i<argLen;i++) {
48                std::string s = argument[i];
49                ret.push_back(s);
50        }
51        return ret;
52}
53/**
54 * Create an arrayBuffer from a list.
55 * This is the reverse of arrayBuffer2list.
56 * <b>Notice</b> it is up to the caller to free the memory allocated in the returned buffer.
57 *
58 * @param lst A list to convert.
59 * @param &argLen Write the length to this argument.
60 * @return A pointer that is managed by the caller.
61 */
62char ** NSCHelper::list2arrayBuffer(const std::list<std::string> lst, unsigned int &argLen) {
63        argLen = static_cast<unsigned int>(lst.size());
64        char **arrayBuffer = new char*[argLen];
65        std::list<std::string>::const_iterator it = lst.begin();
66        for (int i=0;it!=lst.end();++it,i++) {
67                std::string::size_type alen = (*it).size();
68                arrayBuffer[i] = new char[alen+2];
69                strncpy(arrayBuffer[i], (*it).c_str(), alen+1);
70        }
71        assert(i == argLen);
72        return arrayBuffer;
73}
74/**
75 * Creates an empty arrayBuffer (only used to allow consistency)
76 * @param &argLen [OUT] The length (items) of the arrayBuffer
77 * @return The arrayBuffer
78 */
79char ** NSCHelper::createEmptyArrayBuffer(unsigned int &argLen) {
80        argLen = 0;
81        char **arrayBuffer = new char*[0];
82        return arrayBuffer;
83}
84/**
85 * Joins an arrayBuffer back into a string
86 * @param **argument The ArrayBuffer
87 * @param argLen The length of the ArrayBuffer
88 * @param join The char to use as separators when joining
89 * @return The joined arrayBuffer
90 */
91std::string NSCHelper::arrayBuffer2string(char **argument, const unsigned int argLen, std::string join) {
92        std::string ret;
93        for (unsigned int i=0;i<argLen;i++) {
94                ret += argument[i];
95                if (i != argLen-1)
96                        ret += join;
97        }
98        return ret;
99}
100/**
101 * Split a string into elements as an arrayBuffer
102 * @param buffer The CharArray to split along
103 * @param splitChar The char to use as splitter
104 * @param &argLen [OUT] The length of the Array
105 * @return The arrayBuffer
106 */
107char ** NSCHelper::split2arrayBuffer(const char* buffer, char splitChar, unsigned int &argLen) {
108        assert(buffer);
109        argLen = 0;
110        const char *p = buffer;
111        while (*p) {
112                if (*p == splitChar)
113                        argLen++;
114                p++;
115        }
116        argLen++;
117        char **arrayBuffer = new char*[argLen];
118        p = buffer;
119        for (unsigned int i=0;i<argLen;i++) {
120                char *q = strchr(p, (i<argLen-1)?splitChar:0);
121                unsigned int len = q-p;
122                arrayBuffer[i] = new char[len+1];
123                strncpy(arrayBuffer[i], p, len);
124                arrayBuffer[i][len] = 0;
125                p = ++q;
126        }
127        return arrayBuffer;
128}
129
130/**
131 * Destroy an arrayBuffer.
132 * The buffer should have been created with list2arrayBuffer.
133 *
134 * @param **argument
135 * @param argLen
136 */
137void NSCHelper::destroyArrayBuffer(char **argument, const unsigned int argLen) {
138        for (unsigned int i=0;i<argLen;i++) {
139                delete [] argument[i];
140        }
141        delete [] argument;
142}
143
144
145/**
146 * Translate a message type into a human readable string.
147 *
148 * @param msgType The message type
149 * @return A string representing the message type
150 */
151std::string NSCHelper::translateMessageType(NSCAPI::messageTypes msgType) {
152        switch (msgType) {
153                case NSCAPI::error:
154                        return "error";
155                case NSCAPI::critical:
156                        return "critical";
157                case NSCAPI::warning:
158                        return "warning";
159                case NSCAPI::log:
160                        return "message";
161                case NSCAPI::debug:
162                        return "debug";
163        }
164        return "unknown";
165}
166std::string NSCHelper::translateReturn(NSCAPI::nagiosReturn returnCode) {
167        if (returnCode == NSCAPI::returnOK)
168                return "OK";
169        else if (returnCode == NSCAPI::returnCRIT)
170                return "CRITICAL";
171        else if (returnCode == NSCAPI::returnWARN)
172                return "WARNING";
173        else
174                return "UNKNOWN";
175}
176
177
178
179namespace NSCModuleHelper {
180        lpNSAPIGetBasePath fNSAPIGetBasePath = NULL;
181        lpNSAPIGetApplicationName fNSAPIGetApplicationName = NULL;
182        lpNSAPIGetApplicationVersionStr fNSAPIGetApplicationVersionStr = NULL;
183        lpNSAPIGetSettingsString fNSAPIGetSettingsString = NULL;
184        lpNSAPIGetSettingsInt fNSAPIGetSettingsInt = NULL;
185        lpNSAPIMessage fNSAPIMessage = NULL;
186        lpNSAPIStopServer fNSAPIStopServer = NULL;
187        lpNSAPIInject fNSAPIInject = NULL;
188}
189
190//////////////////////////////////////////////////////////////////////////
191// Callbacks into the core
192//////////////////////////////////////////////////////////////////////////
193
194/**
195 * Callback to send a message through to the core
196 *
197 * @param msgType Message type (debug, warning, etc.)
198 * @param file File where message was generated (__FILE__)
199 * @param line Line where message was generated (__LINE__)
200 * @param message Message in human readable format
201 * @throws NSCMHExcpetion When core pointer set is unavailable.
202 */
203void NSCModuleHelper::Message(int msgType, std::string file, int line, std::string message) {
204        if (!fNSAPIMessage)
205                throw NSCMHExcpetion("NSCore has not been initiated...");
206        return fNSAPIMessage(msgType, file.c_str(), line, message.c_str());
207}
208/**
209 * Inject a request command in the core (this will then be sent to the plug-in stack for processing)
210 * @param command Command to inject (password should not be included.
211 * @return The result (if any) of the command.
212 * @throws NSCMHExcpetion When core pointer set is unavailable or an unknown inject error occurs.
213 */
214NSCAPI::nagiosReturn NSCModuleHelper::InjectCommandRAW(const char* command, const unsigned int argLen, char **argument, char *returnBuffer, unsigned int returnBufferLen)
215{
216        if (!fNSAPIInject)
217                throw NSCMHExcpetion("NSCore has not been initiated...");
218        return fNSAPIInject(command, argLen, argument, returnBuffer, returnBufferLen);
219}
220NSCAPI::nagiosReturn NSCModuleHelper::InjectCommand(const char* command, const unsigned int argLen, char **argument, std::string & message, std::string & perf)
221{
222        if (!fNSAPIInject)
223                throw NSCMHExcpetion("NSCore has not been initiated...");
224        char *buffer = new char[BUFF_LEN+1];
225        buffer[0] = 0;
226        // @todo message here !
227        NSCAPI::nagiosReturn retC = InjectCommandRAW(command, argLen, argument, buffer, BUFF_LEN);
228        switch (retC) {
229                case NSCAPI::returnIgnored:
230                        NSC_LOG_MESSAGE("No handler for this message.");
231                        break;
232                case NSCAPI::returnInvalidBufferLen:
233                        NSC_LOG_ERROR("Inject command resulted in an invalid buffer size.");
234                        break;
235                case NSCAPI::returnOK:
236                case NSCAPI::returnCRIT:
237                case NSCAPI::returnWARN:
238                case NSCAPI::returnUNKNOWN:
239                        message = buffer;
240                        // @todo perf data
241                        break;
242                default:
243                        throw NSCMHExcpetion("Unknown inject error.");
244        }
245        delete [] buffer;
246        return retC;
247}
248/**
249 * A wrapper around the InjetCommand that is simpler to use.
250 * Parses a string by splitting and makes the array and also manages return buffers and such.
251 * @param command The command to execute
252 * @param buffer The buffer to splitwww.ikea.se
253
254 * @param splitChar The char to use as splitter
255 * @return The result of the command
256 */
257NSCAPI::nagiosReturn NSCModuleHelper::InjectSplitAndCommand(const char* command, char* buffer, char splitChar, std::string & message, std::string & perf)
258{
259        if (!fNSAPIInject)
260                throw NSCMHExcpetion("NSCore has not been initiated...");
261        unsigned int argLen = 0;
262        char ** aBuffer;
263        if (buffer)
264                aBuffer= NSCHelper::split2arrayBuffer(buffer, splitChar, argLen);
265        else
266                aBuffer= NSCHelper::createEmptyArrayBuffer(argLen);
267        NSCAPI::nagiosReturn ret = InjectCommand(command, argLen, aBuffer, message, perf);
268        NSCHelper::destroyArrayBuffer(aBuffer, argLen);
269        return ret;
270}
271/**
272 * Ask the core to shutdown (only works when run as a service, o/w does nothing ?
273 * @todo Check if this might cause damage if not run as a service.
274 */
275void NSCModuleHelper::StopService(void) {
276        if (fNSAPIStopServer)
277                fNSAPIStopServer();
278}
279/**
280 * Retrieve a string from the settings subsystem (INI-file)
281 * Might possibly be located in the registry in the future.
282 *
283 * @param section Section key (generally module specific, make sure this is "unique")
284 * @param key The key to retrieve
285 * @param defaultValue A default value (if no value is set in the settings file)
286 * @return the current value or defaultValue if no value is set.
287 * @throws NSCMHExcpetion When core pointer set is unavailable or an error occurs.
288 */
289std::string NSCModuleHelper::getSettingsString(std::string section, std::string key, std::string defaultValue) {
290        if (!fNSAPIGetSettingsString)
291                throw NSCMHExcpetion("NSCore has not been initiated...");
292        char *buffer = new char[BUFF_LEN+1];
293        if (fNSAPIGetSettingsString(section.c_str(), key.c_str(), defaultValue.c_str(), buffer, BUFF_LEN) != NSCAPI::isSuccess) {
294                delete [] buffer;
295                throw NSCMHExcpetion("Settings could not be retrieved.");
296        }
297        std::string ret = buffer;
298        delete [] buffer;
299        return ret;
300}
301/**
302 * Retrieve an int from the settings subsystem (INI-file)
303 * Might possibly be located in the registry in the future.
304 *
305 * @param section Section key (generally module specific, make sure this is "unique")
306 * @param key The key to retrieve
307 * @param defaultValue A default value (if no value is set in the settings file)
308 * @return the current value or defaultValue if no value is set.
309 * @throws NSCMHExcpetion When core pointer set is unavailable.
310 */
311int NSCModuleHelper::getSettingsInt(std::string section, std::string key, int defaultValue) {
312        if (!fNSAPIGetSettingsInt)
313                throw NSCMHExcpetion("NSCore has not been initiated...");
314        return fNSAPIGetSettingsInt(section.c_str(), key.c_str(), defaultValue);
315}
316/**
317 * Retrieve the application name (in human readable format) from the core.
318 * @return A string representing the application name.
319 * @throws NSCMHExcpetion When core pointer set is unavailable or an unexpected error occurs.
320 */
321std::string NSCModuleHelper::getApplicationName() {
322        if (!fNSAPIGetApplicationName)
323                throw NSCMHExcpetion("NSCore has not been initiated...");
324        char *buffer = new char[BUFF_LEN+1];
325        if (fNSAPIGetApplicationName(buffer, BUFF_LEN) != NSCAPI::isSuccess) {
326                delete [] buffer;
327                throw NSCMHExcpetion("Application name could not be retrieved");
328        }
329        std::string ret = buffer;
330        delete [] buffer;
331        return ret;
332}
333/**
334 * Retrieve the directory root of the application from the core.
335 * @return A string representing the base path.
336 * @throws NSCMHExcpetion When core pointer set is unavailable or an unexpected error occurs.
337 */
338std::string NSCModuleHelper::getBasePath() {
339        if (!fNSAPIGetBasePath)
340                throw NSCMHExcpetion("NSCore has not been initiated...");
341        char *buffer = new char[BUFF_LEN+1];
342        if (fNSAPIGetBasePath(buffer, BUFF_LEN) != NSCAPI::isSuccess) {
343                delete [] buffer;
344                throw NSCMHExcpetion("Base path could not be retrieved");
345        }
346        std::string ret = buffer;
347        delete [] buffer;
348        return ret;
349}
350/**
351 * Retrieve the application version as a string (in human readable format) from the core.
352 * @return A string representing the application version.
353 * @throws NSCMHExcpetion When core pointer set is unavailable.
354 */
355std::string NSCModuleHelper::getApplicationVersionString() {
356        if (!fNSAPIGetApplicationVersionStr)
357                throw NSCMHExcpetion("NSCore has not been initiated...");
358        char *buffer = new char[BUFF_LEN+1];
359        int x = fNSAPIGetApplicationVersionStr(buffer, BUFF_LEN);
360        std::string ret = buffer;
361        delete [] buffer;
362        return ret;
363}
364
365//////////////////////////////////////////////////////////////////////////
366// Module helper functions
367//////////////////////////////////////////////////////////////////////////
368namespace NSCModuleWrapper {
369        HINSTANCE hModule_ = NULL;
370}
371/**
372 * Used to help store the module handle (and possibly other things in the future)
373 * @param hModule cf. DllMain
374 * @param ul_reason_for_call cf. DllMain
375 * @return TRUE
376 */
377BOOL NSCModuleWrapper::wrapDllMain(HANDLE hModule, DWORD ul_reason_for_call)
378{
379        switch (ul_reason_for_call)
380        {
381        case DLL_PROCESS_ATTACH:
382        case DLL_THREAD_ATTACH:
383                hModule_ = (HINSTANCE)hModule;
384                break;
385        case DLL_THREAD_DETACH:
386        case DLL_PROCESS_DETACH:
387                break;
388        }
389        return TRUE;
390}
391/**
392 * Retrieve the module handle from the DllMain call.
393 * @return Module handle of this DLL
394 */
395HINSTANCE NSCModuleWrapper::getModule() {
396        return hModule_;
397}
398
399/**
400 * Wrapper function around the ModuleHelperInit call.
401 * This wrapper retrieves all pointers and stores them for future use.
402 * @param f A function pointer to a function that can be used to load function from the core.
403 * @return NSCAPI::success or NSCAPI::failure
404 */
405int NSCModuleWrapper::wrapModuleHelperInit(NSCModuleHelper::lpNSAPILoader f) {
406        NSCModuleHelper::fNSAPIGetApplicationName = (NSCModuleHelper::lpNSAPIGetApplicationName)f("NSAPIGetApplicationName");
407        NSCModuleHelper::fNSAPIGetApplicationVersionStr = (NSCModuleHelper::lpNSAPIGetApplicationVersionStr)f("NSAPIGetApplicationVersionStr");
408        NSCModuleHelper::fNSAPIGetSettingsInt = (NSCModuleHelper::lpNSAPIGetSettingsInt)f("NSAPIGetSettingsInt");
409        NSCModuleHelper::fNSAPIGetSettingsString = (NSCModuleHelper::lpNSAPIGetSettingsString)f("NSAPIGetSettingsString");
410        NSCModuleHelper::fNSAPIMessage = (NSCModuleHelper::lpNSAPIMessage)f("NSAPIMessage");
411        NSCModuleHelper::fNSAPIStopServer = (NSCModuleHelper::lpNSAPIStopServer)f("NSAPIStopServer");
412        NSCModuleHelper::fNSAPIInject = (NSCModuleHelper::lpNSAPIInject)f("NSAPIInject");
413        NSCModuleHelper::fNSAPIGetBasePath = (NSCModuleHelper::lpNSAPIGetBasePath)f("NSAPIGetBasePath");
414        return NSCAPI::isSuccess;
415}
416/**
417* Wrap the GetModuleName function call
418* @param buf Buffer to store the module name
419* @param bufLen Length of buffer
420* @param str String to store inside the buffer
421* @return buffer copy status
422*/
423NSCAPI::errorReturn NSCModuleWrapper::wrapGetModuleName(char* buf, unsigned int bufLen, std::string str) {
424        return NSCHelper::wrapReturnString(buf, bufLen, str, NSCAPI::isSuccess);
425}
426/**
427 * Wrap the GetModuleVersion function call
428 * @param *major Major version number
429 * @param *minor Minor version number
430 * @param *revision Revision
431 * @param version version as a module_version
432 * @return NSCAPI::success
433 */
434NSCAPI::errorReturn NSCModuleWrapper::wrapGetModuleVersion(int *major, int *minor, int *revision, module_version version) {
435        *major = version.major;
436        *minor = version.minor;
437        *revision = version.revision;
438        return NSCAPI::isSuccess;
439}
440/**
441 * Wrap the HasCommandHandler function call
442 * @param has true if this module has a command handler
443 * @return NSCAPI::istrue or NSCAPI::isfalse
444 */
445NSCAPI::boolReturn NSCModuleWrapper::wrapHasCommandHandler(bool has) {
446        if (has)
447                return NSCAPI::istrue;
448        return NSCAPI::isfalse;
449}
450/**
451 * Wrap the HasMessageHandler function call
452 * @param has true if this module has a message handler
453 * @return NSCAPI::istrue or NSCAPI::isfalse
454 */
455NSCAPI::boolReturn NSCModuleWrapper::wrapHasMessageHandler(bool has) {
456        if (has)
457                return NSCAPI::istrue;
458        return NSCAPI::isfalse;
459}
460/**
461 * Wrap the HandleCommand call
462 * @param retStr The string to return to the core
463 * @param *returnBuffer A buffer to copy the return string to
464 * @param returnBufferLen length of returnBuffer
465 * @return copy status or NSCAPI::isfalse if retStr is empty
466 */
467NSCAPI::nagiosReturn NSCModuleWrapper::wrapHandleCommand(NSCAPI::nagiosReturn retResult, const std::string retMessage, const std::string retPerformance, char *returnBufferMessage, unsigned int returnBufferMessageLen, char *returnBufferPerf, unsigned int returnBufferPerfLen) {
468        if (retMessage.empty())
469                return NSCAPI::returnIgnored;
470        NSCAPI::nagiosReturn ret = NSCHelper::wrapReturnString(returnBufferMessage, returnBufferMessageLen, retMessage, retResult);
471        return NSCHelper::wrapReturnString(returnBufferPerf, returnBufferPerfLen, retPerformance, ret);
472}
473/**
474 * Wrap the NSLoadModule call
475 * @param success true if module load was successfully
476 * @return NSCAPI::success or NSCAPI::failed
477 */
478int NSCModuleWrapper::wrapLoadModule(bool success) {
479        if (success)
480                return NSCAPI::isSuccess;
481        return NSCAPI::hasFailed;
482}
483/**
484 * Wrap the NSUnloadModule call
485 * @param success true if module load was successfully
486 * @return NSCAPI::success or NSCAPI::failed
487 */
488int NSCModuleWrapper::wrapUnloadModule(bool success) {
489        if (success)
490                return NSCAPI::isSuccess;
491        return NSCAPI::hasFailed;
492}
493
494
495
Note: See TracBrowser for help on using the repository browser.