9682fa8346cdf9700cc65058139f2b460e704372
[public/netxms.git] / src / server / core / nxslext.cpp
1 /*
2 ** NetXMS - Network Management System
3 ** Copyright (C) 2003-2011 Victor Kirhenshtein
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 **
19 ** File: nxslext.cpp
20 **
21 **/
22
23 #include "nxcore.h"
24
25
26 //
27 // Externals
28 //
29
30 extern DWORD g_nxslNumSituationFunctions;
31 extern NXSL_ExtFunction g_nxslSituationFunctions[];
32
33 void RegisterDCIFunctions(NXSL_Environment *pEnv);
34
35
36 //
37 // Get node's custom attribute
38 // First argument is a node object, and second is an attribute name
39 //
40
41 static int F_GetCustomAttribute(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_Program *program)
42 {
43 NXSL_Object *object;
44 Node *node;
45 const TCHAR *value;
46
47 if (!argv[0]->isObject())
48 return NXSL_ERR_NOT_OBJECT;
49
50 if (!argv[1]->isString())
51 return NXSL_ERR_NOT_STRING;
52
53 object = argv[0]->getValueAsObject();
54 if (_tcscmp(object->getClass()->getName(), g_nxslNodeClass.getName()))
55 return NXSL_ERR_BAD_CLASS;
56
57 node = (Node *)object->getData();
58 value = node->GetCustomAttribute(argv[1]->getValueAsCString());
59 if (value != NULL)
60 {
61 *ppResult = new NXSL_Value(value);
62 }
63 else
64 {
65 *ppResult = new NXSL_Value; // Return NULL if attribute not found
66 }
67
68 return 0;
69 }
70
71
72 //
73 // Set node's custom attribute
74 // First argument is a node object, second is an attribute name, third is new value
75 // Returns previous value
76 //
77
78 static int F_SetCustomAttribute(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_Program *program)
79 {
80 NXSL_Object *object;
81 Node *node;
82 const TCHAR *value;
83
84 if (!argv[0]->isObject())
85 return NXSL_ERR_NOT_OBJECT;
86
87 if (!argv[1]->isString() || !argv[2]->isString())
88 return NXSL_ERR_NOT_STRING;
89
90 object = argv[0]->getValueAsObject();
91 if (_tcscmp(object->getClass()->getName(), g_nxslNodeClass.getName()))
92 return NXSL_ERR_BAD_CLASS;
93
94 node = (Node *)object->getData();
95 value = node->GetCustomAttribute(argv[1]->getValueAsCString());
96 if (value != NULL)
97 {
98 *ppResult = new NXSL_Value(value);
99 }
100 else
101 {
102 *ppResult = new NXSL_Value; // Return NULL if attribute not found
103 }
104
105 node->SetCustomAttribute(argv[1]->getValueAsCString(), argv[2]->getValueAsCString());
106
107 return 0;
108 }
109
110
111 //
112 // Get interface name by index
113 // Parameters: node object and interface index
114 //
115
116 static int F_GetInterfaceName(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_Program *program)
117 {
118 if (!argv[0]->isObject())
119 return NXSL_ERR_NOT_OBJECT;
120
121 if (!argv[1]->isInteger())
122 return NXSL_ERR_NOT_INTEGER;
123
124 NXSL_Object *object = argv[0]->getValueAsObject();
125 if (_tcscmp(object->getClass()->getName(), g_nxslNodeClass.getName()))
126 return NXSL_ERR_BAD_CLASS;
127
128 Node *node = (Node *)object->getData();
129 Interface *ifc = node->findInterface(argv[1]->getValueAsUInt32(), INADDR_ANY);
130 if (ifc != NULL)
131 {
132 *ppResult = new NXSL_Value(ifc->Name());
133 }
134 else
135 {
136 *ppResult = new NXSL_Value; // Return NULL if interface not found
137 }
138
139 return 0;
140 }
141
142
143 //
144 // Find node object
145 // First argument: current node object or null
146 // Second argument: node id or name
147 // Returns node object or null if requested node was not found or access to it was denied
148 //
149
150 static int F_FindNodeObject(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_Program *program)
151 {
152 Node *currNode = NULL, *node = NULL;
153
154 if (!argv[0]->isNull())
155 {
156 if (!argv[0]->isObject())
157 return NXSL_ERR_NOT_OBJECT;
158
159 NXSL_Object *object = argv[0]->getValueAsObject();
160 if (_tcscmp(object->getClass()->getName(), g_nxslNodeClass.getName()))
161 return NXSL_ERR_BAD_CLASS;
162
163 currNode = (Node *)object->getData();
164 }
165
166 if (!argv[1]->isString())
167 return NXSL_ERR_NOT_STRING;
168
169 if (argv[1]->isInteger())
170 {
171 NetObj *o = FindObjectById(argv[1]->getValueAsUInt32());
172 if ((o != NULL) && (o->Type() == OBJECT_NODE))
173 node = (Node *)o;
174 }
175 else
176 {
177 node = (Node *)FindObjectByName(argv[1]->getValueAsCString(), OBJECT_NODE);
178 }
179
180 if (node != NULL)
181 {
182 if (g_dwFlags & AF_CHECK_TRUSTED_NODES)
183 {
184 if ((currNode != NULL) && (node->IsTrustedNode(currNode->Id())))
185 {
186 *ppResult = new NXSL_Value(new NXSL_Object(&g_nxslNodeClass, node));
187 }
188 else
189 {
190 // No access, return null
191 *ppResult = new NXSL_Value;
192 DbgPrintf(4, _T("NXSL::FindNodeObject(%s [%d], '%s'): access denied for node %s [%d]"),
193 (currNode != NULL) ? currNode->Name() : _T("null"), (currNode != NULL) ? currNode->Id() : 0,
194 argv[1]->getValueAsCString(), node->Name(), node->Id());
195 }
196 }
197 else
198 {
199 *ppResult = new NXSL_Value(new NXSL_Object(&g_nxslNodeClass, node));
200 }
201 }
202 else
203 {
204 // Node not found, return null
205 *ppResult = new NXSL_Value;
206 }
207
208 return 0;
209 }
210
211
212 //
213 // Get node object's parents
214 // First argument: node object
215 // Returns array of accessible parent objects
216 //
217
218 static int F_GetNodeParents(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_Program *program)
219 {
220 if (!argv[0]->isObject())
221 return NXSL_ERR_NOT_OBJECT;
222
223 NXSL_Object *object = argv[0]->getValueAsObject();
224 if (_tcscmp(object->getClass()->getName(), g_nxslNodeClass.getName()))
225 return NXSL_ERR_BAD_CLASS;
226
227 Node *node = (Node *)object->getData();
228 *ppResult = new NXSL_Value(node->getParentsForNXSL());
229 return 0;
230 }
231
232
233 //
234 // Get event's named parameter
235 // First argument: event object
236 // Second argument: parameter's name
237 // Returns parameter's value or null
238 //
239
240 static int F_GetEventParameter(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_Program *program)
241 {
242 if (!argv[0]->isObject())
243 return NXSL_ERR_NOT_OBJECT;
244
245 NXSL_Object *object = argv[0]->getValueAsObject();
246 if (_tcscmp(object->getClass()->getName(), g_nxslEventClass.getName()))
247 return NXSL_ERR_BAD_CLASS;
248
249 if (!argv[1]->isString())
250 return NXSL_ERR_NOT_STRING;
251
252 Event *e = (Event *)object->getData();
253 const TCHAR *value = e->getNamedParameter(argv[1]->getValueAsCString());
254 *ppResult = (value != NULL) ? new NXSL_Value(value) : new NXSL_Value;
255 return 0;
256 }
257
258
259 //
260 // Set event's named parameter
261 // First argument: event object
262 // Second argument: parameter's name
263 // Third argument: new value
264 //
265
266 static int F_SetEventParameter(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_Program *program)
267 {
268 if (!argv[0]->isObject())
269 return NXSL_ERR_NOT_OBJECT;
270
271 NXSL_Object *object = argv[0]->getValueAsObject();
272 if (_tcscmp(object->getClass()->getName(), g_nxslEventClass.getName()))
273 return NXSL_ERR_BAD_CLASS;
274
275 if (!argv[1]->isString() || !argv[2]->isString())
276 return NXSL_ERR_NOT_STRING;
277
278 Event *e = (Event *)object->getData();
279 e->setNamedParameter(argv[1]->getValueAsCString(), argv[2]->getValueAsCString());
280 *ppResult = new NXSL_Value;
281 return 0;
282 }
283
284
285 //
286 // Post event
287 // Syntax:
288 // PostEvent(node, event, tag, ...)
289 // where:
290 // node - node object to send event on behalf of
291 // event - event code
292 // tag - user tag (optional)
293 // ... - optional parameters, will be passed as %1, %2, etc.
294 //
295
296 static int F_PostEvent(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_Program *program)
297 {
298 if (argc < 2)
299 return NXSL_ERR_INVALID_ARGUMENT_COUNT;
300
301 // Validate first argument
302 if (!argv[0]->isObject())
303 return NXSL_ERR_NOT_OBJECT;
304
305 NXSL_Object *object = argv[0]->getValueAsObject();
306 if (_tcscmp(object->getClass()->getName(), g_nxslNodeClass.getName()))
307 return NXSL_ERR_BAD_CLASS;
308
309 Node *node = (Node *)object->getData();
310
311 // Validate secod argument - event code
312 if (!argv[1]->isInteger())
313 return NXSL_ERR_NOT_INTEGER;
314
315 // User tag
316 const TCHAR *userTag = NULL;
317 if (argc > 2)
318 {
319 if (!argv[2]->isString())
320 return NXSL_ERR_NOT_STRING;
321 userTag = argv[2]->getValueAsCString();
322 }
323
324 // Post event
325 char format[] = "ssssssssssssssssssssssssssssssss";
326 const TCHAR *plist[32];
327 int eargc = 0;
328 for(int i = 3; (i < argc) && (eargc < 32); i++)
329 plist[eargc++] = argv[i]->getValueAsCString();
330 format[eargc] = 0;
331 BOOL success = PostEventWithTag(argv[1]->getValueAsUInt32(), node->Id(), userTag, format,
332 plist[0], plist[1], plist[2], plist[3],
333 plist[4], plist[5], plist[6], plist[7],
334 plist[8], plist[9], plist[10], plist[11],
335 plist[12], plist[13], plist[14], plist[15],
336 plist[16], plist[17], plist[18], plist[19],
337 plist[20], plist[21], plist[22], plist[23],
338 plist[24], plist[25], plist[26], plist[27],
339 plist[28], plist[29], plist[30], plist[31]);
340
341 *ppResult = new NXSL_Value((LONG)success);
342 return 0;
343 }
344
345
346 //
347 // Additional server functions to use within all scripts
348 //
349
350 static NXSL_ExtFunction m_nxslServerFunctions[] =
351 {
352 { _T("GetCustomAttribute"), F_GetCustomAttribute, 2 },
353 { _T("GetEventParameter"), F_GetEventParameter, 2 },
354 { _T("GetInterfaceName"), F_GetInterfaceName, 2 },
355 { _T("GetNodeParents"), F_GetNodeParents, 1 },
356 { _T("FindNodeObject"), F_FindNodeObject, 2 },
357 { _T("PostEvent"), F_PostEvent, -1 },
358 { _T("SetCustomAttribute"), F_SetCustomAttribute, 3 }
359 };
360
361
362 //
363 // Constructor for server default script environment
364 //
365
366 NXSL_ServerEnv::NXSL_ServerEnv()
367 : NXSL_Environment()
368 {
369 setLibrary(g_pScriptLibrary);
370 registerFunctionSet(sizeof(m_nxslServerFunctions) / sizeof(NXSL_ExtFunction), m_nxslServerFunctions);
371 RegisterDCIFunctions(this);
372 registerFunctionSet(g_nxslNumSituationFunctions, g_nxslSituationFunctions);
373 }
374
375
376 //
377 // Script trace output
378 //
379
380 void NXSL_ServerEnv::trace(int level, const TCHAR *text)
381 {
382 if (level == 0)
383 {
384 nxlog_write(MSG_OTHER, EVENTLOG_INFORMATION_TYPE, "s", text);
385 }
386 else
387 {
388 DbgPrintf(level, _T("%s"), text);
389 }
390 }