implemented nxsl class "Interface" and function GetInterfaceObject; manual updated
[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 // Get interface object by index
145 // Parameters: node object and interface index
146 //
147
148 static int F_GetInterfaceObject(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_Program *program)
149 {
150 if (!argv[0]->isObject())
151 return NXSL_ERR_NOT_OBJECT;
152
153 if (!argv[1]->isInteger())
154 return NXSL_ERR_NOT_INTEGER;
155
156 NXSL_Object *object = argv[0]->getValueAsObject();
157 if (_tcscmp(object->getClass()->getName(), g_nxslNodeClass.getName()))
158 return NXSL_ERR_BAD_CLASS;
159
160 Node *node = (Node *)object->getData();
161 Interface *ifc = node->findInterface(argv[1]->getValueAsUInt32(), INADDR_ANY);
162 if (ifc != NULL)
163 {
164 *ppResult = new NXSL_Value(new NXSL_Object(&g_nxslInterfaceClass, ifc));
165 }
166 else
167 {
168 *ppResult = new NXSL_Value; // Return NULL if interface not found
169 }
170
171 return 0;
172 }
173
174
175 //
176 // Find node object
177 // First argument: current node object or null
178 // Second argument: node id or name
179 // Returns node object or null if requested node was not found or access to it was denied
180 //
181
182 static int F_FindNodeObject(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_Program *program)
183 {
184 Node *currNode = NULL, *node = NULL;
185
186 if (!argv[0]->isNull())
187 {
188 if (!argv[0]->isObject())
189 return NXSL_ERR_NOT_OBJECT;
190
191 NXSL_Object *object = argv[0]->getValueAsObject();
192 if (_tcscmp(object->getClass()->getName(), g_nxslNodeClass.getName()))
193 return NXSL_ERR_BAD_CLASS;
194
195 currNode = (Node *)object->getData();
196 }
197
198 if (!argv[1]->isString())
199 return NXSL_ERR_NOT_STRING;
200
201 if (argv[1]->isInteger())
202 {
203 NetObj *o = FindObjectById(argv[1]->getValueAsUInt32());
204 if ((o != NULL) && (o->Type() == OBJECT_NODE))
205 node = (Node *)o;
206 }
207 else
208 {
209 node = (Node *)FindObjectByName(argv[1]->getValueAsCString(), OBJECT_NODE);
210 }
211
212 if (node != NULL)
213 {
214 if (g_dwFlags & AF_CHECK_TRUSTED_NODES)
215 {
216 if ((currNode != NULL) && (node->IsTrustedNode(currNode->Id())))
217 {
218 *ppResult = new NXSL_Value(new NXSL_Object(&g_nxslNodeClass, node));
219 }
220 else
221 {
222 // No access, return null
223 *ppResult = new NXSL_Value;
224 DbgPrintf(4, _T("NXSL::FindNodeObject(%s [%d], '%s'): access denied for node %s [%d]"),
225 (currNode != NULL) ? currNode->Name() : _T("null"), (currNode != NULL) ? currNode->Id() : 0,
226 argv[1]->getValueAsCString(), node->Name(), node->Id());
227 }
228 }
229 else
230 {
231 *ppResult = new NXSL_Value(new NXSL_Object(&g_nxslNodeClass, node));
232 }
233 }
234 else
235 {
236 // Node not found, return null
237 *ppResult = new NXSL_Value;
238 }
239
240 return 0;
241 }
242
243
244 //
245 // Get node object's parents
246 // First argument: node object
247 // Returns array of accessible parent objects
248 //
249
250 static int F_GetNodeParents(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_Program *program)
251 {
252 if (!argv[0]->isObject())
253 return NXSL_ERR_NOT_OBJECT;
254
255 NXSL_Object *object = argv[0]->getValueAsObject();
256 if (_tcscmp(object->getClass()->getName(), g_nxslNodeClass.getName()))
257 return NXSL_ERR_BAD_CLASS;
258
259 Node *node = (Node *)object->getData();
260 *ppResult = new NXSL_Value(node->getParentsForNXSL());
261 return 0;
262 }
263
264
265 //
266 // Get event's named parameter
267 // First argument: event object
268 // Second argument: parameter's name
269 // Returns parameter's value or null
270 //
271
272 static int F_GetEventParameter(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_Program *program)
273 {
274 if (!argv[0]->isObject())
275 return NXSL_ERR_NOT_OBJECT;
276
277 NXSL_Object *object = argv[0]->getValueAsObject();
278 if (_tcscmp(object->getClass()->getName(), g_nxslEventClass.getName()))
279 return NXSL_ERR_BAD_CLASS;
280
281 if (!argv[1]->isString())
282 return NXSL_ERR_NOT_STRING;
283
284 Event *e = (Event *)object->getData();
285 const TCHAR *value = e->getNamedParameter(argv[1]->getValueAsCString());
286 *ppResult = (value != NULL) ? new NXSL_Value(value) : new NXSL_Value;
287 return 0;
288 }
289
290
291 //
292 // Set event's named parameter
293 // First argument: event object
294 // Second argument: parameter's name
295 // Third argument: new value
296 //
297
298 static int F_SetEventParameter(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_Program *program)
299 {
300 if (!argv[0]->isObject())
301 return NXSL_ERR_NOT_OBJECT;
302
303 NXSL_Object *object = argv[0]->getValueAsObject();
304 if (_tcscmp(object->getClass()->getName(), g_nxslEventClass.getName()))
305 return NXSL_ERR_BAD_CLASS;
306
307 if (!argv[1]->isString() || !argv[2]->isString())
308 return NXSL_ERR_NOT_STRING;
309
310 Event *e = (Event *)object->getData();
311 e->setNamedParameter(argv[1]->getValueAsCString(), argv[2]->getValueAsCString());
312 *ppResult = new NXSL_Value;
313 return 0;
314 }
315
316
317 //
318 // Post event
319 // Syntax:
320 // PostEvent(node, event, tag, ...)
321 // where:
322 // node - node object to send event on behalf of
323 // event - event code
324 // tag - user tag (optional)
325 // ... - optional parameters, will be passed as %1, %2, etc.
326 //
327
328 static int F_PostEvent(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_Program *program)
329 {
330 if (argc < 2)
331 return NXSL_ERR_INVALID_ARGUMENT_COUNT;
332
333 // Validate first argument
334 if (!argv[0]->isObject())
335 return NXSL_ERR_NOT_OBJECT;
336
337 NXSL_Object *object = argv[0]->getValueAsObject();
338 if (_tcscmp(object->getClass()->getName(), g_nxslNodeClass.getName()))
339 return NXSL_ERR_BAD_CLASS;
340
341 Node *node = (Node *)object->getData();
342
343 // Validate secod argument - event code
344 if (!argv[1]->isInteger())
345 return NXSL_ERR_NOT_INTEGER;
346
347 // User tag
348 const TCHAR *userTag = NULL;
349 if (argc > 2)
350 {
351 if (!argv[2]->isString())
352 return NXSL_ERR_NOT_STRING;
353 userTag = argv[2]->getValueAsCString();
354 }
355
356 // Post event
357 char format[] = "ssssssssssssssssssssssssssssssss";
358 const TCHAR *plist[32];
359 int eargc = 0;
360 for(int i = 3; (i < argc) && (eargc < 32); i++)
361 plist[eargc++] = argv[i]->getValueAsCString();
362 format[eargc] = 0;
363 BOOL success = PostEventWithTag(argv[1]->getValueAsUInt32(), node->Id(), userTag, format,
364 plist[0], plist[1], plist[2], plist[3],
365 plist[4], plist[5], plist[6], plist[7],
366 plist[8], plist[9], plist[10], plist[11],
367 plist[12], plist[13], plist[14], plist[15],
368 plist[16], plist[17], plist[18], plist[19],
369 plist[20], plist[21], plist[22], plist[23],
370 plist[24], plist[25], plist[26], plist[27],
371 plist[28], plist[29], plist[30], plist[31]);
372
373 *ppResult = new NXSL_Value((LONG)success);
374 return 0;
375 }
376
377
378 //
379 // Additional server functions to use within all scripts
380 //
381
382 static NXSL_ExtFunction m_nxslServerFunctions[] =
383 {
384 { _T("GetCustomAttribute"), F_GetCustomAttribute, 2 },
385 { _T("GetEventParameter"), F_GetEventParameter, 2 },
386 { _T("GetInterfaceName"), F_GetInterfaceName, 2 },
387 { _T("GetInterfaceObject"), F_GetInterfaceObject, 2 },
388 { _T("GetNodeParents"), F_GetNodeParents, 1 },
389 { _T("FindNodeObject"), F_FindNodeObject, 2 },
390 { _T("PostEvent"), F_PostEvent, -1 },
391 { _T("SetCustomAttribute"), F_SetCustomAttribute, 3 }
392 };
393
394
395 //
396 // Constructor for server default script environment
397 //
398
399 NXSL_ServerEnv::NXSL_ServerEnv()
400 : NXSL_Environment()
401 {
402 setLibrary(g_pScriptLibrary);
403 registerFunctionSet(sizeof(m_nxslServerFunctions) / sizeof(NXSL_ExtFunction), m_nxslServerFunctions);
404 RegisterDCIFunctions(this);
405 registerFunctionSet(g_nxslNumSituationFunctions, g_nxslSituationFunctions);
406 }
407
408
409 //
410 // Script trace output
411 //
412
413 void NXSL_ServerEnv::trace(int level, const TCHAR *text)
414 {
415 if (level == 0)
416 {
417 nxlog_write(MSG_OTHER, EVENTLOG_INFORMATION_TYPE, "s", text);
418 }
419 else
420 {
421 DbgPrintf(level, _T("%s"), text);
422 }
423 }