c7ce0cea31c54a97d2b5c5527b0fcd998411cc27
[public/netxms.git] / src / server / core / nxslext.cpp
1 /*
2 ** NetXMS - Network Management System
3 ** Copyright (C) 2003-2014 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 * Externals
27 */
28 extern UINT32 g_nxslNumSituationFunctions;
29 extern NXSL_ExtFunction g_nxslSituationFunctions[];
30
31 void RegisterDCIFunctions(NXSL_Environment *pEnv);
32 int F_map(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm);
33
34 /**
35 * Get node's custom attribute
36 * First argument is a node object, and second is an attribute name
37 */
38 static int F_GetCustomAttribute(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
39 {
40 NXSL_Object *object;
41 const TCHAR *value;
42
43 if (!argv[0]->isObject())
44 return NXSL_ERR_NOT_OBJECT;
45
46 if (!argv[1]->isString())
47 return NXSL_ERR_NOT_STRING;
48
49 object = argv[0]->getValueAsObject();
50 if (_tcscmp(object->getClass()->getName(), g_nxslNodeClass.getName()) &&
51 _tcscmp(object->getClass()->getName(), g_nxslInterfaceClass.getName()) &&
52 _tcscmp(object->getClass()->getName(), g_nxslNetObjClass.getName()))
53 return NXSL_ERR_BAD_CLASS;
54
55 NetObj *netxmsObject = (NetObj *)object->getData();
56 value = netxmsObject->getCustomAttribute(argv[1]->getValueAsCString());
57 if (value != NULL)
58 {
59 *ppResult = new NXSL_Value(value);
60 }
61 else
62 {
63 *ppResult = new NXSL_Value; // Return NULL if attribute not found
64 }
65
66 return 0;
67 }
68
69 /**
70 * Set node's custom attribute
71 * First argument is a node object, second is an attribute name, third is new value
72 * Returns previous value
73 */
74 static int F_SetCustomAttribute(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
75 {
76 NXSL_Object *object;
77 const TCHAR *value;
78
79 if (!argv[0]->isObject())
80 return NXSL_ERR_NOT_OBJECT;
81
82 if (!argv[1]->isString() || !argv[2]->isString())
83 return NXSL_ERR_NOT_STRING;
84
85 object = argv[0]->getValueAsObject();
86 if (_tcscmp(object->getClass()->getName(), g_nxslNodeClass.getName()) &&
87 _tcscmp(object->getClass()->getName(), g_nxslInterfaceClass.getName()) &&
88 _tcscmp(object->getClass()->getName(), g_nxslNetObjClass.getName()))
89 return NXSL_ERR_BAD_CLASS;
90
91 NetObj *netxmsObject = (NetObj *)object->getData();
92 value = netxmsObject->getCustomAttribute(argv[1]->getValueAsCString());
93 if (value != NULL)
94 {
95 *ppResult = new NXSL_Value(value);
96 }
97 else
98 {
99 *ppResult = new NXSL_Value; // Return NULL if attribute not found
100 }
101
102 netxmsObject->setCustomAttribute(argv[1]->getValueAsCString(), argv[2]->getValueAsCString());
103
104 return 0;
105 }
106
107 /**
108 * Delete node's custom attribute
109 * First argument is a node object, second is an attribute name
110 */
111 static int F_DeleteCustomAttribute(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
112 {
113 NXSL_Object *object;
114 const TCHAR *value;
115
116 if (!argv[0]->isObject())
117 return NXSL_ERR_NOT_OBJECT;
118
119 if (!argv[1]->isString())
120 return NXSL_ERR_NOT_STRING;
121
122 object = argv[0]->getValueAsObject();
123 if (_tcscmp(object->getClass()->getName(), g_nxslNodeClass.getName()) &&
124 _tcscmp(object->getClass()->getName(), g_nxslInterfaceClass.getName()) &&
125 _tcscmp(object->getClass()->getName(), g_nxslNetObjClass.getName()))
126 return NXSL_ERR_BAD_CLASS;
127
128 NetObj *netxmsObject = (NetObj *)object->getData();
129 netxmsObject->deleteCustomAttribute(argv[1]->getValueAsCString());
130 *ppResult = new NXSL_Value;
131 return 0;
132 }
133
134 /**
135 * Get interface name by index
136 * Parameters: node object and interface index
137 */
138 static int F_GetInterfaceName(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
139 {
140 if (!argv[0]->isObject())
141 return NXSL_ERR_NOT_OBJECT;
142
143 if (!argv[1]->isInteger())
144 return NXSL_ERR_NOT_INTEGER;
145
146 NXSL_Object *object = argv[0]->getValueAsObject();
147 if (_tcscmp(object->getClass()->getName(), g_nxslNodeClass.getName()))
148 return NXSL_ERR_BAD_CLASS;
149
150 Node *node = (Node *)object->getData();
151 Interface *ifc = node->findInterface(argv[1]->getValueAsUInt32(), INADDR_ANY);
152 if (ifc != NULL)
153 {
154 *ppResult = new NXSL_Value(ifc->Name());
155 }
156 else
157 {
158 *ppResult = new NXSL_Value; // Return NULL if interface not found
159 }
160
161 return 0;
162 }
163
164 /**
165 * Get interface object by index
166 * Parameters: node object and interface index
167 */
168 static int F_GetInterfaceObject(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
169 {
170 if (!argv[0]->isObject())
171 return NXSL_ERR_NOT_OBJECT;
172
173 if (!argv[1]->isInteger())
174 return NXSL_ERR_NOT_INTEGER;
175
176 NXSL_Object *object = argv[0]->getValueAsObject();
177 if (_tcscmp(object->getClass()->getName(), g_nxslNodeClass.getName()))
178 return NXSL_ERR_BAD_CLASS;
179
180 Node *node = (Node *)object->getData();
181 Interface *ifc = node->findInterface(argv[1]->getValueAsUInt32(), INADDR_ANY);
182 if (ifc != NULL)
183 {
184 *ppResult = new NXSL_Value(new NXSL_Object(&g_nxslInterfaceClass, ifc));
185 }
186 else
187 {
188 *ppResult = new NXSL_Value; // Return NULL if interface not found
189 }
190
191 return 0;
192 }
193
194 /**
195 * Find node object
196 * First argument: current node object or null
197 * Second argument: node id or name
198 * Returns node object or null if requested node was not found or access to it was denied
199 */
200 static int F_FindNodeObject(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
201 {
202 Node *currNode = NULL, *node = NULL;
203
204 if (!argv[0]->isNull())
205 {
206 if (!argv[0]->isObject())
207 return NXSL_ERR_NOT_OBJECT;
208
209 NXSL_Object *object = argv[0]->getValueAsObject();
210 if (_tcscmp(object->getClass()->getName(), g_nxslNodeClass.getName()))
211 return NXSL_ERR_BAD_CLASS;
212
213 currNode = (Node *)object->getData();
214 }
215
216 if (!argv[1]->isString())
217 return NXSL_ERR_NOT_STRING;
218
219 if (argv[1]->isInteger())
220 {
221 NetObj *o = FindObjectById(argv[1]->getValueAsUInt32());
222 if ((o != NULL) && (o->Type() == OBJECT_NODE))
223 node = (Node *)o;
224 }
225 else
226 {
227 node = (Node *)FindObjectByName(argv[1]->getValueAsCString(), OBJECT_NODE);
228 }
229
230 if (node != NULL)
231 {
232 if (g_flags & AF_CHECK_TRUSTED_NODES)
233 {
234 if ((currNode != NULL) && (node->isTrustedNode(currNode->Id())))
235 {
236 *ppResult = new NXSL_Value(new NXSL_Object(&g_nxslNodeClass, node));
237 }
238 else
239 {
240 // No access, return null
241 *ppResult = new NXSL_Value;
242 DbgPrintf(4, _T("NXSL::FindNodeObject(%s [%d], '%s'): access denied for node %s [%d]"),
243 (currNode != NULL) ? currNode->Name() : _T("null"), (currNode != NULL) ? currNode->Id() : 0,
244 argv[1]->getValueAsCString(), node->Name(), node->Id());
245 }
246 }
247 else
248 {
249 *ppResult = new NXSL_Value(new NXSL_Object(&g_nxslNodeClass, node));
250 }
251 }
252 else
253 {
254 // Node not found, return null
255 *ppResult = new NXSL_Value;
256 }
257
258 return 0;
259 }
260
261 /**
262 * Find object
263 * First argument: object id or name
264 * Second argument (optional): current node object or null
265 * Returns generic object or null if requested object was not found or access to it was denied
266 */
267 static int F_FindObject(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
268 {
269 NetObj *object = NULL;
270
271 if ((argc !=1) && (argc != 2))
272 return NXSL_ERR_INVALID_ARGUMENT_COUNT;
273
274 if (!argv[0]->isString())
275 return NXSL_ERR_NOT_STRING;
276
277 if (argc == 2 && (!argv[1]->isNull() && !argv[1]->isObject()))
278 return NXSL_ERR_NOT_OBJECT;
279
280 if (argv[0]->isInteger())
281 {
282 object = FindObjectById(argv[0]->getValueAsUInt32());
283 }
284 else
285 {
286 object = FindObjectByName(argv[0]->getValueAsCString(), -1);
287 }
288
289 if (object != NULL)
290 {
291 if (g_flags & AF_CHECK_TRUSTED_NODES)
292 {
293 Node *currNode = NULL;
294 if ((argc == 2) && !argv[1]->isNull())
295 {
296 NXSL_Object *o = argv[1]->getValueAsObject();
297 if (_tcscmp(o->getClass()->getName(), g_nxslNodeClass.getName()))
298 return NXSL_ERR_BAD_CLASS;
299
300 currNode = (Node *)o->getData();
301 }
302 if ((currNode != NULL) && (object->isTrustedNode(currNode->Id())))
303 {
304 *ppResult = new NXSL_Value(new NXSL_Object((object->Type() == OBJECT_NODE) ? (NXSL_Class *)&g_nxslNodeClass : (NXSL_Class *)&g_nxslNetObjClass, object));
305 }
306 else
307 {
308 // No access, return null
309 *ppResult = new NXSL_Value;
310 DbgPrintf(4, _T("NXSL::FindObject('%s', %s [%d]): access denied for node %s [%d]"),
311 argv[0]->getValueAsCString(),
312 (currNode != NULL) ? currNode->Name() : _T("null"), (currNode != NULL) ? currNode->Id() : 0,
313 object->Name(), object->Id());
314 }
315 }
316 else
317 {
318 *ppResult = new NXSL_Value(new NXSL_Object((object->Type() == OBJECT_NODE) ? (NXSL_Class *)&g_nxslNodeClass : (NXSL_Class *)&g_nxslNetObjClass, object));
319 }
320 }
321 else
322 {
323 // Object not found, return null
324 *ppResult = new NXSL_Value;
325 }
326
327 return 0;
328 }
329
330 /**
331 * Get node object's parents
332 * First argument: node object
333 * Returns array of accessible parent objects
334 */
335 static int F_GetNodeParents(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
336 {
337 if (!argv[0]->isObject())
338 return NXSL_ERR_NOT_OBJECT;
339
340 NXSL_Object *object = argv[0]->getValueAsObject();
341 if (_tcscmp(object->getClass()->getName(), g_nxslNodeClass.getName()))
342 return NXSL_ERR_BAD_CLASS;
343
344 Node *node = (Node *)object->getData();
345 *ppResult = new NXSL_Value(node->getParentsForNXSL());
346 return 0;
347 }
348
349 /**
350 * Get object's parents
351 * First argument: NetXMS object (NetObj, Node, or Interface)
352 * Returns array of accessible parent objects
353 */
354 static int F_GetObjectParents(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
355 {
356 if (!argv[0]->isObject())
357 return NXSL_ERR_NOT_OBJECT;
358
359 NXSL_Object *object = argv[0]->getValueAsObject();
360 if (_tcscmp(object->getClass()->getName(), g_nxslNodeClass.getName()) &&
361 _tcscmp(object->getClass()->getName(), g_nxslInterfaceClass.getName()) &&
362 _tcscmp(object->getClass()->getName(), g_nxslNetObjClass.getName()))
363 return NXSL_ERR_BAD_CLASS;
364
365 NetObj *netobj = (NetObj *)object->getData();
366 *ppResult = new NXSL_Value(netobj->getParentsForNXSL());
367 return 0;
368 }
369
370 /**
371 * Get object's children
372 * First argument: NetXMS object (NetObj, Node, or Interface)
373 * Returns array of accessible child objects
374 */
375 static int F_GetObjectChildren(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
376 {
377 if (!argv[0]->isObject())
378 return NXSL_ERR_NOT_OBJECT;
379
380 NXSL_Object *object = argv[0]->getValueAsObject();
381 if (_tcscmp(object->getClass()->getName(), g_nxslNodeClass.getName()) &&
382 _tcscmp(object->getClass()->getName(), g_nxslInterfaceClass.getName()) &&
383 _tcscmp(object->getClass()->getName(), g_nxslNetObjClass.getName()))
384 return NXSL_ERR_BAD_CLASS;
385
386 NetObj *netobj = (NetObj *)object->getData();
387 *ppResult = new NXSL_Value(netobj->getChildrenForNXSL());
388 return 0;
389 }
390
391 /**
392 * Get node's interfaces
393 * First argument: node object
394 * Returns array of interface objects
395 */
396 static int F_GetNodeInterfaces(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
397 {
398 if (!argv[0]->isObject())
399 return NXSL_ERR_NOT_OBJECT;
400
401 NXSL_Object *object = argv[0]->getValueAsObject();
402 if (_tcscmp(object->getClass()->getName(), g_nxslNodeClass.getName()))
403 return NXSL_ERR_BAD_CLASS;
404
405 Node *node = (Node *)object->getData();
406 *ppResult = new NXSL_Value(node->getInterfacesForNXSL());
407 return 0;
408 }
409
410 /**
411 * Get event's named parameter
412 * First argument: event object
413 * Second argument: parameter's name
414 * Returns parameter's value or null
415 */
416 static int F_GetEventParameter(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
417 {
418 if (!argv[0]->isObject())
419 return NXSL_ERR_NOT_OBJECT;
420
421 NXSL_Object *object = argv[0]->getValueAsObject();
422 if (_tcscmp(object->getClass()->getName(), g_nxslEventClass.getName()))
423 return NXSL_ERR_BAD_CLASS;
424
425 if (!argv[1]->isString())
426 return NXSL_ERR_NOT_STRING;
427
428 Event *e = (Event *)object->getData();
429 const TCHAR *value = e->getNamedParameter(argv[1]->getValueAsCString());
430 *ppResult = (value != NULL) ? new NXSL_Value(value) : new NXSL_Value;
431 return 0;
432 }
433
434 /**
435 * Set event's named parameter
436 * First argument: event object
437 * Second argument: parameter's name
438 * Third argument: new value
439 */
440 static int F_SetEventParameter(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
441 {
442 if (!argv[0]->isObject())
443 return NXSL_ERR_NOT_OBJECT;
444
445 NXSL_Object *object = argv[0]->getValueAsObject();
446 if (_tcscmp(object->getClass()->getName(), g_nxslEventClass.getName()))
447 return NXSL_ERR_BAD_CLASS;
448
449 if (!argv[1]->isString() || !argv[2]->isString())
450 return NXSL_ERR_NOT_STRING;
451
452 Event *e = (Event *)object->getData();
453 e->setNamedParameter(argv[1]->getValueAsCString(), argv[2]->getValueAsCString());
454 *ppResult = new NXSL_Value;
455 return 0;
456 }
457
458 /**
459 * Post event
460 * Syntax:
461 * PostEvent(node, event, tag, ...)
462 * where:
463 * node - node object to send event on behalf of
464 * event - event code
465 * tag - user tag (optional)
466 * ... - optional parameters, will be passed as %1, %2, etc.
467 */
468 static int F_PostEvent(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
469 {
470 if (argc < 2)
471 return NXSL_ERR_INVALID_ARGUMENT_COUNT;
472
473 // Validate first argument
474 if (!argv[0]->isObject())
475 return NXSL_ERR_NOT_OBJECT;
476
477 NXSL_Object *object = argv[0]->getValueAsObject();
478 if (_tcscmp(object->getClass()->getName(), g_nxslNodeClass.getName()))
479 return NXSL_ERR_BAD_CLASS;
480
481 Node *node = (Node *)object->getData();
482
483 // Event code
484 if (!argv[1]->isString())
485 return NXSL_ERR_NOT_STRING;
486
487 UINT32 eventCode = 0;
488 if (argv[1]->isInteger())
489 {
490 eventCode = argv[1]->getValueAsUInt32();
491 }
492 else
493 {
494 eventCode = EventCodeFromName(argv[1]->getValueAsCString(), 0);
495 }
496
497 BOOL success;
498 if (eventCode > 0)
499 {
500 // User tag
501 const TCHAR *userTag = NULL;
502 if ((argc > 2) && !argv[2]->isNull())
503 {
504 if (!argv[2]->isString())
505 return NXSL_ERR_NOT_STRING;
506 userTag = argv[2]->getValueAsCString();
507 }
508
509 // Post event
510 char format[] = "ssssssssssssssssssssssssssssssss";
511 const TCHAR *plist[32];
512 int eargc = 0;
513 for(int i = 3; (i < argc) && (eargc < 32); i++)
514 plist[eargc++] = argv[i]->getValueAsCString();
515 format[eargc] = 0;
516 success = PostEventWithTag(eventCode, node->Id(), userTag, format,
517 plist[0], plist[1], plist[2], plist[3],
518 plist[4], plist[5], plist[6], plist[7],
519 plist[8], plist[9], plist[10], plist[11],
520 plist[12], plist[13], plist[14], plist[15],
521 plist[16], plist[17], plist[18], plist[19],
522 plist[20], plist[21], plist[22], plist[23],
523 plist[24], plist[25], plist[26], plist[27],
524 plist[28], plist[29], plist[30], plist[31]);
525 }
526 else
527 {
528 success = FALSE;
529 }
530
531 *ppResult = new NXSL_Value((LONG)success);
532 return 0;
533 }
534
535 /**
536 * Create node object
537 * Syntax:
538 * CreateNode(parent, name, primaryHostName)
539 * where:
540 * parent - parent object
541 * name - name for new node
542 * primaryHostName - primary host name for new node
543 * Return value:
544 * new node object or null on failure
545 */
546 static int F_CreateNode(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
547 {
548 if (!argv[0]->isObject())
549 return NXSL_ERR_NOT_OBJECT;
550
551 NXSL_Object *obj = argv[0]->getValueAsObject();
552 if (_tcscmp(obj->getClass()->getName(), g_nxslNetObjClass.getName()))
553 return NXSL_ERR_BAD_CLASS;
554
555 NetObj *parent = (NetObj*)obj->getData();
556 if (parent->Type() != OBJECT_CONTAINER && parent->Type() != OBJECT_SERVICEROOT)
557 return NXSL_ERR_BAD_CLASS;
558
559 if (!argv[1]->isString() || !argv[2]->isString())
560 return NXSL_ERR_NOT_STRING;
561
562 const TCHAR *pname = argv[2]->getValueAsCString();
563 if (*pname == 0)
564 pname = argv[1]->getValueAsCString();
565 Node *node = PollNewNode(ntohl(ResolveHostName(pname)), 0, 0, 0, 0, argv[1]->getValueAsCString(), 0, 0, NULL, 0, true, false);
566 if (node != NULL)
567 {
568 node->setPrimaryName(pname);
569 parent->AddChild(node);
570 node->AddParent(parent);
571 node->unhide();
572 *ppResult = new NXSL_Value(new NXSL_Object(&g_nxslNodeClass, node));
573 }
574 else
575 {
576 *ppResult = new NXSL_Value;
577 }
578 return 0;
579 }
580
581 /**
582 * Create container object
583 * Syntax:
584 * CreateContainer(parent, name)
585 * where:
586 * parent - parent object
587 * name - name for new container
588 * Return value:
589 * new container object
590 */
591 static int F_CreateContainer(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
592 {
593 if (!argv[0]->isObject())
594 return NXSL_ERR_NOT_OBJECT;
595
596 NXSL_Object *obj = argv[0]->getValueAsObject();
597 if (_tcscmp(obj->getClass()->getName(), g_nxslNetObjClass.getName()))
598 return NXSL_ERR_BAD_CLASS;
599
600 NetObj *parent = (NetObj*)obj->getData();
601 if (parent->Type() != OBJECT_CONTAINER && parent->Type() != OBJECT_SERVICEROOT)
602 return NXSL_ERR_BAD_CLASS;
603
604 if (!argv[1]->isString())
605 return NXSL_ERR_NOT_STRING;
606
607 const TCHAR *name = argv[1]->getValueAsCString();
608
609 Container *container = new Container(name, 0);
610 NetObjInsert(container, TRUE);
611 parent->AddChild(container);
612 container->AddParent(parent);
613 container->unhide();
614
615 *ppResult = new NXSL_Value(new NXSL_Object(&g_nxslNetObjClass, container));
616
617 return 0;
618 }
619
620 /**
621 * Delete object
622 * Syntax:
623 * DeleteObject(object)
624 * where:
625 * object - object to remove, must be of class NetObj, Interface, or Node
626 * Return value:
627 * null
628 */
629 static int F_DeleteObject(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
630 {
631 if (!argv[0]->isObject())
632 return NXSL_ERR_NOT_OBJECT;
633
634 NXSL_Object *obj = argv[0]->getValueAsObject();
635 if (_tcscmp(obj->getClass()->getName(), g_nxslNetObjClass.getName()) &&
636 _tcscmp(obj->getClass()->getName(), g_nxslInterfaceClass.getName()) &&
637 _tcscmp(obj->getClass()->getName(), g_nxslNodeClass.getName()))
638 return NXSL_ERR_BAD_CLASS;
639
640 NetObj *netobj = (NetObj*)obj->getData();
641 netobj->deleteObject();
642
643 *ppResult = new NXSL_Value;
644 return 0;
645 }
646
647 /**
648 * Bind object to container
649 * Syntax:
650 * BindObject(parent, child)
651 * where:
652 * parent - container object
653 * child - either node or container or subnet to be bound to parent
654 * Return value:
655 * null
656 */
657 static int F_BindObject(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
658 {
659 if (!argv[0]->isObject() || !argv[1]->isObject())
660 return NXSL_ERR_NOT_OBJECT;
661
662 NXSL_Object *obj = argv[0]->getValueAsObject();
663 if (_tcscmp(obj->getClass()->getName(), g_nxslNetObjClass.getName()))
664 return NXSL_ERR_BAD_CLASS;
665
666 NetObj *netobj = (NetObj*)obj->getData();
667 if (netobj->Type() != OBJECT_CONTAINER)
668 return NXSL_ERR_BAD_CLASS;
669
670 NXSL_Object *obj2 = argv[1]->getValueAsObject();
671 if (_tcscmp(obj2->getClass()->getName(), g_nxslNetObjClass.getName()) &&
672 _tcscmp(obj2->getClass()->getName(), g_nxslNodeClass.getName()))
673 return NXSL_ERR_BAD_CLASS;
674
675 NetObj *child = (NetObj*)obj2->getData();
676 if (child->Type() != OBJECT_CONTAINER && child->Type() != OBJECT_SUBNET && child->Type() != OBJECT_NODE)
677 return NXSL_ERR_BAD_CLASS;
678
679 if (child->isChild(netobj->Id())) // prevent loops
680 return NXSL_ERR_INVALID_OBJECT_OPERATION;
681
682 netobj->AddChild(child);
683 child->AddParent(netobj);
684 netobj->calculateCompoundStatus();
685
686 *ppResult = new NXSL_Value;
687
688 return 0;
689 }
690
691 /**
692 * Remove (unbind) object from container
693 * Syntax:
694 * UnbindObject(parent, child)
695 * where:
696 * parent - container object
697 * child - either node or container or subnet to be removed from container
698 * Return value:
699 * null
700 */
701 static int F_UnbindObject(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
702 {
703 if (!argv[0]->isObject() || !argv[1]->isObject())
704 return NXSL_ERR_NOT_OBJECT;
705
706 NXSL_Object *obj = argv[0]->getValueAsObject();
707 if (_tcscmp(obj->getClass()->getName(), g_nxslNetObjClass.getName()))
708 return NXSL_ERR_BAD_CLASS;
709
710 NetObj *netobj = (NetObj*)obj->getData();
711 if (netobj->Type() != OBJECT_CONTAINER)
712 return NXSL_ERR_BAD_CLASS;
713
714 NXSL_Object *obj2 = argv[1]->getValueAsObject();
715 if (_tcscmp(obj2->getClass()->getName(), g_nxslNetObjClass.getName()) &&
716 _tcscmp(obj2->getClass()->getName(), g_nxslNodeClass.getName()))
717 return NXSL_ERR_BAD_CLASS;
718
719 NetObj *child = (NetObj*)obj2->getData();
720 if (child->Type() != OBJECT_CONTAINER && child->Type() != OBJECT_SUBNET && child->Type() != OBJECT_NODE)
721 return NXSL_ERR_BAD_CLASS;
722
723 netobj->DeleteChild(child);
724 child->DeleteParent(netobj);
725
726 *ppResult = new NXSL_Value;
727
728 return 0;
729 }
730
731 /**
732 * Rename object
733 * Syntax:
734 * RenameObject(object, name)
735 * where:
736 * object - NetXMS object (Node, Interface, or NetObj)
737 * name - new name for object
738 * Return value:
739 * null
740 */
741 static int F_RenameObject(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
742 {
743 if (!argv[0]->isObject())
744 return NXSL_ERR_NOT_OBJECT;
745
746 if (!argv[1]->isString())
747 return NXSL_ERR_NOT_STRING;
748
749 NXSL_Object *object = argv[0]->getValueAsObject();
750 if (_tcscmp(object->getClass()->getName(), g_nxslNetObjClass.getName()) &&
751 _tcscmp(object->getClass()->getName(), g_nxslNodeClass.getName()) &&
752 _tcscmp(object->getClass()->getName(), g_nxslInterfaceClass.getName()))
753 return NXSL_ERR_BAD_CLASS;
754
755 ((NetObj *)object->getData())->setName(argv[1]->getValueAsCString());
756
757 *ppResult = new NXSL_Value;
758 return 0;
759 }
760
761 /**
762 * Manage object (set to managed state)
763 * Syntax:
764 * ManageObject(object)
765 * where:
766 * object - NetXMS object (Node, Interface, or NetObj)
767 * Return value:
768 * null
769 */
770 static int F_ManageObject(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
771 {
772 if (!argv[0]->isObject())
773 return NXSL_ERR_NOT_OBJECT;
774
775 NXSL_Object *object = argv[0]->getValueAsObject();
776 if (_tcscmp(object->getClass()->getName(), g_nxslNetObjClass.getName()) &&
777 _tcscmp(object->getClass()->getName(), g_nxslNodeClass.getName()) &&
778 _tcscmp(object->getClass()->getName(), g_nxslInterfaceClass.getName()))
779 return NXSL_ERR_BAD_CLASS;
780
781 ((NetObj *)object->getData())->setMgmtStatus(TRUE);
782
783 *ppResult = new NXSL_Value;
784 return 0;
785 }
786
787 /**
788 * Unmanage object (set to unmanaged state)
789 * Syntax:
790 * UnmanageObject(object)
791 * where:
792 * object - NetXMS object (Node, Interface, or NetObj)
793 * Return value:
794 * null
795 */
796 static int F_UnmanageObject(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
797 {
798 if (!argv[0]->isObject())
799 return NXSL_ERR_NOT_OBJECT;
800
801 NXSL_Object *object = argv[0]->getValueAsObject();
802 if (_tcscmp(object->getClass()->getName(), g_nxslNetObjClass.getName()) &&
803 _tcscmp(object->getClass()->getName(), g_nxslNodeClass.getName()) &&
804 _tcscmp(object->getClass()->getName(), g_nxslInterfaceClass.getName()))
805 return NXSL_ERR_BAD_CLASS;
806
807 ((NetObj *)object->getData())->setMgmtStatus(FALSE);
808
809 *ppResult = new NXSL_Value;
810 return 0;
811 }
812
813 /**
814 * Set interface expected state
815 * Syntax:
816 * SetInterfaceExpectedState(interface, state)
817 * where:
818 * interface - Interface object
819 * state - state ID or name. Possible values: 0 "UP", 1 "DOWN", 2 "IGNORE"
820 * Return value:
821 * null
822 */
823 static int F_SetInterfaceExpectedState(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
824 {
825 if (!argv[0]->isObject())
826 return NXSL_ERR_NOT_OBJECT;
827
828 NXSL_Object *object = argv[0]->getValueAsObject();
829 if (_tcscmp(object->getClass()->getName(), g_nxslInterfaceClass.getName()))
830 return NXSL_ERR_BAD_CLASS;
831
832 int state;
833 if (argv[1]->isInteger())
834 {
835 state = argv[1]->getValueAsInt32();
836 }
837 else if (argv[1]->isString())
838 {
839 static const TCHAR *stateNames[] = { _T("UP"), _T("DOWN"), _T("IGNORE"), NULL };
840 const TCHAR *name = argv[1]->getValueAsCString();
841 for(state = 0; stateNames[state] != NULL; state++)
842 if (!_tcsicmp(stateNames[state], name))
843 break;
844 }
845 else
846 {
847 return NXSL_ERR_NOT_STRING;
848 }
849
850 if ((state >= 0) && (state <= 2))
851 ((Interface *)object->getData())->setExpectedState(state);
852
853 *ppResult = new NXSL_Value;
854 return 0;
855 }
856
857 /**
858 * Create new SNMP transport object
859 * Syntax:
860 * CreateSNMPTransport(node)
861 * where:
862 * node - node to create SNMP transport for
863 * Return value:
864 * new SNMP_Transport object
865 */
866 static int F_CreateSNMPTransport(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
867 {
868 if (!argv[0]->isObject())
869 return NXSL_ERR_NOT_OBJECT;
870
871 NXSL_Object *obj = argv[0]->getValueAsObject();
872 if (_tcscmp(obj->getClass()->getName(), g_nxslNodeClass.getName()))
873 return NXSL_ERR_BAD_CLASS;
874
875 Node *node = (Node*)obj->getData();
876 if (node != NULL)
877 {
878 SNMP_Transport *t = node->createSnmpTransport();
879 *ppResult = (t != NULL) ? new NXSL_Value(new NXSL_Object(&g_nxslSnmpTransportClass, t)) : new NXSL_Value;
880 }
881 else
882 {
883 *ppResult = new NXSL_Value;
884 }
885
886 return 0;
887 }
888
889 /**
890 * Do SNMP GET for the given object id
891 * Syntax:
892 * SNMPGet(transport, oid)
893 * where:
894 * transport - NXSL transport object
895 * oid - SNMP object id
896 * Return value:
897 * new SNMP_VarBind object
898 */
899 static int F_SNMPGet(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
900 {
901 UINT32 len;
902 static UINT32 requestId = 1;
903 UINT32 varName[MAX_OID_LEN], result = SNMP_ERR_SUCCESS;
904
905 if (!argv[0]->isObject())
906 return NXSL_ERR_NOT_OBJECT;
907 if (!argv[1]->isString())
908 return NXSL_ERR_NOT_STRING;
909
910 NXSL_Object *obj = argv[0]->getValueAsObject();
911 if (_tcscmp(obj->getClass()->getName(), g_nxslSnmpTransportClass.getName()))
912 return NXSL_ERR_BAD_CLASS;
913
914 SNMP_Transport *trans = (SNMP_Transport*)obj->getData();
915
916 // Create PDU and send request
917 size_t nameLen = SNMPParseOID(argv[1]->getValueAsString(&len), varName, MAX_OID_LEN);
918 if (nameLen == 0)
919 return NXSL_ERR_BAD_CONDITION;
920
921 SNMP_PDU *pdu = new SNMP_PDU(SNMP_GET_REQUEST, requestId++, trans->getSnmpVersion());
922 pdu->bindVariable(new SNMP_Variable(varName, nameLen));
923
924 SNMP_PDU *rspPDU;
925 result = trans->doRequest(pdu, &rspPDU, g_dwSNMPTimeout, 3 /* num retries */);
926 if (result == SNMP_ERR_SUCCESS)
927 {
928 if ((rspPDU->getNumVariables() > 0) && (rspPDU->getErrorCode() == SNMP_PDU_ERR_SUCCESS))
929 {
930 SNMP_Variable *pVar = rspPDU->getVariable(0);
931 *ppResult = new NXSL_Value(new NXSL_Object(&g_nxslSnmpVarBindClass, pVar));
932 rspPDU->unlinkVariables();
933 }
934 else
935 {
936 *ppResult = new NXSL_Value;
937 }
938 delete rspPDU;
939 }
940 else
941 {
942 *ppResult = new NXSL_Value;
943 }
944 return 0;
945 }
946
947 /**
948 * Do SNMP GET for the given object id
949 * Syntax:
950 * SNMPGetValue(transport, oid)
951 * where:
952 * transport - NXSL transport object
953 * oid - SNMP object id
954 * Return value:
955 * value for the given oid
956 */
957 static int F_SNMPGetValue(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
958 {
959 TCHAR buffer[4096];
960 UINT32 len;
961
962 if (!argv[0]->isObject())
963 return NXSL_ERR_NOT_OBJECT;
964 if (!argv[1]->isString())
965 return NXSL_ERR_NOT_STRING;
966
967 NXSL_Object *obj = argv[0]->getValueAsObject();
968 if (_tcscmp(obj->getClass()->getName(), g_nxslSnmpTransportClass.getName()))
969 return NXSL_ERR_BAD_CLASS;
970
971 SNMP_Transport *trans = (SNMP_Transport*)obj->getData();
972
973 if (SnmpGetEx(trans, argv[1]->getValueAsString(&len), NULL, 0, buffer, sizeof(buffer), SG_STRING_RESULT, NULL) == SNMP_ERR_SUCCESS)
974 {
975 *ppResult = new NXSL_Value(buffer);
976 }
977 else
978 {
979 *ppResult = new NXSL_Value;
980 }
981
982 return 0;
983 }
984
985 /**
986 * Do SNMP SET for the given object id
987 * Syntax:
988 * SNMPSet(transport, oid, value, [data_type])
989 * where:
990 * transport - NXSL transport object
991 * oid - SNMP object id
992 * value - value to set
993 * data_type (optional)
994 * Return value:
995 * value for the given oid
996 */
997 static int F_SNMPSet(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
998 {
999 SNMP_PDU *request = NULL, *response;
1000 UINT32 len;
1001 LONG ret = FALSE;
1002
1003 if (argc < 3 || argc > 4)
1004 return NXSL_ERR_INVALID_ARGUMENT_COUNT;
1005 if (!argv[0]->isObject())
1006 return NXSL_ERR_NOT_OBJECT;
1007 if (!argv[1]->isString() || !argv[2]->isString() || (argc == 4 && !argv[3]->isString()))
1008 return NXSL_ERR_NOT_STRING;
1009
1010 NXSL_Object *obj = argv[0]->getValueAsObject();
1011 if (_tcscmp(obj->getClass()->getName(), g_nxslSnmpTransportClass.getName()))
1012 return NXSL_ERR_BAD_CLASS;
1013
1014 SNMP_Transport *trans = (SNMP_Transport*)obj->getData();
1015
1016 // Create request
1017 request = new SNMP_PDU(SNMP_SET_REQUEST, getpid(), trans->getSnmpVersion());
1018
1019 if (SNMPIsCorrectOID(argv[1]->getValueAsString(&len)))
1020 {
1021 SNMP_Variable *var = new SNMP_Variable(argv[1]->getValueAsString(&len));
1022 if (argc == 3)
1023 {
1024 var->setValueFromString(ASN_OCTET_STRING, argv[2]->getValueAsString(&len));
1025 }
1026 else
1027 {
1028 UINT32 dataType = SNMPResolveDataType(argv[3]->getValueAsString(&len));
1029 if (dataType == ASN_NULL)
1030 {
1031 DbgPrintf(6, _T("SNMPSet: failed to resolve data type '%s', assume string"),
1032 argv[3]->getValueAsString(&len));
1033 dataType = ASN_OCTET_STRING;
1034 }
1035 var->setValueFromString(dataType, argv[2]->getValueAsString(&len));
1036 }
1037 request->bindVariable(var);
1038 }
1039 else
1040 {
1041 DbgPrintf(6, _T("SNMPSet: Invalid OID: %s"), argv[1]->getValueAsString(&len));
1042 goto finish;
1043 }
1044
1045 // Send request and process response
1046 UINT32 snmpResult;
1047 if ((snmpResult = trans->doRequest(request, &response, g_dwSNMPTimeout, 3)) == SNMP_ERR_SUCCESS)
1048 {
1049 if (response->getErrorCode() != 0)
1050 {
1051 DbgPrintf(6, _T("SNMPSet: operation failed (error code %d)"), response->getErrorCode());
1052 goto finish;
1053 }
1054 else
1055 {
1056 DbgPrintf(6, _T("SNMPSet: success"));
1057 ret = TRUE;
1058 }
1059 delete response;
1060 }
1061 else
1062 {
1063 DbgPrintf(6, _T("SNMPSet: %s"), SNMPGetErrorText(snmpResult));
1064 }
1065
1066 finish:
1067 delete request;
1068 *ppResult = new NXSL_Value(ret);
1069 return 0;
1070 }
1071
1072 /**
1073 * Do SNMP walk starting from the given oid
1074 * Syntax:
1075 * SNMPWalk(transport, oid)
1076 * where:
1077 * transport - NXSL transport object
1078 * oid - SNMP object id
1079 * Return value:
1080 * an array of VarBind objects
1081 */
1082 static int F_SNMPWalk(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
1083 {
1084 static UINT32 requestId = 1;
1085 UINT32 rootName[MAX_OID_LEN], name[MAX_OID_LEN], result;
1086 size_t rootNameLen, nameLen;
1087 SNMP_PDU *rqPDU, *rspPDU;
1088 BOOL isRunning = TRUE;
1089 int i = 0;
1090
1091 if (!argv[0]->isObject())
1092 return NXSL_ERR_NOT_OBJECT;
1093 if (!argv[1]->isString())
1094 return NXSL_ERR_NOT_STRING;
1095
1096 NXSL_Object *obj = argv[0]->getValueAsObject();
1097 if (_tcscmp(obj->getClass()->getName(), g_nxslSnmpTransportClass.getName()))
1098 return NXSL_ERR_BAD_CLASS;
1099
1100 SNMP_Transport *trans = (SNMP_Transport*)obj->getData();
1101
1102 // Get root
1103 rootNameLen = SNMPParseOID(argv[1]->getValueAsCString(), rootName, MAX_OID_LEN);
1104 if (rootNameLen == 0)
1105 return SNMP_ERR_BAD_OID;
1106
1107 memcpy(name, rootName, rootNameLen * sizeof(UINT32));
1108 nameLen = rootNameLen;
1109
1110 NXSL_Array *varList = new NXSL_Array;
1111
1112 // Walk the MIB
1113 while(isRunning)
1114 {
1115 rqPDU = new SNMP_PDU(SNMP_GET_NEXT_REQUEST, requestId++, trans->getSnmpVersion());
1116 rqPDU->bindVariable(new SNMP_Variable(name, nameLen));
1117 result = trans->doRequest(rqPDU, &rspPDU, g_dwSNMPTimeout, 3);
1118
1119 // Analyze response
1120 if (result == SNMP_ERR_SUCCESS)
1121 {
1122 if ((rspPDU->getNumVariables() > 0) &&
1123 (rspPDU->getErrorCode() == SNMP_PDU_ERR_SUCCESS))
1124 {
1125 SNMP_Variable *var = rspPDU->getVariable(0);
1126 if ((var->getType() != ASN_NO_SUCH_OBJECT) &&
1127 (var->getType() != ASN_NO_SUCH_INSTANCE))
1128 {
1129 // Do we have to stop walking?
1130 if ((var->getName()->getLength() < rootNameLen) ||
1131 (memcmp(rootName, var->getName()->getValue(), rootNameLen * sizeof(UINT32))) ||
1132 ((var->getName()->getLength() == nameLen) &&
1133 (!memcmp(var->getName()->getValue(), name, var->getName()->getLength() * sizeof(UINT32)))))
1134 {
1135 isRunning = FALSE;
1136 delete rspPDU;
1137 delete rqPDU;
1138 break;
1139 }
1140 memcpy(name, var->getName()->getValue(), var->getName()->getLength() * sizeof(UINT32));
1141 nameLen = var->getName()->getLength();
1142 varList->set(i++, new NXSL_Value(new NXSL_Object(&g_nxslSnmpVarBindClass, var)));
1143 rspPDU->unlinkVariables();
1144 }
1145 else
1146 {
1147 result = SNMP_ERR_NO_OBJECT;
1148 isRunning = FALSE;
1149 }
1150 }
1151 else
1152 {
1153 if (rspPDU->getErrorCode() == SNMP_PDU_ERR_NO_SUCH_NAME)
1154 result = SNMP_ERR_NO_OBJECT;
1155 else
1156 result = SNMP_ERR_AGENT;
1157 isRunning = FALSE;
1158 }
1159 delete rspPDU;
1160 }
1161 else
1162 {
1163 isRunning = FALSE;
1164 }
1165 delete rqPDU;
1166 }
1167
1168 if (result != SNMP_ERR_SUCCESS)
1169 {
1170 DbgPrintf(9, _T("SNMPWalk returned %d"), result);
1171 *ppResult = new NXSL_Value;
1172 delete varList;
1173 }
1174 else
1175 {
1176 *ppResult = new NXSL_Value(varList);
1177 }
1178 return 0;
1179 }
1180
1181 /**
1182 * Read parameter's value from agent
1183 * Syntax:
1184 * AgentReadParameter(object, name)
1185 * where:
1186 * object - NetXMS node object
1187 * name - name of the parameter
1188 * Return value:
1189 * paramater's value on success and null on failure
1190 */
1191 static int F_AgentReadParameter(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
1192 {
1193 if (!argv[0]->isObject())
1194 return NXSL_ERR_NOT_OBJECT;
1195
1196 if (!argv[1]->isString())
1197 return NXSL_ERR_NOT_STRING;
1198
1199 NXSL_Object *object = argv[0]->getValueAsObject();
1200 if (_tcscmp(object->getClass()->getName(), g_nxslNodeClass.getName()))
1201 return NXSL_ERR_BAD_CLASS;
1202
1203 TCHAR buffer[MAX_RESULT_LENGTH];
1204 UINT32 rcc = ((Node *)object->getData())->getItemFromAgent(argv[1]->getValueAsCString(), MAX_RESULT_LENGTH, buffer);
1205 if (rcc == DCE_SUCCESS)
1206 *ppResult = new NXSL_Value(buffer);
1207 else
1208 *ppResult = new NXSL_Value;
1209 return 0;
1210 }
1211
1212 /**
1213 * Read table value from agent
1214 * Syntax:
1215 * AgentReadTable(object, name)
1216 * where:
1217 * object - NetXMS node object
1218 * name - name of the table
1219 * Return value:
1220 * table value on success and null on failure
1221 */
1222 static int F_AgentReadTable(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
1223 {
1224 if (!argv[0]->isObject())
1225 return NXSL_ERR_NOT_OBJECT;
1226
1227 if (!argv[1]->isString())
1228 return NXSL_ERR_NOT_STRING;
1229
1230 NXSL_Object *object = argv[0]->getValueAsObject();
1231 if (_tcscmp(object->getClass()->getName(), g_nxslNodeClass.getName()))
1232 return NXSL_ERR_BAD_CLASS;
1233
1234 Table *table;
1235 UINT32 rcc = ((Node *)object->getData())->getTableFromAgent(argv[1]->getValueAsCString(), &table);
1236 if (rcc == DCE_SUCCESS)
1237 *ppResult = new NXSL_Value(new NXSL_Object(&g_nxslTableClass, table));
1238 else
1239 *ppResult = new NXSL_Value;
1240 return 0;
1241 }
1242
1243 /**
1244 * Get server's configuration variable
1245 * First argument is a variable name
1246 * Optional second argumet is default value
1247 * Returns variable's value if found, default value if not found, and null if not found and no default value given
1248 */
1249 static int F_GetConfigurationVariable(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL_VM *vm)
1250 {
1251 if ((argc == 0) || (argc > 2))
1252 return NXSL_ERR_INVALID_ARGUMENT_COUNT;
1253
1254 if (!argv[0]->isString())
1255 return NXSL_ERR_NOT_STRING;
1256
1257 TCHAR buffer[MAX_DB_STRING];
1258 if (ConfigReadStr(argv[0]->getValueAsCString(), buffer, MAX_DB_STRING, _T("")))
1259 {
1260 *ppResult = new NXSL_Value(buffer);
1261 }
1262 else
1263 {
1264 *ppResult = (argc == 2) ? new NXSL_Value(argv[1]) : new NXSL_Value;
1265 }
1266
1267 return 0;
1268 }
1269
1270 /**
1271 * Additional server functions to use within all scripts
1272 */
1273 static NXSL_ExtFunction m_nxslServerFunctions[] =
1274 {
1275 { _T("map"), F_map, -1 },
1276 { _T("AgentReadParameter"), F_AgentReadParameter, 2 },
1277 { _T("AgentReadTable"), F_AgentReadTable, 2 },
1278 { _T("CreateSNMPTransport"), F_CreateSNMPTransport, 1 },
1279 { _T("DeleteCustomAttribute"), F_DeleteCustomAttribute, 2 },
1280 { _T("GetConfigurationVariable"), F_GetConfigurationVariable, -1 },
1281 { _T("GetCustomAttribute"), F_GetCustomAttribute, 2 },
1282 { _T("GetEventParameter"), F_GetEventParameter, 2 },
1283 { _T("GetInterfaceName"), F_GetInterfaceName, 2 },
1284 { _T("GetInterfaceObject"), F_GetInterfaceObject, 2 },
1285 { _T("GetNodeInterfaces"), F_GetNodeInterfaces, 1 },
1286 { _T("GetNodeParents"), F_GetNodeParents, 1 },
1287 { _T("GetObjectChildren"), F_GetObjectChildren, 1 },
1288 { _T("GetObjectParents"), F_GetObjectParents, 1 },
1289 { _T("FindNodeObject"), F_FindNodeObject, 2 },
1290 { _T("FindObject"), F_FindObject, -1 },
1291 { _T("ManageObject"), F_ManageObject, 1 },
1292 { _T("PostEvent"), F_PostEvent, -1 },
1293 { _T("RenameObject"), F_RenameObject, 2 },
1294 { _T("SetCustomAttribute"), F_SetCustomAttribute, 3 },
1295 { _T("SetEventParameter"), F_SetEventParameter, 3 },
1296 { _T("SetInterfaceExpectedState"), F_SetInterfaceExpectedState, 2 },
1297 { _T("SNMPGet"), F_SNMPGet, 2 },
1298 { _T("SNMPGetValue"), F_SNMPGetValue, 2 },
1299 { _T("SNMPSet"), F_SNMPSet, -1 /* 3 or 4 */ },
1300 { _T("SNMPWalk"), F_SNMPWalk, 2 },
1301 { _T("UnmanageObject"), F_UnmanageObject, 1 }
1302 };
1303
1304 /**
1305 * Additional server functions to manage objects (disabled by default)
1306 */
1307 static NXSL_ExtFunction m_nxslServerFunctionsForContainers[] =
1308 {
1309 { _T("BindObject"), F_BindObject, 2 },
1310 { _T("CreateContainer"), F_CreateContainer, 2 },
1311 { _T("CreateNode"), F_CreateNode, 3 },
1312 { _T("DeleteObject"), F_DeleteObject, 1 },
1313 { _T("UnbindObject"), F_UnbindObject, 2 }
1314 };
1315
1316 /**
1317 * Constructor for server default script environment
1318 */
1319 NXSL_ServerEnv::NXSL_ServerEnv() : NXSL_Environment()
1320 {
1321 m_console = NULL;
1322 setLibrary(g_pScriptLibrary);
1323 registerFunctionSet(sizeof(m_nxslServerFunctions) / sizeof(NXSL_ExtFunction), m_nxslServerFunctions);
1324 RegisterDCIFunctions(this);
1325 registerFunctionSet(g_nxslNumSituationFunctions, g_nxslSituationFunctions);
1326 if (g_flags & AF_ENABLE_NXSL_CONTAINER_FUNCS)
1327 registerFunctionSet(sizeof(m_nxslServerFunctionsForContainers) / sizeof(NXSL_ExtFunction), m_nxslServerFunctionsForContainers);
1328 }
1329
1330 /**
1331 * Script trace output
1332 */
1333 void NXSL_ServerEnv::trace(int level, const TCHAR *text)
1334 {
1335 if (level == 0)
1336 {
1337 nxlog_write(MSG_OTHER, EVENTLOG_INFORMATION_TYPE, "s", text);
1338 }
1339 else
1340 {
1341 DbgPrintf(level, _T("%s"), text);
1342 }
1343 }
1344
1345 /**
1346 * Print script output to console
1347 */
1348 void NXSL_ServerEnv::print(NXSL_Value *value)
1349 {
1350 if (m_console != NULL)
1351 {
1352 const TCHAR *text = value->getValueAsCString();
1353 ConsolePrintf(m_console, _T("%s"), CHECK_NULL(text));
1354 }
1355 }