Merge branch 'develop' of git.netxms.org:public/netxms into develop
authorMarco Incalcaterra <marco.incalcaterra@thinksoft.it>
Sun, 5 Oct 2014 15:45:00 +0000 (17:45 +0200)
committerMarco Incalcaterra <marco.incalcaterra@thinksoft.it>
Sun, 5 Oct 2014 15:45:00 +0000 (17:45 +0200)
476 files changed:
.gitignore
ChangeLog
android/src/agent/res/values/build_number.xml
android/src/console/.classpath
android/src/console/res/values/build_number.xml
android/src/console/src/org/netxms/ui/android/main/adapters/ActivityListAdapter.java
android/src/console/src/org/netxms/ui/android/main/adapters/AlarmListAdapter.java
android/src/console/src/org/netxms/ui/android/main/adapters/InterfaceDetailsAdapter.java
android/src/console/src/org/netxms/ui/android/main/adapters/InterfacesAdapter.java
android/src/console/src/org/netxms/ui/android/main/adapters/LastValuesAdapter.java
android/src/console/src/org/netxms/ui/android/main/adapters/ObjectListAdapter.java
android/src/console/src/org/netxms/ui/android/main/adapters/OverviewAdapter.java
android/src/console/src/org/netxms/ui/android/service/ClientConnectorService.java
build/build_number
configure.ac
doc/internal/checklists/AddingNewConfigParameter.txt [new file with mode: 0644]
include/build.h
include/netxms-version.h
include/netxmsdb.h
include/nms_agent.h
include/nms_common.h
include/nms_cscp.h
include/nms_threads.h
include/nms_util.h
include/nxclapi.h
include/nxconfig.h
include/nxcpapi.h
include/nxdbapi.h
include/nxevent.h
include/nxsl_classes.h
netxms.sln
packages/solaris/agent/files/nxagentd
packages/solaris/agent/pkginfo.in
packages/solaris/agent/postinstall
packages/solaris/agent/preinstall
packages/solaris/agent/preremove
packages/solaris/server/Makefile
packages/solaris/server/files/netxmsd
packages/solaris/server/files/netxmsd.xml
packages/solaris/server/pkginfo.in
packages/solaris/server/postinstall
packages/solaris/server/preinstall
packages/solaris/server/preremove
sql/events.in
sql/schema.in
sql/setup.in
src/agent/core/Makefile.am
src/agent/core/comm.cpp
src/agent/core/epp.cpp
src/agent/core/exec.cpp
src/agent/core/getparam.cpp
src/agent/core/nxagentd.cpp
src/agent/core/nxagentd.h
src/agent/core/nxagentd.vcproj
src/agent/core/policy.cpp
src/agent/core/sa.cpp [new file with mode: 0644]
src/agent/core/session.cpp
src/agent/core/subagent.cpp
src/agent/nxsagent/main.cpp [new file with mode: 0644]
src/agent/nxsagent/nxsagent.h [copied from include/netxmsdb.h with 56% similarity]
src/agent/nxsagent/nxsagent.vcproj [copied from src/agent/subagents/winnt/winnt.vcproj with 76% similarity]
src/agent/nxsagent/png.cpp [new file with mode: 0644]
src/agent/nxsagent/screenshot.cpp [new file with mode: 0644]
src/agent/subagents/filemgr/filemgr.cpp
src/agent/subagents/filemgr/filemgr.h
src/agent/subagents/filemgr/logmonitoring.cpp
src/agent/subagents/oracle/Makefile.am
src/agent/subagents/oracle/db.cpp [new file with mode: 0644]
src/agent/subagents/oracle/main.cpp
src/agent/subagents/oracle/oracle.vcproj
src/agent/subagents/oracle/oracle_subagent.h
src/agent/subagents/portCheck/main.cpp
src/agent/subagents/winnt/main.cpp
src/agent/subagents/winnt/system.cpp
src/agent/subagents/winnt/winnt.vcproj
src/agent/subagents/winnt/winnt_subagent.h
src/agent/tools/nxapush/nxapush.cpp
src/client/nxalarm/nxalarm.cpp
src/client/windows/nxcon/ObjectPropsCustomAttrs.cpp
src/client/windows/nxcon/RuleSituationDlg.cpp
src/client/windows/nxcon/globals.cpp
src/install/windows/netxms-x64.iss
src/install/windows/netxms.iss
src/install/windows/setup.iss
src/java/build/pack.cmd
src/java/build/set_build_number.cmd
src/java/certificate-manager/pom.xml
src/java/certificate-manager/src/test/java/org/netxms/certificate/TestListener.java
src/java/mobile-agent/pom.xml
src/java/mobile-agent/src/main/java/org/netxms/mobile/agent/Session.java
src/java/mobile-agent/src/test/java/org/netxms/mobile/agent/SessionTest.java
src/java/mobile-agent/src/test/java/org/netxms/mobile/agent/TestConstants.java [new file with mode: 0644]
src/java/netxms-base/pom.xml
src/java/netxms-base/src/main/java/org/netxms/base/BuildNumber.java
src/java/netxms-base/src/main/java/org/netxms/base/NXCPCodes.java
src/java/netxms-client-api/pom.xml
src/java/netxms-client/pom.xml
src/java/netxms-client/src/main/java/org/netxms/client/NXCObjectModificationData.java
src/java/netxms-client/src/main/java/org/netxms/client/NXCSession.java
src/java/netxms-client/src/main/java/org/netxms/client/TimePeriod.java [new file with mode: 0644]
src/java/netxms-client/src/main/java/org/netxms/client/constants/ObjectStatus.java [new file with mode: 0644]
src/java/netxms-client/src/main/java/org/netxms/client/constants/Severity.java
src/java/netxms-client/src/main/java/org/netxms/client/datacollection/DataCollectionObject.java
src/java/netxms-client/src/main/java/org/netxms/client/datacollection/Threshold.java
src/java/netxms-client/src/main/java/org/netxms/client/datacollection/ThresholdViolationSummary.java
src/java/netxms-client/src/main/java/org/netxms/client/events/Alarm.java
src/java/netxms-client/src/main/java/org/netxms/client/events/AlarmComment.java
src/java/netxms-client/src/main/java/org/netxms/client/events/EventProcessingPolicyRule.java
src/java/netxms-client/src/main/java/org/netxms/client/events/EventTemplate.java
src/java/netxms-client/src/main/java/org/netxms/client/objects/AbstractObject.java
src/java/netxms-client/src/main/java/org/netxms/client/objects/Interface.java
src/java/netxms-client/src/main/java/org/netxms/client/objects/NetworkMap.java
src/java/netxms-client/src/main/java/org/netxms/client/objects/UnknownObject.java
src/java/netxms-client/src/test/java/org/netxms/client/AgentTest.java
src/java/netxms-client/src/test/java/org/netxms/client/ConnectionTest.java
src/java/netxms-client/src/test/java/org/netxms/client/DataCollectionTest.java
src/java/netxms-client/src/test/java/org/netxms/client/EventProcessingPolicyTest.java
src/java/netxms-client/src/test/java/org/netxms/client/ObjectTest.java
src/java/netxms-client/src/test/java/org/netxms/client/ServerFilesTest.java
src/java/netxms-client/src/test/java/org/netxms/client/SessionTest.java
src/java/netxms-client/src/test/java/org/netxms/client/TestConstants.java
src/java/netxms-client/src/test/java/org/netxms/client/TopologyTest.java
src/java/netxms-eclipse/AgentManager/icons/image_obj.gif [new file with mode: 0644]
src/java/netxms-eclipse/AgentManager/plugin.xml
src/java/netxms-eclipse/AgentManager/src/org/netxms/ui/eclipse/agentmanager/actions/OpenAgentScreenshot.java [new file with mode: 0644]
src/java/netxms-eclipse/AgentManager/src/org/netxms/ui/eclipse/agentmanager/views/AgentScreenshotView.java [new file with mode: 0644]
src/java/netxms-eclipse/AgentManager/src/org/netxms/ui/eclipse/agentmanager/widgets/internal/AgentConfigSourceViewerConfiguration.java
src/java/netxms-eclipse/AlarmViewer/plugin.xml
src/java/netxms-eclipse/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/AlarmNotifier.java
src/java/netxms-eclipse/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/views/ObjectAlarmBrowser.java
src/java/netxms-eclipse/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/widgets/AlarmList.java
src/java/netxms-eclipse/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/widgets/helpers/AlarmComparator.java
src/java/netxms-eclipse/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/widgets/helpers/AlarmListFilter.java
src/java/netxms-eclipse/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/widgets/helpers/AlarmListLabelProvider.java
src/java/netxms-eclipse/Charts/src/org/netxms/ui/eclipse/charts/api/DataChart.java
src/java/netxms-eclipse/Charts/src/org/netxms/ui/eclipse/charts/figures/BirtChartFigure.java
src/java/netxms-eclipse/Charts/src/org/netxms/ui/eclipse/charts/widgets/CurrentValueWidget.java
src/java/netxms-eclipse/Charts/src/org/netxms/ui/eclipse/charts/widgets/DataComparisonBirtChart.java
src/java/netxms-eclipse/Charts/src/org/netxms/ui/eclipse/charts/widgets/DialChartWidget.java
src/java/netxms-eclipse/Charts/src/org/netxms/ui/eclipse/charts/widgets/LineChart.java
src/java/netxms-eclipse/Core/.classpath
src/java/netxms-eclipse/Core/META-INF/MANIFEST.MF
src/java/netxms-eclipse/Core/build.properties
src/java/netxms-eclipse/Core/nxmc.product
src/java/netxms-eclipse/Core/plugin.xml
src/java/netxms-eclipse/Core/src/org/netxms/ui/eclipse/console/resources/StatusDisplayInfo.java
src/java/netxms-eclipse/Core/src/org/netxms/ui/eclipse/widgets/StatusSelector.java
src/java/netxms-eclipse/Core/src/org/netxms/ui/eclipse/widgets/TimePeriodSelector.java [new file with mode: 0644]
src/java/netxms-eclipse/Dashboard/src/org/netxms/ui/eclipse/dashboard/widgets/ObjectStatusChartElement.java
src/java/netxms-eclipse/Dashboard/src/org/netxms/ui/eclipse/dashboard/widgets/StatusIndicatorElement.java
src/java/netxms-eclipse/DataCollection/META-INF/MANIFEST.MF
src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/Messages.java
src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/dialogs/SelectInternalParamDlg.java
src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/dialogs/SelectParameterScriptDialog.java [new file with mode: 0644]
src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/dialogs/TestTransformationDlg.java
src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/messages.properties
src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/messages_cs.properties
src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/messages_es.properties
src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/messages_ru.properties
src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/messages_zh_CN.properties
src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/propertypages/General.java
src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/views/DataCollectionEditor.java
src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/views/helpers/DciLabelProvider.java
src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/widgets/internal/LastValuesLabelProvider.java
src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/widgets/internal/ThresholdTreeComparator.java
src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/widgets/internal/ThresholdTreeLabelProvider.java
src/java/netxms-eclipse/EPP/META-INF/MANIFEST.MF
src/java/netxms-eclipse/EPP/plugin.xml
src/java/netxms-eclipse/EPP/src/org/netxms/ui/eclipse/epp/propertypages/RuleAlarm.java
src/java/netxms-eclipse/EPP/src/org/netxms/ui/eclipse/epp/propertypages/RuleEvents.java
src/java/netxms-eclipse/EPP/src/org/netxms/ui/eclipse/epp/propertypages/RuleServerActions.java
src/java/netxms-eclipse/EPP/src/org/netxms/ui/eclipse/epp/propertypages/RuleSituation.java
src/java/netxms-eclipse/EPP/src/org/netxms/ui/eclipse/epp/views/EventProcessingPolicyEditor.java
src/java/netxms-eclipse/EPP/src/org/netxms/ui/eclipse/epp/widgets/RuleEditor.java
src/java/netxms-eclipse/EventManager/META-INF/MANIFEST.MF
src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/dialogs/EditEventTemplateDialog.java
src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/dialogs/EventSelectionDialog.java
src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/helpers/EventTemplateComparator.java
src/java/netxms-eclipse/EventManager/src/org/netxms/ui/eclipse/eventmanager/widgets/helpers/SyslogLabelProvider.java
src/java/netxms-eclipse/FileManager/META-INF/MANIFEST.MF
src/java/netxms-eclipse/FileManager/src/org/netxms/ui/eclipse/filemanager/views/AgentFileManager.java
src/java/netxms-eclipse/FileManager/src/org/netxms/ui/eclipse/filemanager/views/helpers/ServerFileLabelProvider.java
src/java/netxms-eclipse/LogViewer/META-INF/MANIFEST.MF
src/java/netxms-eclipse/LogViewer/src/org/netxms/ui/eclipse/logviewer/widgets/SeverityConditionEditor.java
src/java/netxms-eclipse/NetworkMaps/META-INF/MANIFEST.MF
src/java/netxms-eclipse/NetworkMaps/icons/hide_link.png [new file with mode: 0644]
src/java/netxms-eclipse/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/MapImageProvidersManager.java
src/java/netxms-eclipse/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/api/NetworkMapImageProvider.java
src/java/netxms-eclipse/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/propertypages/MapOptions.java
src/java/netxms-eclipse/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/views/AbstractNetworkMapView.java
src/java/netxms-eclipse/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/views/helpers/MapLabelProvider.java
src/java/netxms-eclipse/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/views/helpers/ObjectFigureIcon.java
src/java/netxms-eclipse/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/views/helpers/ObjectFigureType.java
src/java/netxms-eclipse/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/views/helpers/ObjectStatusIcon.java [new file with mode: 0644]
src/java/netxms-eclipse/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/views/helpers/ObjectTooltip.java
src/java/netxms-eclipse/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/views/helpers/ResourceFigure.java
src/java/netxms-eclipse/OSM/icons/map_zoom_in.png [new file with mode: 0644]
src/java/netxms-eclipse/OSM/icons/map_zoom_out.png [new file with mode: 0644]
src/java/netxms-eclipse/OSM/src/org/netxms/ui/eclipse/osm/dialogs/TimeSelectionDialog.java [new file with mode: 0644]
src/java/netxms-eclipse/OSM/src/org/netxms/ui/eclipse/osm/views/HistoryView.java
src/java/netxms-eclipse/OSM/src/org/netxms/ui/eclipse/osm/widgets/GeoMapViewer.java
src/java/netxms-eclipse/ObjectBrowser/src/org/netxms/ui/eclipse/objectbrowser/ObjectDecorator.java
src/java/netxms-eclipse/ObjectBrowser/src/org/netxms/ui/eclipse/objectbrowser/views/ObjectBrowser.java
src/java/netxms-eclipse/ObjectBrowser/src/org/netxms/ui/eclipse/objectbrowser/widgets/ObjectStatusIndicator.java
src/java/netxms-eclipse/ObjectBrowser/src/org/netxms/ui/eclipse/objectbrowser/widgets/internal/ObjectFilter.java
src/java/netxms-eclipse/ObjectManager/META-INF/MANIFEST.MF
src/java/netxms-eclipse/ObjectManager/OSGI-INF/l10n/bundle.properties
src/java/netxms-eclipse/ObjectManager/OSGI-INF/l10n/bundle_cs.properties
src/java/netxms-eclipse/ObjectManager/OSGI-INF/l10n/bundle_es.properties
src/java/netxms-eclipse/ObjectManager/OSGI-INF/l10n/bundle_ru.properties
src/java/netxms-eclipse/ObjectManager/OSGI-INF/l10n/bundle_zh_CN.properties
src/java/netxms-eclipse/ObjectManager/plugin.xml
src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/actions/DeleteObject.java
src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/actions/Manage.java
src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/actions/Unmanage.java
src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/dialogs/AddAddressListElementDialog.java [new file with mode: 0644]
src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/propertypages/ConditionEvents.java
src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/propertypages/StatusCalculation.java
src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/propertypages/VPNSubnets.java [new file with mode: 0644]
src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/propertypages/helpers/AddressListElementComparator.java [new file with mode: 0644]
src/java/netxms-eclipse/ObjectTools/META-INF/MANIFEST.MF
src/java/netxms-eclipse/ObjectTools/plugin.xml
src/java/netxms-eclipse/ObjectTools/src/org/netxms/ui/eclipse/objecttools/views/BrowserView.java
src/java/netxms-eclipse/ObjectView/META-INF/MANIFEST.MF
src/java/netxms-eclipse/ObjectView/src/org/netxms/ui/eclipse/objectview/objecttabs/helpers/InterfaceListComparator.java
src/java/netxms-eclipse/ObjectView/src/org/netxms/ui/eclipse/objectview/objecttabs/helpers/InterfaceListLabelProvider.java
src/java/netxms-eclipse/ObjectView/src/org/netxms/ui/eclipse/objectview/objecttabs/helpers/NodeListComparator.java
src/java/netxms-eclipse/ObjectView/src/org/netxms/ui/eclipse/objectview/views/TabbedObjectView.java
src/java/netxms-eclipse/ObjectView/src/org/netxms/ui/eclipse/objectview/widgets/ObjectStatusMap.java
src/java/netxms-eclipse/PerfView/src/org/netxms/ui/eclipse/perfview/ChartConfig.java
src/java/netxms-eclipse/PerfView/src/org/netxms/ui/eclipse/perfview/objecttabs/PerformanceTab.java
src/java/netxms-eclipse/PerfView/src/org/netxms/ui/eclipse/perfview/propertypages/General.java
src/java/netxms-eclipse/PerfView/src/org/netxms/ui/eclipse/perfview/views/DataComparisonView.java
src/java/netxms-eclipse/PerfView/src/org/netxms/ui/eclipse/perfview/views/HistoricalGraphView.java
src/java/netxms-eclipse/Topology/META-INF/MANIFEST.MF
src/java/netxms-eclipse/Topology/src/org/netxms/ui/eclipse/topology/widgets/SlotView.java
src/java/netxms-eclipse/Topology/src/org/netxms/ui/eclipse/topology/widgets/helpers/PortInfo.java
src/java/netxms-eclipse/UserManager/META-INF/MANIFEST.MF
src/java/netxms-eclipse/UserManager/src/org/netxms/ui/eclipse/usermanager/propertypages/SystemRights.java
src/java/nxreporting/pom.xml
src/java/nxreporting/sql/mysql/nxreporting.sql [new file with mode: 0644]
src/java/nxreporting/sql/mysql/quartz.sql [new file with mode: 0644]
src/java/nxreporting/sql/postgres/nxreporting.sql [new file with mode: 0644]
src/java/nxreporting/sql/postgres/quartz.sql [new file with mode: 0644]
src/java/package.cmd
src/java/package.sh
src/java/pom.xml
src/libnetxms/Makefile.am
src/libnetxms/array.cpp
src/libnetxms/config.cpp
src/libnetxms/geolocation.cpp
src/libnetxms/iconv.cpp [new file with mode: 0644]
src/libnetxms/inetaddr.cpp [new file with mode: 0644]
src/libnetxms/libnetxms.vcproj
src/libnetxms/log.cpp
src/libnetxms/main.cpp
src/libnetxms/message.cpp
src/libnetxms/nxcp.cpp
src/libnetxms/strmap-internal.h [copied from include/netxmsdb.h with 73% similarity]
src/libnetxms/strmap.cpp
src/libnetxms/strmapbase.cpp
src/libnetxms/tools.cpp
src/libnetxms/unicode.cpp
src/libnxcl/alarms.cpp
src/libnxcl/epp.cpp
src/libnxcl/objects.cpp
src/libnxsl/variable.cpp
src/libnxsl/vm.cpp
src/libpng/libpng.vcproj [copied from src/agent/subagents/winnt/winnt.vcproj with 78% similarity]
src/libpng/png.c [new file with mode: 0644]
src/libpng/png.h [new file with mode: 0644]
src/libpng/pngconf.h [new file with mode: 0644]
src/libpng/pngdebug.h [new file with mode: 0644]
src/libpng/pngerror.c [new file with mode: 0644]
src/libpng/pngget.c [new file with mode: 0644]
src/libpng/pnginfo.h [new file with mode: 0644]
src/libpng/pnglibconf.h [new file with mode: 0644]
src/libpng/pngmem.c [new file with mode: 0644]
src/libpng/pngpread.c [new file with mode: 0644]
src/libpng/pngpriv.h [new file with mode: 0644]
src/libpng/pngread.c [new file with mode: 0644]
src/libpng/pngrio.c [new file with mode: 0644]
src/libpng/pngrtran.c [new file with mode: 0644]
src/libpng/pngrutil.c [new file with mode: 0644]
src/libpng/pngset.c [new file with mode: 0644]
src/libpng/pngstruct.h [new file with mode: 0644]
src/libpng/pngtrans.c [new file with mode: 0644]
src/libpng/pngwio.c [new file with mode: 0644]
src/libpng/pngwrite.c [new file with mode: 0644]
src/libpng/pngwtran.c [new file with mode: 0644]
src/libpng/pngwutil.c [new file with mode: 0644]
src/server/Makefile.am
src/server/core/Makefile.am
src/server/core/alarm.cpp
src/server/core/ap_jobs.cpp
src/server/core/bizservice.cpp
src/server/core/client.cpp
src/server/core/config.cpp
src/server/core/container.cpp
src/server/core/datacoll.cpp
src/server/core/dbwrite.cpp
src/server/core/dcitem.cpp
src/server/core/dcobject.cpp
src/server/core/dctable.cpp
src/server/core/dctarget.cpp
src/server/core/epp.cpp
src/server/core/events.cpp
src/server/core/interface.cpp
src/server/core/job.cpp
src/server/core/jobmgr.cpp
src/server/core/ldap.cpp
src/server/core/lln.cpp
src/server/core/main.cpp
src/server/core/mdconn.cpp
src/server/core/mobile.cpp
src/server/core/modules.cpp
src/server/core/mt.cpp
src/server/core/netobj.cpp
src/server/core/node.cpp
src/server/core/nxcore.vcproj
src/server/core/nxslext.cpp
src/server/core/objects.cpp
src/server/core/pds.cpp [new file with mode: 0644]
src/server/core/radius.h
src/server/core/reporting.cpp
src/server/core/session.cpp
src/server/core/situation.cpp
src/server/core/snmptrap.cpp
src/server/core/subnet.cpp
src/server/core/syslogd.cpp
src/server/core/template.cpp
src/server/core/timer.cpp [new file with mode: 0644]
src/server/core/userdb.cpp
src/server/core/userdb_objects.cpp
src/server/drivers/lib/avaya-ers/avaya-ers.cpp
src/server/include/Makefile.am
src/server/include/nms_alarm.h
src/server/include/nms_core.h
src/server/include/nms_dcoll.h
src/server/include/nms_events.h
src/server/include/nms_objects.h
src/server/include/nms_topo.h
src/server/include/nms_users.h
src/server/include/nxcore_jobs.h
src/server/include/nxsrvapi.h
src/server/include/pdsdrv.h [new file with mode: 0644]
src/server/include/server_timers.h [new file with mode: 0644]
src/server/libnxsrv/agent.cpp
src/server/libnxsrv/main.cpp
src/server/libnxsrv/messages.mc
src/server/pdsdrv/Makefile.am [copied from src/server/Makefile.am with 85% similarity]
src/server/pdsdrv/rrdtool/Makefile.am [new file with mode: 0644]
src/server/pdsdrv/rrdtool/rrdtool.cpp [new file with mode: 0644]
src/server/pdsdrv/rrdtool/rrdtool.vcproj [copied from src/agent/subagents/oracle/oracle.vcproj with 80% similarity]
src/server/tools/driverloader/loader.cpp
src/server/tools/nxdbmgr/check.cpp
src/server/tools/nxdbmgr/upgrade.cpp
src/server/tools/nxget/nxget.cpp
tests/Makefile.am [copied from src/server/Makefile.am with 85% similarity]
tests/include/Makefile.am [copied from src/server/Makefile.am with 85% similarity]
tests/include/testtools.h [new file with mode: 0644]
tests/test-libnetxms/Makefile.am [copied from src/server/Makefile.am with 59% similarity]
tests/test-libnetxms/test-libnetxms.cpp [new file with mode: 0644]
tests/test-libnetxms/test-libnetxms.vcproj [copied from src/agent/subagents/oracle/oracle.vcproj with 78% similarity]
webui/webapp/AgentManager/icons/image_obj.gif [new file with mode: 0644]
webui/webapp/AgentManager/plugin.xml
webui/webapp/AgentManager/src/org/netxms/ui/eclipse/agentmanager/actions/OpenAgentScreenshot.java [new file with mode: 0644]
webui/webapp/AgentManager/src/org/netxms/ui/eclipse/agentmanager/views/AgentScreenshotView.java [new file with mode: 0644]
webui/webapp/AlarmViewer/META-INF/MANIFEST.MF
webui/webapp/AlarmViewer/plugin.xml
webui/webapp/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/AlarmNotifier.java
webui/webapp/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/views/ObjectAlarmBrowser.java
webui/webapp/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/widgets/AlarmList.java
webui/webapp/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/widgets/helpers/AlarmComparator.java
webui/webapp/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/widgets/helpers/AlarmListFilter.java
webui/webapp/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/widgets/helpers/AlarmListLabelProvider.java
webui/webapp/Charts/src/org/netxms/ui/eclipse/charts/widgets/LineChart.java
webui/webapp/Core/.classpath
webui/webapp/Core/META-INF/MANIFEST.MF
webui/webapp/Core/build.properties
webui/webapp/Core/nxmc.warproduct
webui/webapp/Core/src/org/netxms/ui/eclipse/console/DownloadServiceHandler.java
webui/webapp/Core/src/org/netxms/ui/eclipse/console/resources/StatusDisplayInfo.java
webui/webapp/Core/src/org/netxms/ui/eclipse/widgets/StatusSelector.java
webui/webapp/Core/src/org/netxms/ui/eclipse/widgets/TimePeriodSelector.java [new file with mode: 0644]
webui/webapp/Dashboard/META-INF/MANIFEST.MF
webui/webapp/Dashboard/src/org/netxms/ui/eclipse/dashboard/widgets/ObjectStatusChartElement.java
webui/webapp/Dashboard/src/org/netxms/ui/eclipse/dashboard/widgets/StatusIndicatorElement.java
webui/webapp/DataCollection/META-INF/MANIFEST.MF
webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/Messages.java
webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/dialogs/SelectInternalParamDlg.java
webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/dialogs/SelectParameterScriptDialog.java [new file with mode: 0644]
webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/dialogs/TestTransformationDlg.java
webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/messages.properties
webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/messages_cs.properties
webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/messages_es.properties
webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/messages_ru.properties
webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/messages_zh_CN.properties
webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/propertypages/General.java
webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/views/DataCollectionEditor.java
webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/views/helpers/DciLabelProvider.java
webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/widgets/internal/LastValuesLabelProvider.java
webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/widgets/internal/ThresholdTreeComparator.java
webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/widgets/internal/ThresholdTreeLabelProvider.java
webui/webapp/EPP/META-INF/MANIFEST.MF
webui/webapp/EPP/plugin.xml
webui/webapp/EPP/src/org/netxms/ui/eclipse/epp/propertypages/RuleAlarm.java
webui/webapp/EPP/src/org/netxms/ui/eclipse/epp/propertypages/RuleEvents.java
webui/webapp/EPP/src/org/netxms/ui/eclipse/epp/propertypages/RuleServerActions.java
webui/webapp/EPP/src/org/netxms/ui/eclipse/epp/propertypages/RuleSituation.java
webui/webapp/EPP/src/org/netxms/ui/eclipse/epp/views/EventProcessingPolicyEditor.java
webui/webapp/EPP/src/org/netxms/ui/eclipse/epp/widgets/RuleEditor.java
webui/webapp/EventManager/META-INF/MANIFEST.MF
webui/webapp/EventManager/src/org/netxms/ui/eclipse/eventmanager/dialogs/EditEventTemplateDialog.java
webui/webapp/EventManager/src/org/netxms/ui/eclipse/eventmanager/views/helpers/EventTemplateComparator.java
webui/webapp/EventManager/src/org/netxms/ui/eclipse/eventmanager/widgets/helpers/SyslogLabelProvider.java
webui/webapp/FileManager/META-INF/MANIFEST.MF
webui/webapp/FileManager/src/org/netxms/ui/eclipse/filemanager/views/AgentFileManager.java
webui/webapp/FileManager/src/org/netxms/ui/eclipse/filemanager/views/helpers/ServerFileLabelProvider.java
webui/webapp/LogViewer/META-INF/MANIFEST.MF
webui/webapp/LogViewer/src/org/netxms/ui/eclipse/logviewer/widgets/SeverityConditionEditor.java
webui/webapp/Mobile/build.properties
webui/webapp/NetworkMaps/META-INF/MANIFEST.MF
webui/webapp/NetworkMaps/icons/hide_link.png [new file with mode: 0644]
webui/webapp/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/MapImageProvidersManager.java
webui/webapp/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/api/NetworkMapImageProvider.java
webui/webapp/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/propertypages/MapOptions.java
webui/webapp/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/views/AbstractNetworkMapView.java
webui/webapp/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/views/PredefinedMap.java
webui/webapp/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/views/helpers/BendpointEditor.java
webui/webapp/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/views/helpers/MapLabelProvider.java
webui/webapp/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/views/helpers/ObjectFigureIcon.java
webui/webapp/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/views/helpers/ObjectFigureType.java
webui/webapp/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/views/helpers/ObjectStatusIcon.java [new file with mode: 0644]
webui/webapp/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/views/helpers/ObjectTooltip.java
webui/webapp/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/views/helpers/ResourceFigure.java
webui/webapp/OSM/icons/map_zoom_in.png [new file with mode: 0644]
webui/webapp/OSM/icons/map_zoom_out.png [new file with mode: 0644]
webui/webapp/OSM/src/org/netxms/ui/eclipse/osm/dialogs/TimeSelectionDialog.java [new file with mode: 0644]
webui/webapp/OSM/src/org/netxms/ui/eclipse/osm/views/HistoryView.java
webui/webapp/OSM/src/org/netxms/ui/eclipse/osm/widgets/GeoMapViewer.java
webui/webapp/ObjectBrowser/src/org/netxms/ui/eclipse/objectbrowser/ObjectDecorator.java
webui/webapp/ObjectBrowser/src/org/netxms/ui/eclipse/objectbrowser/views/ObjectBrowser.java
webui/webapp/ObjectBrowser/src/org/netxms/ui/eclipse/objectbrowser/widgets/ObjectStatusIndicator.java
webui/webapp/ObjectBrowser/src/org/netxms/ui/eclipse/objectbrowser/widgets/internal/ObjectFilter.java
webui/webapp/ObjectManager/META-INF/MANIFEST.MF
webui/webapp/ObjectManager/OSGI-INF/l10n/bundle.properties
webui/webapp/ObjectManager/OSGI-INF/l10n/bundle_cs.properties
webui/webapp/ObjectManager/OSGI-INF/l10n/bundle_es.properties
webui/webapp/ObjectManager/OSGI-INF/l10n/bundle_ru.properties
webui/webapp/ObjectManager/OSGI-INF/l10n/bundle_zh_CN.properties
webui/webapp/ObjectManager/plugin.xml
webui/webapp/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/actions/DeleteObject.java
webui/webapp/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/actions/Manage.java
webui/webapp/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/actions/Unmanage.java
webui/webapp/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/dialogs/AddAddressListElementDialog.java [new file with mode: 0644]
webui/webapp/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/propertypages/ConditionEvents.java
webui/webapp/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/propertypages/StatusCalculation.java
webui/webapp/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/propertypages/VPNSubnets.java [new file with mode: 0644]
webui/webapp/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/propertypages/helpers/AddressListElementComparator.java [new file with mode: 0644]
webui/webapp/ObjectTools/META-INF/MANIFEST.MF
webui/webapp/ObjectTools/plugin.xml
webui/webapp/ObjectView/META-INF/MANIFEST.MF
webui/webapp/ObjectView/src/org/netxms/ui/eclipse/objectview/objecttabs/helpers/InterfaceListComparator.java
webui/webapp/ObjectView/src/org/netxms/ui/eclipse/objectview/objecttabs/helpers/InterfaceListLabelProvider.java
webui/webapp/ObjectView/src/org/netxms/ui/eclipse/objectview/objecttabs/helpers/NodeListComparator.java
webui/webapp/ObjectView/src/org/netxms/ui/eclipse/objectview/views/TabbedObjectView.java
webui/webapp/ObjectView/src/org/netxms/ui/eclipse/objectview/widgets/ObjectStatusMap.java
webui/webapp/PerfView/src/org/netxms/ui/eclipse/perfview/ChartConfig.java
webui/webapp/PerfView/src/org/netxms/ui/eclipse/perfview/objecttabs/PerformanceTab.java
webui/webapp/PerfView/src/org/netxms/ui/eclipse/perfview/propertypages/General.java
webui/webapp/Topology/META-INF/MANIFEST.MF
webui/webapp/Topology/src/org/netxms/ui/eclipse/topology/widgets/SlotView.java
webui/webapp/Topology/src/org/netxms/ui/eclipse/topology/widgets/helpers/PortInfo.java
webui/webapp/UserManager/META-INF/MANIFEST.MF
webui/webapp/UserManager/src/org/netxms/ui/eclipse/usermanager/propertypages/SystemRights.java

index 1e84c41..04e053e 100644 (file)
@@ -90,6 +90,7 @@ target
 /packages/solaris/pkginfo
 /private
 /release
+/sdk/install/Output
 /sql/dbinit_db2.sql
 /sql/dbinit_mssql.sql
 /sql/dbinit_mysql.sql
@@ -195,6 +196,7 @@ target
 /src/tools/nxencpasswd/nxencpasswd
 /stamp-h1
 /status
+/tests/test-libnetxms/test-libnetxms
 /webui/eclipse
 /x64
 
index 53254f3..889bc25 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,20 @@
 *
 * 1.2.17
 *
+
+- New DCI source: NXSL script executed on server
+- Configurable node matching policy for built-in syslog server (controlled by SyslogNodeMatchingPolicy configuration parameter)
+- Oracle monitoring subagent improved (bugs fixed, new metrics)
+- nxalarm tool supports commands add-comment and get-comments
+- Source port number added to events generated from SNMP trap (available via "sourcePort" named parameter)
+- Management console:
+    - Can show alarms for multiple selected objects
+    - Fixed non-working ordering in event list in alarm details view
+    - Fixed bug with LDAP user system rights
+    - Added default search string for LDAP to select all objects: "(objectClass=*)"
+    - Added device geolocation tracking and display on map
+    - Filter in event processing policy editor
+    - Fixed bug with deletion of subnet with corrected IP
 - Android console:
        - Fix bug in notifying connection point not found
        - Fix bug in computing interface expanded list size (removed hardcoded values)
@@ -8,12 +22,8 @@
        - Fix aesthetic problems in expandable list (graphs and interfaces list)
        - Integration of new support library
        - Target to new API version (20)
-- Management console:
-       - Can show alarms for multiple selected objects
-       - Fixed non-working ordering in event list in alarm details view
-    - Fixed bug with LDAP user system rights
-    - Added device geolocation tracking and display on map 
-- Fixed issues: #593, #613, #624
+- Fixed issues: #51, #91, #359, #409, #532, #542, #571, #563, #590, #593,
+                #613, #617, #624, #626, #629, #632, #635, #638, #639, #642, #649
 
 
 *
@@ -33,7 +43,7 @@
    - Fixed incorrect processing of ilike, match, and imatch operators
    - Added try / catch operator
 - New MIBs added: NETUP-MIB
-- Fixed issues: #424, #618, #619, #620
+- Fixed issues: #424, #463, #543, #618, #619, #620
 
 
 *
index 65a3891..ebd9c6d 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
-       <string name="build_number">7885</string>
+       <string name="build_number">7890</string>
 </resources>
index 23a83b2..3d55a1d 100644 (file)
@@ -9,9 +9,9 @@
        <classpathentry kind="lib" path="libs/acra-4.4.0.jar"/>
        <classpathentry kind="src" path="src"/>
        <classpathentry kind="src" path="gen"/>
-       <classpathentry kind="lib" path="libs/certificate-manager-1.2.16.jar"/>
-       <classpathentry kind="lib" path="libs/netxms-base-1.2.16.jar"/>
-       <classpathentry kind="lib" path="libs/netxms-client-1.2.16.jar"/>
-       <classpathentry kind="lib" path="libs/netxms-client-api-1.2.16.jar"/>
+       <classpathentry kind="lib" path="libs/certificate-manager-1.2.17.jar"/>
+       <classpathentry kind="lib" path="libs/netxms-base-1.2.17.jar"/>
+       <classpathentry kind="lib" path="libs/netxms-client-1.2.17.jar"/>
+       <classpathentry kind="lib" path="libs/netxms-client-api-1.2.17.jar"/>
        <classpathentry kind="output" path="bin/classes"/>
 </classpath>
index 65a3891..ebd9c6d 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
-       <string name="build_number">7885</string>
+       <string name="build_number">7890</string>
 </resources>
index fea9c75..49bd626 100644 (file)
@@ -4,13 +4,10 @@
 package org.netxms.ui.android.main.adapters;
 
 import java.util.ArrayList;
-
-import org.netxms.client.constants.Severity;
 import org.netxms.client.objects.AbstractObject;
 import org.netxms.ui.android.R;
 import org.netxms.ui.android.main.activities.HomeScreen;
 import org.netxms.ui.android.main.views.ActivityListElement;
-
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.LayerDrawable;
@@ -194,17 +191,17 @@ public class ActivityListAdapter extends BaseAdapter
                                                {
                                                        switch (obj.getStatus())
                                                        {
-                                                               case Severity.WARNING:
-                                                               case Severity.MINOR:
-                                                               case Severity.MAJOR:
-                                                               case Severity.CRITICAL:
-                                                                       infoLayer = parent.getResources().getDrawable(statusImageId[obj.getStatus()]);
+                                                               case WARNING:
+                                                               case MINOR:
+                                                               case MAJOR:
+                                                               case CRITICAL:
+                                                                       infoLayer = parent.getResources().getDrawable(statusImageId[obj.getStatus().getValue()]);
                                                                        break;
-                                                               case Severity.NORMAL:
-                                                               case Severity.UNKNOWN:
-                                                               case Severity.UNMANAGED:
-                                                               case Severity.DISABLED:
-                                                               case Severity.TESTING:
+                                                               case NORMAL:
+                                                               case UNKNOWN:
+                                                               case UNMANAGED:
+                                                               case DISABLED:
+                                                               case TESTING:
                                                                default:
                                                                        break;
                                                        }
index 9cc922f..51fd679 100644 (file)
@@ -162,7 +162,7 @@ public class AlarmListAdapter extends BaseAdapter
                int rc = 0;
                if (alarm1 != null && alarm2 != null)
                {
-                       rc = alarm1.getCurrentSeverity() - alarm2.getCurrentSeverity();
+                       rc = alarm1.getCurrentSeverity().compareTo(alarm2.getCurrentSeverity());
                        if (rc == 0)
                        {
                                rc = (int)(alarm1.getSourceObjectId() - alarm2.getSourceObjectId());
@@ -355,7 +355,7 @@ public class AlarmListAdapter extends BaseAdapter
        {
                final int[] severityImageId = { R.drawable.status_normal, R.drawable.status_warning,
                                R.drawable.status_minor, R.drawable.status_major, R.drawable.status_critical };
-               return severityImageId[alarm.getCurrentSeverity()];
+               return severityImageId[alarm.getCurrentSeverity().getValue()];
 
        }
        private int getAlarmIconState(Alarm alarm)
index fd04fd0..41f79d9 100644 (file)
@@ -6,6 +6,7 @@ package org.netxms.ui.android.main.adapters;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.netxms.client.constants.ObjectStatus;
 import org.netxms.client.objects.Interface;
 import org.netxms.ui.android.R;
 
@@ -192,7 +193,7 @@ public class InterfaceDetailsAdapter extends BaseAdapter
                return r.getColor(R.color.text_color);
        }
 
-       private int getNodeStatusColor(int status)
+       private int getNodeStatusColor(ObjectStatus status)
        {
                final int[] statuses =
                {
@@ -207,7 +208,7 @@ public class InterfaceDetailsAdapter extends BaseAdapter
                                R.color.status_testing
                };
 
-               return r.getColor(status >= 0 && status < statuses.length ? statuses[status] : R.color.status_unknown);
+               return r.getColor(status.getValue() >= 0 && status.getValue() < statuses.length ? statuses[status.getValue()] : R.color.status_unknown);
        }
 
        private String getExpStateText(int state)
@@ -224,7 +225,7 @@ public class InterfaceDetailsAdapter extends BaseAdapter
                return r.getString(R.string.status_unknown);
        }
 
-       private String getNodeStatusText(int status)
+       private String getNodeStatusText(ObjectStatus status)
        {
                final int[] statuses =
                {
@@ -239,6 +240,6 @@ public class InterfaceDetailsAdapter extends BaseAdapter
                                R.string.status_testing
                };
 
-               return r.getString(status >= 0 && status < statuses.length ? statuses[status] : R.string.status_unknown);
+               return r.getString(status.getValue() >= 0 && status.getValue() < statuses.length ? statuses[status.getValue()] : R.string.status_unknown);
        }
 }
index 6e7d4fe..5acea7b 100644 (file)
@@ -4,11 +4,9 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
-
-import org.netxms.client.constants.Severity;
+import org.netxms.client.constants.ObjectStatus;
 import org.netxms.client.objects.Interface;
 import org.netxms.ui.android.R;
-
 import android.annotation.SuppressLint;
 import android.content.Context;
 import android.view.LayoutInflater;
@@ -177,25 +175,25 @@ public class InterfacesAdapter extends BaseExpandableListAdapter
                return true;
        }
 
-       private int getInterfaceStatusIcon(int status)
+       private int getInterfaceStatusIcon(ObjectStatus status)
        {
                switch (status)
                {
-                       case Severity.NORMAL:
+                       case NORMAL:
                                return R.drawable.status_normal;
-                       case Severity.WARNING:
+                       case WARNING:
                                return R.drawable.status_warning;
-                       case Severity.MINOR:
+                       case MINOR:
                                return R.drawable.status_minor;
-                       case Severity.MAJOR:
+                       case MAJOR:
                                return R.drawable.status_major;
-                       case Severity.CRITICAL:
+                       case CRITICAL:
                                return R.drawable.status_critical;
-                       case Severity.UNKNOWN:
+                       case UNKNOWN:
                                return R.drawable.status_unknown;
-                       case Severity.UNMANAGED:
+                       case UNMANAGED:
                                return R.drawable.status_unmanaged;
-                       case Severity.DISABLED:
+                       case DISABLED:
                                return R.drawable.status_disabled;
                }
                return R.drawable.status_unknown;
index 874bb82..d8fe962 100644 (file)
@@ -298,7 +298,7 @@ public class LastValuesAdapter extends BaseAdapter
         */
        private int getThresholdIcon(Threshold t)
        {
-               int s = t != null ? t.getCurrentSeverity() : 0;
+               int s = t != null ? t.getCurrentSeverity().getValue() : 0;
                return severityImageId[s < severityImageId.length ? s : 0];
        }
 
index 4234a42..99dee81 100644 (file)
@@ -8,11 +8,9 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
-
-import org.netxms.client.constants.Severity;
+import org.netxms.client.constants.ObjectStatus;
 import org.netxms.client.objects.AbstractObject;
 import org.netxms.ui.android.R;
-
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
@@ -174,19 +172,19 @@ public class ObjectListAdapter extends BaseAdapter
                }
 
                // set fields in view
-               int objectStatus;
+               ObjectStatus objectStatus;
                int objectIconId = R.drawable.object_unknown;
                AbstractObject object = objectList.get(position);
                if (object == null)
                {
                        objectName.setText(r.getString(R.string.node_unknown));
                        objectStatusText.setText(r.getString(R.string.status_unknown));
-                       objectStatus = Severity.UNKNOWN;
+                       objectStatus = ObjectStatus.UNKNOWN;
                }
                else
                {
                        objectName.setText(object.getObjectName());
-                       objectStatusText.setText(statusTextId[object.getStatus()]);
+                       objectStatusText.setText(statusTextId[object.getStatus().getValue()]);
                        objectStatus = object.getStatus();
                        switch (object.getObjectClass())
                        {
@@ -216,7 +214,7 @@ public class ObjectListAdapter extends BaseAdapter
 
                Drawable[] layers = new Drawable[2];
                layers[0] = parent.getResources().getDrawable(objectIconId);
-               layers[1] = parent.getResources().getDrawable(ObjectListAdapter.statusImageId[objectStatus]);
+               layers[1] = parent.getResources().getDrawable(ObjectListAdapter.statusImageId[objectStatus.getValue()]);
                LayerDrawable drawable = new LayerDrawable(layers);
                drawable.setLayerInset(1, layers[0].getIntrinsicWidth() - layers[1].getIntrinsicWidth(),
                                layers[0].getIntrinsicHeight() - layers[1].getIntrinsicHeight(), 0, 0);
index c774c44..e78043e 100644 (file)
@@ -6,14 +6,12 @@ package org.netxms.ui.android.main.adapters;
 import java.text.DateFormat;
 import java.util.ArrayList;
 import java.util.List;
-
 import org.netxms.base.GeoLocation;
-import org.netxms.client.constants.Severity;
+import org.netxms.client.constants.ObjectStatus;
 import org.netxms.client.objects.AbstractObject;
 import org.netxms.client.objects.MobileDevice;
 import org.netxms.client.objects.Node;
 import org.netxms.ui.android.R;
-
 import android.content.Context;
 import android.content.res.Resources;
 import android.view.Gravity;
@@ -253,27 +251,27 @@ public class OverviewAdapter extends BaseAdapter
         * @param status NetXMS type of status
         * @return Human readable status 
         */
-       private String getNodeStatus(int status)
+       private String getNodeStatus(ObjectStatus status)
        {
                switch (status)
                {
-                       case Severity.NORMAL:
+                       case NORMAL:
                                return r.getString(R.string.status_normal);
-                       case Severity.WARNING:
+                       case WARNING:
                                return r.getString(R.string.status_warning);
-                       case Severity.MINOR:
+                       case MINOR:
                                return r.getString(R.string.status_minor);
-                       case Severity.MAJOR:
+                       case MAJOR:
                                return r.getString(R.string.status_major);
-                       case Severity.CRITICAL:
+                       case CRITICAL:
                                return r.getString(R.string.status_critical);
-                       case Severity.UNKNOWN:
+                       case UNKNOWN:
                                return r.getString(R.string.status_unknown);
-                       case Severity.UNMANAGED:
+                       case UNMANAGED:
                                return r.getString(R.string.status_unmanaged);
-                       case Severity.DISABLED:
+                       case DISABLED:
                                return r.getString(R.string.status_disabled);
-                       case Severity.TESTING:
+                       case TESTING:
                                return r.getString(R.string.status_testing);
                }
                return r.getString(R.string.status_unknown);
index a15591c..bdb9660 100644 (file)
@@ -15,6 +15,7 @@ import org.netxms.api.client.SessionNotification;
 import org.netxms.base.Logger;
 import org.netxms.client.NXCNotification;
 import org.netxms.client.NXCSession;
+import org.netxms.client.constants.Severity;
 import org.netxms.client.datacollection.DciValue;
 import org.netxms.client.events.Alarm;
 import org.netxms.client.objects.AbstractObject;
@@ -273,7 +274,7 @@ public class ClientConnectorService extends Service implements SessionListener
         */
        public void alarmNotification(Alarm alarm, String text)
        {
-               int severity = alarm.getCurrentSeverity();
+               Severity severity = alarm.getCurrentSeverity();
                if (notifyAlarm)
                {
                        Intent notifyIntent = new Intent(getApplicationContext(), AlarmBrowserFragment.class);
@@ -893,19 +894,19 @@ public class ClientConnectorService extends Service implements SessionListener
         * 
         * @param severity
         */
-       private String GetAlarmSound(int severity)
+       private String GetAlarmSound(Severity severity)
        {
                switch (severity)
                {
-                       case 0: // Normal
+                       case NORMAL: // Normal
                                return sp.getString("alarm.sound.normal", "");
-                       case 1: // Warning
+                       case WARNING: // Warning
                                return sp.getString("alarm.sound.warning", "");
-                       case 2: // Minor
+                       case MINOR: // Minor
                                return sp.getString("alarm.sound.minor", "");
-                       case 3: // Major
+                       case MAJOR: // Major
                                return sp.getString("alarm.sound.major", "");
-                       case 4: // Critical
+                       case CRITICAL: // Critical
                                return sp.getString("alarm.sound.critical", "");
                }
                return "";
@@ -916,19 +917,19 @@ public class ClientConnectorService extends Service implements SessionListener
         * 
         * @param severity
         */
-       private int getAlarmIcon(int severity)
+       private int getAlarmIcon(Severity severity)
        {
                switch (severity)
                {
-                       case 0: // Normal
+                       case NORMAL: // Normal
                                return R.drawable.status_normal;
-                       case 1: // Warning
+                       case WARNING: // Warning
                                return R.drawable.status_warning;
-                       case 2: // Minor
+                       case MINOR: // Minor
                                return R.drawable.status_minor;
-                       case 3: // Major
+                       case MAJOR: // Major
                                return R.drawable.status_major;
-                       case 4: // Critical
+                       case CRITICAL: // Critical
                                return R.drawable.status_critical;
                }
                return android.R.drawable.stat_notify_sdcard;
index 3906954..285ff73 100644 (file)
@@ -1 +1 @@
-7885
+7890
index 7e065a0..b6b735a 100644 (file)
@@ -4,7 +4,7 @@
 # Configure script
 #
 
-AC_INIT([NetXMS], [1.2.16], [bugs@netxms.org])
+AC_INIT([NetXMS], [1.2.17], [bugs@netxms.org])
 AC_CONFIG_AUX_DIR(config)
 AC_CONFIG_HEADERS(config.h)
 AM_INIT_AUTOMAKE
@@ -59,6 +59,7 @@ SERVER_TOOLS=""
 SERVER_INCLUDE=""
 SMSDRV_DIRS=""
 HDLINK_DIRS=""
+PDSDRV_DIRS=""
 TOP_LEVEL_MODULES=""
 CONTRIB_MODULES=""
 CLIENT_COMPONENTS=""
@@ -380,6 +381,11 @@ AC_ARG_ENABLE(iconv,
        DISABLE_ICONV="yes"
 ])
 
+AC_ARG_ENABLE(iconv-cache,
+[AS_HELP_STRING([--enable-iconv-cache=@<:@yes/no/auto@:>@],
+[cache iconv descriptors [default=auto]])],,
+[enable_iconv_cache=auto])
+
 AC_ARG_ENABLE(readline,
 [AS_HELP_STRING(--disable-readline,do not use libreadline)],
 [
@@ -444,8 +450,9 @@ AC_ARG_WITH(dist,
        SUBAGENT_DIRS="linux freebsd openbsd netbsd sunos aix ipso hpux odbcquery informix oracle lmsensors darwin rpi java netsvc db2"
        SMSDRV_DIRS="websms"
    HDLINK_DIRS="jira"
+   PDSDRV_DIRS="rrdtool"
        NXCONFIG="nxconfig"
-       TOP_LEVEL_MODULES="include sql images"
+       TOP_LEVEL_MODULES="include sql images tests"
        SERVER_INCLUDE="include"
        CONTRIB_MODULES="mibs backgrounds"
        CLIENT_COMPONENTS="nxalarm nxevent nxlexer nxpush nxsms scilexer windows"
@@ -458,6 +465,12 @@ AC_ARG_WITH(rpi-agent,
        COMPONENTS="$COMPONENTS raspberrypi"
 ])
 
+AC_ARG_WITH(tests,
+[AS_HELP_STRING(--with-tests,build tests)],
+[
+       TOP_LEVEL_MODULES="$TOP_LEVEL_MODULES tests"
+])
+
 
 #--------------------------------------------------------------------
 # Set LD_LIBRARY_PATH from LD_RUN_PATH because on some systems
@@ -804,6 +817,7 @@ esac
 #  * Turn on 64bit mode on HP-UX/Itanium
 #  * Turn on 64bit mode on AIX
 #  * Turn on 64bit mode on Solaris
+#  * Disable inconsistent C/C++ linkage warnings for Solaris Studio
 #--------------------------------------------------------------------
 
 if test "x$ac_compiler_gnu" = "xyes" ; then
@@ -1016,6 +1030,7 @@ fi
 if test "x$CXX" = "xCC" ; then
        SQLFLAGS="-Qn"
        CPPFLAGS="$CPPFLAGS -mt"
+       CXXFLAGS="$CXXFLAGS -erroff=badargtype2w,wbadinit"
 
        if test "x$FORCE_32BIT_BUILD" = "xyes"; then
                AC_MSG_CHECKING(whether C compiler accepts -m32)
@@ -1298,10 +1313,12 @@ if test "x$BUILD_SERVER" = "xyes" ; then
    if test "x$DISABLE_READLINE" = "xno"; then
       AC_CHECK_LIB(readline, readline, [SERVER_LIBS="$SERVER_LIBS -lreadline"], [AC_CHECK_LIB(edit, readline, [SERVER_LIBS="$SERVER_LIBS -ledit"])])
    fi
+   AC_CHECK_LIB(rt, timer_create, [SERVER_LIBS="$SERVER_LIBS -lrt"])
    SAVED_LDFLAGS="$LDFLAGS"
    LDFLAGS="$LDFLAGS $SERVER_LIBS"
 
-   AC_CHECK_FUNCS([readline])
+   AC_CHECK_FUNCS([readline timer_create])
+   AC_CHECK_TYPES([timer_t])
 
    # Check if passing rl_insert to rl_bind_key needs cast
    if test "$ac_cv_func_readline" = "yes"; then
@@ -1426,6 +1443,7 @@ if test "x$HAVE_LIBCURL" = "xyes"; then
   SUBAGENT_DIRS="$SUBAGENT_DIRS netsvc"
   SMSDRV_DIRS="$SMSDRV_DIRS websms"
   HDLINK_DIRS="$HDLINK_DIRS jira"
+  AC_DEFINE(HAVE_LIBCURL, 1, Define to 1 if libcurl is available)
 fi
 
 if test "x$LDAP_SUPPORT" = "xyes"; then
@@ -2110,6 +2128,49 @@ AC_RUN_IFELSE(
   [ AC_MSG_RESULT(no) ]
 )
 
+AC_MSG_CHECKING(whether iconv supports state reset)
+AC_RUN_IFELSE(
+  [AC_LANG_PROGRAM([
+#include <stdio.h>
+#if HAVE_ICONV_H
+#include <iconv.h>
+#endif
+     ], [
+     iconv_t cd = iconv_open("UTF-8","$valid_ucs2_code");
+     if (cd == (iconv_t)(-1)) return 1;
+     return iconv(cd, NULL, NULL, NULL, NULL) != 0;
+     ])
+  ],
+  [ AC_MSG_RESULT(yes)
+    AC_DEFINE(HAVE_ICONV_STATE_RESET, 1, Define to 1 if iconv supports state reset)
+  ],
+  [ AC_MSG_RESULT(no) ],
+  [ AC_MSG_RESULT(no) ]
+)
+
+AC_MSG_CHECKING(whether iconv descriptor cache is needed)
+case $enable_iconv_cache in
+    auto)
+        case $PLATFORM in
+            SunOS|HP-UX|AIX)
+                enable_iconv_cache=yes
+                ;;
+            *)
+                enable_iconv_cache=no
+                ;;
+        esac
+        ;;
+    yes|no)
+        ;;
+    *)
+        AC_MSG_ERROR([Value given to --enable-iconv-cache must be one of yes, no or auto])
+        ;;
+esac
+if test "x$enable_iconv_cache" = "xyes"; then
+    AC_DEFINE(WITH_ICONV_CACHE, 1, Define to 1 to enable iconv descriptor cache)
+fi
+AC_MSG_RESULT($enable_iconv_cache)
+
 # taken from ZSH's configure
 # Check if iconv uses const in prototype declaration
 if test "x$ac_found_iconv" = "xyes"; then
@@ -2132,6 +2193,9 @@ if test "x$ac_found_iconv" = "xyes"; then
     [Define as const if the declaration of iconv() needs const.])
 fi
 
+AC_MSG_CHECKING(if iconv descriptor cache is needed)
+
+
 if test "x$ac_cv_type_wchar_t" = "xyes"; then
        if test $ac_cv_sizeof_wchar_t -eq 2; then
                AC_DEFINE(UNICODE_UCS2, 1, Define to 1 if you have 2-byte wchar_t)
@@ -2377,6 +2441,7 @@ AC_SUBST(SERVER_LIBS)
 AC_SUBST(SERVER_TOOLS)
 AC_SUBST(SMSDRV_DIRS)
 AC_SUBST(HDLINK_DIRS)
+AC_SUBST(PDSDRV_DIRS)
 AC_SUBST(TOP_LEVEL_MODULES)
 AC_SUBST(CONTRIB_MODULES)
 AC_SUBST(CLIENT_COMPONENTS)
@@ -2585,6 +2650,8 @@ AC_CONFIG_FILES([
        src/server/include/Makefile
        src/server/libnxsrv/Makefile
        src/server/netxmsd/Makefile
+       src/server/pdsdrv/Makefile
+       src/server/pdsdrv/rrdtool/Makefile
        src/server/smsdrv/Makefile
        src/server/smsdrv/dummy/Makefile
        src/server/smsdrv/generic/Makefile
@@ -2612,6 +2679,9 @@ AC_CONFIG_FILES([
        src/tools/nxencpasswd/Makefile
        src/zlib/Makefile
        sql/Makefile
+       tests/Makefile
+       tests/include/Makefile
+       tests/test-libnetxms/Makefile
        tools/Makefile
 ])
 
diff --git a/doc/internal/checklists/AddingNewConfigParameter.txt b/doc/internal/checklists/AddingNewConfigParameter.txt
new file mode 100644 (file)
index 0000000..4891b4a
--- /dev/null
@@ -0,0 +1,8 @@
+Adding new server configuration parameter
+=========================================
+
+1. Add INSERT query to setup.in
+
+2. Add database upgrade procedure with CreateConfigParam call
+
+3. Update documentation (wiki and/or sphynx)
index d4b9ba4..e2c7663 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef __build_h
 #define __build_h
-#define NETXMS_VERSION_BUILD 7885
-#define NETXMS_VERSION_BUILD_STRING _T("7885")
+#define NETXMS_VERSION_BUILD 7890
+#define NETXMS_VERSION_BUILD_STRING _T("7890")
 #endif
index e70a858..bca2a29 100644 (file)
@@ -30,9 +30,9 @@
  */
 #define NETXMS_VERSION_MAJOR        1
 #define NETXMS_VERSION_MINOR        2
-#define NETXMS_VERSION_RELEASE      16
-#define NETXMS_VERSION_STRING       _T("1.2.16")
-#define NETXMS_VERSION_STRING_A     "1.2.16"
+#define NETXMS_VERSION_RELEASE      17
+#define NETXMS_VERSION_STRING       _T("1.2.17")
+#define NETXMS_VERSION_STRING_A     "1.2.17"
 
 #ifdef UNICODE
 #define IS_UNICODE_BUILD_STRING     _T(" (UNICODE)")
index 7e7891e..20e911e 100644 (file)
@@ -23,6 +23,6 @@
 #ifndef _netxmsdb_h
 #define _netxmsdb_h
 
-#define DB_FORMAT_VERSION   333
+#define DB_FORMAT_VERSION   337
 
 #endif
index 273fb3f..5fb7ed9 100644 (file)
@@ -92,6 +92,7 @@
 #define ERR_FILE_STAT_FAILED        ((UINT32)916)
 #define ERR_MEM_ALLOC_FAILED        ((UINT32)917)
 #define ERR_FILE_DELETE_FAILED      ((UINT32)918)
+#define ERR_NO_SESSION_AGENT        ((UINT32)919)
 
 /**
  * Parameter handler return codes
 #define WINPERF_AUTOMATIC_SAMPLE_COUNT    ((UINT32)0x00000001)
 #define WINPERF_REMOTE_COUNTER_CONFIG     ((UINT32)0x00000002)
 
+/**
+ * User session states (used by session agents)
+ */
+#define USER_SESSION_ACTIVE         0
+#define USER_SESSION_CONNECTED      1
+#define USER_SESSION_DISCONNECTED   2
+#define USER_SESSION_IDLE           3
+#define USER_SESSION_OTHER          4
+
 /**
  * Descriptions for common parameters
  */
 #define DCIDESC_DEPRECATED                        _T("<deprecated>")
 
 
+#define DCTDESC_AGENT_SESSION_AGENTS              _T("Registered session agents")
 #define DCTDESC_AGENT_SUBAGENTS                   _T("Loaded subagents")
 #define DCTDESC_FILESYSTEM_VOLUMES                _T("File system volumes")
 #define DCTDESC_SYSTEM_INSTALLED_PRODUCTS         _T("Installed products")
 #define DCTDESC_SYSTEM_PROCESSES                  _T("Processes")
 
+/**
+ * API for CommSession
+ */
+class AbstractCommSession
+{
+public:
+   virtual bool isMasterServer() = 0;
+   virtual bool isControlServer() = 0;
+   virtual const InetAddress& getServerAddress() = 0;
+
+   virtual void sendMessage(CSCPMessage *pMsg) = 0;
+   virtual void sendRawMessage(CSCP_MESSAGE *pMsg) = 0;
+       virtual bool sendFile(UINT32 requestId, const TCHAR *file, long offset) = 0;
+   virtual UINT32 openFile(TCHAR* nameOfFile, UINT32 requestId) = 0;
+};
+
 /**
  * Subagent's parameter information
  */
@@ -398,13 +425,13 @@ typedef struct
    TCHAR description[MAX_DB_STRING];
 } NETXMS_SUBAGENT_ACTION;
 
-/**
- * Subagent initialization structure
- */
 #define NETXMS_SUBAGENT_INFO_MAGIC     ((UINT32)0x20110301)
 
 class CSCPMessage;
 
+/**
+ * Subagent initialization structure
+ */
 typedef struct
 {
    UINT32 magic;    // Magic number to check if subagent uses correct version of this structure
@@ -412,7 +439,7 @@ typedef struct
    TCHAR version[32];
        BOOL (* init)(Config *);   // Called to initialize subagent. Can be NULL.
    void (* shutdown)();       // Called at subagent unload. Can be NULL.
-   BOOL (* commandHandler)(UINT32 dwCommand, CSCPMessage *pRequest, CSCPMessage *pResponse, void *session);
+   BOOL (* commandHandler)(UINT32 command, CSCPMessage *request, CSCPMessage *response, AbstractCommSession *session);
    UINT32 numParameters;
    NETXMS_SUBAGENT_PARAM *parameters;
    UINT32 numLists;
@@ -498,18 +525,6 @@ inline void ret_uint64(TCHAR *rbuf, QWORD value)
 #endif   /* _WIN32 */
 }
 
-/**
- * Api for CommSession
- */
-class AbstractCommSession
-{
-public:
-   virtual UINT32 openFile(TCHAR* nameOfFile, UINT32 requestId) = 0;
-   virtual BOOL isMasterServer() = 0;
-   virtual UINT32 getServerAddress() = 0;
-   virtual void sendMessage(CSCPMessage *pMsg) = 0;
-};
-
 //
 // API for subagents
 //
index dc2757a..c8c8ed2 100644 (file)
 /**
  * Compatibility defines for C sources
  */
-#ifndef __cplusplus
+#if !defined(__cplusplus) && !defined(CORTEX)
 typedef int bool;
 #endif
 
@@ -184,6 +184,8 @@ typedef int bool;
 #endif
 #define HAVE_DECL_VA_COPY       1
 
+#define HAVE_LIBCURL            1
+
 #include <winsock2.h>
 #include <windows.h>
 #include <ws2tcpip.h>
index 7d6066d..46e1090 100644 (file)
@@ -495,6 +495,7 @@ typedef struct
 #define CMD_GET_SWITCH_FDB             0x012B
 #define CMD_COMMAND_OUTPUT             0x012C
 #define CMD_GET_LOC_HISTORY            0x012D
+#define CMD_TAKE_SCREENSHOT            0x012E
 
 #define CMD_RS_LIST_REPORTS            0x1100
 #define CMD_RS_GET_REPORT              0x1101
@@ -992,6 +993,8 @@ typedef struct
 #define VID_ROOT                    ((UINT32)480)
 #define VID_INCLUDE_NOVALUE_OBJECTS ((UINT32)481)
 #define VID_RECEIVE_OUTPUT          ((UINT32)482)
+#define VID_SESSION_STATE           ((UINT32)483)
+#define VID_PAGE_SIZE               ((UINT32)484)
 
 // Base variabe for single threshold in message
 #define VID_THRESHOLD_BASE          ((UINT32)0x00800000)
index 5dac519..48090d5 100644 (file)
@@ -233,10 +233,10 @@ inline void ConditionPulse(CONDITION hCond)
    PulseEvent(hCond);
 }
 
-inline BOOL ConditionWait(CONDITION hCond, UINT32 dwTimeOut)
+inline bool ConditionWait(CONDITION hCond, UINT32 dwTimeOut)
 {
        if (hCond == INVALID_CONDITION_HANDLE)
-               return FALSE;
+               return false;
    return WaitForSingleObject(hCond, dwTimeOut) == WAIT_OBJECT_0;
 }
 
@@ -451,9 +451,9 @@ inline void ConditionPulse(CONDITION cond)
        }
 }
 
-inline BOOL ConditionWait(CONDITION cond, UINT32 dwTimeOut)
+inline bool ConditionWait(CONDITION cond, UINT32 dwTimeOut)
 {
-       BOOL ret = FALSE;
+       bool ret = false;
 
        if (cond != NULL)
        {
@@ -462,7 +462,7 @@ inline BOOL ConditionWait(CONDITION cond, UINT32 dwTimeOut)
                pth_mutex_acquire(&cond->mutex, FALSE, NULL);
       if (cond->isSet)
       {
-         ret = TRUE;
+         ret = true;
          if (!cond->broadcast)
             cond->isSet = FALSE;
       }
@@ -485,7 +485,7 @@ inline BOOL ConditionWait(CONDITION cond, UINT32 dwTimeOut)
                   {
             if (!cond->broadcast)
                cond->isSet = FALSE;
-                          ret = TRUE;
+                          ret = true;
                   }
       }
 
@@ -810,9 +810,9 @@ inline void ConditionPulse(CONDITION cond)
        }
 }
 
-inline BOOL ConditionWait(CONDITION cond, UINT32 dwTimeOut)
+inline bool ConditionWait(CONDITION cond, UINT32 dwTimeOut)
 {
-       BOOL ret = FALSE;
+       bool ret = FALSE;
 
        if (cond != NULL)
        {
@@ -821,7 +821,7 @@ inline BOOL ConditionWait(CONDITION cond, UINT32 dwTimeOut)
                pthread_mutex_lock(&cond->mutex);
       if (cond->isSet)
       {
-         ret = TRUE;
+         ret = true;
          if (!cond->broadcast)
             cond->isSet = FALSE;
       }
@@ -868,7 +868,7 @@ inline BOOL ConditionWait(CONDITION cond, UINT32 dwTimeOut)
                   {
             if (!cond->broadcast)
                cond->isSet = FALSE;
-                          ret = TRUE;
+                          ret = true;
                   }
       }
 
index ad470cf..c0cd951 100644 (file)
@@ -278,20 +278,148 @@ public:
        void shrink(int chars = 1);
 };
 
+/**
+ * Dynamic array class
+ */
+class LIBNETXMS_EXPORTABLE Array
+{
+private:
+       int m_size;
+       int m_allocated;
+       int m_grow;
+   size_t m_elementSize;
+       void **m_data;
+       bool m_objectOwner;
+
+       void internalRemove(int index, bool allowDestruction);
+       void destroyObject(void *object) { if (object != NULL) m_objectDestructor(object); }
+
+protected:
+   bool m_storePointers;
+       void (*m_objectDestructor)(void *);
+
+   Array(void *data, int initial, int grow, size_t elementSize);
+   void *__getBuffer() { return m_data; }
+
+public:
+       Array(int initial = 0, int grow = 16, bool owner = false);
+       virtual ~Array();
+
+       int add(void *element);
+   void *get(int index) { return ((index >= 0) && (index < m_size)) ? (m_storePointers ? m_data[index] : (void *)((char *)m_data + index * m_elementSize)): NULL; }
+   int indexOf(void *element);
+       void set(int index, void *element);
+       void replace(int index, void *element);
+       void remove(int index) { internalRemove(index, true); }
+   void remove(void *element) { internalRemove(indexOf(element), true); }
+       void unlink(int index) { internalRemove(index, false); }
+       void unlink(void *element) { internalRemove(indexOf(element), false); }
+       void clear();
+   void sort(int (*cb)(const void *, const void *));
+   void *find(const void *key, int (*cb)(const void *, const void *));
+
+       int size() { return m_size; }
+
+       void setOwner(bool owner) { m_objectOwner = owner; }
+       bool isOwner() { return m_objectOwner; }
+};
+
+/**
+ * Template class for dynamic array which holds objects
+ */
+template <class T> class ObjectArray : public Array
+{
+private:
+       static void destructor(void *object) { delete (T*)object; }
+
+public:
+       ObjectArray(int initial = 0, int grow = 16, bool owner = false) : Array(initial, grow, owner) { m_objectDestructor = destructor; }
+       virtual ~ObjectArray() { }
+
+       int add(T *object) { return Array::add((void *)object); }
+       T *get(int index) { return (T*)Array::get(index); }
+   int indexOf(T *object) { return Array::indexOf((void *)object); }
+       void set(int index, T *object) { Array::set(index, (void *)object); }
+       void replace(int index, T *object) { Array::replace(index, (void *)object); }
+       void remove(int index) { Array::remove(index); }
+   void remove(T *object) { Array::remove((void *)object); }
+       void unlink(int index) { Array::unlink(index); }
+   void unlink(T *object) { Array::unlink((void *)object); }
+};
+
+/**
+ * Template class for dynamic array which holds scalar values
+ */
+template <class T> class IntegerArray : public Array
+{
+private:
+       static void destructor(void *element) { }
+
+public:
+       IntegerArray(int initial = 0, int grow = 16) : Array(NULL, initial, grow, sizeof(T)) { m_objectDestructor = destructor; m_storePointers = (sizeof(T) == sizeof(void *)); }
+       virtual ~IntegerArray() { }
+
+   int add(T value) { return Array::add(m_storePointers ? CAST_TO_POINTER(value, void *) : &value); }
+   T get(int index) { return m_storePointers ? CAST_FROM_POINTER(Array::get(index), T) : *((T*)Array::get(index)); }
+   int indexOf(T value) { return Array::indexOf(m_storePointers ? CAST_TO_POINTER(value, void *) : &value); }
+   void set(int index, T value) { Array::set(index, m_storePointers ? CAST_TO_POINTER(value, void *) : &value); }
+   void replace(int index, T value) { Array::replace(index, m_storePointers ? CAST_TO_POINTER(value, void *) : &value); }
+
+   T *getBuffer() { return (T*)__getBuffer(); }
+};
+
+/**
+ * Auxilliary class to hold dynamically allocated array of structures
+ */
+template <class T> class StructArray : public Array
+{
+private:
+       static void destructor(void *element) { }
+
+public:
+       StructArray(int initial = 0, int grow = 16) : Array(NULL, initial, grow, sizeof(T)) { m_objectDestructor = destructor; }
+       StructArray(T *data, int size) : Array(data, size, 16, sizeof(T)) { m_objectDestructor = destructor; }
+       virtual ~StructArray() { }
+
+       int add(T *element) { return Array::add((void *)element); }
+       T *get(int index) { return (T*)Array::get(index); }
+   int indexOf(T *element) { return Array::indexOf((void *)element); }
+       void set(int index, T *element) { Array::set(index, (void *)element); }
+       void replace(int index, T *element) { Array::replace(index, (void *)element); }
+       void remove(int index) { Array::remove(index); }
+   void remove(T *element) { Array::remove((void *)element); }
+       void unlink(int index) { Array::unlink(index); }
+   void unlink(T *element) { Array::unlink((void *)element); }
+
+   T *getBuffer() { return (T*)__getBuffer(); }
+};
+
+/**
+ * Entry of string map (internal)
+ */
+struct StringMapEntry;
+
+/**
+ * Key/value pair
+ */
+struct KeyValuePair
+{
+   const TCHAR *key;
+   const void *value;
+};
+
 /**
  * String maps base class
  */
 class LIBNETXMS_EXPORTABLE StringMapBase
 {
 protected:
-       int m_size;
-       TCHAR **m_keys;
-       void **m_values;
+   StringMapEntry *m_data;
        bool m_objectOwner;
    bool m_ignoreCase;
        void (*m_objectDestructor)(void *);
 
-       UINT32 find(const TCHAR *key);
+       StringMapEntry *find(const TCHAR *key);
        void setObject(TCHAR *key, void *value, bool keyPreAlloc);
        void *getObject(const TCHAR *key);
        void destroyObject(void *object) { if (object != NULL) m_objectDestructor(object); }
@@ -301,15 +429,25 @@ public:
        virtual ~StringMapBase();
 
    void setOwner(bool owner) { m_objectOwner = owner; }
-   void setIgnoreCase(bool ignore) { m_ignoreCase = ignore; }
+   void setIgnoreCase(bool ignore);
 
        void remove(const TCHAR *key);
        void clear();
 
-       int size() { return m_size; }
-       const TCHAR *getKeyByIndex(int idx) { return ((idx >= 0) && (idx < m_size)) ? CHECK_NULL_EX(m_keys[idx]) : NULL; }
+       int size();
+   bool contains(const TCHAR *key) { return find(key) != NULL; }
+
+   bool forEach(bool (*cb)(const TCHAR *, const void *, void *), void *userData);
+   const void *findElement(bool (*comparator)(const TCHAR *, const void *, void *), void *userData);
+
+   StructArray<KeyValuePair> *toArray();
 };
 
+/**
+ * NXCP message class
+ */
+class CSCPMessage;
+
 /**
  * String map class
  */
@@ -332,7 +470,7 @@ public:
        UINT32 getULong(const TCHAR *key, UINT32 defaultValue);
        bool getBoolean(const TCHAR *key, bool defaultValue);
 
-       const TCHAR *getValueByIndex(int idx) { return ((idx >= 0) && (idx < m_size)) ? CHECK_NULL_EX((TCHAR *)m_values[idx]) : NULL; }
+   void fillMessage(CSCPMessage *msg, UINT32 sizeFieldId, UINT32 baseFieldId);
 };
 
 /**
@@ -348,7 +486,6 @@ public:
 
        void set(const TCHAR *key, T *object) { setObject((TCHAR *)key, (void *)object, false); }
        T *get(const TCHAR *key) { return (T*)getObject(key); }
-       T *getValueByIndex(int idx) { return ((idx >= 0) && (idx < m_size)) ? (T *)m_values[idx] : NULL; }
 };
 
 /**
@@ -429,121 +566,6 @@ public:
    String getAll(const TCHAR *separator);
 };
 
-/**
- * Dynamic array class
- */
-class LIBNETXMS_EXPORTABLE Array
-{
-private:
-       int m_size;
-       int m_allocated;
-       int m_grow;
-   size_t m_elementSize;
-       void **m_data;
-       bool m_objectOwner;
-
-       void internalRemove(int index, bool allowDestruction);
-       void destroyObject(void *object) { if (object != NULL) m_objectDestructor(object); }
-
-protected:
-   bool m_storePointers;
-       void (*m_objectDestructor)(void *);
-
-   Array(void *data, int initial, int grow, size_t elementSize);
-   void *__getBuffer() { return m_data; }
-
-public:
-       Array(int initial = 0, int grow = 16, bool owner = false);
-       virtual ~Array();
-
-       int add(void *element);
-   void *get(int index) { return ((index >= 0) && (index < m_size)) ? (m_storePointers ? m_data[index] : (void *)((char *)m_data + index * m_elementSize)): NULL; }
-   int indexOf(void *element);
-       void set(int index, void *element);
-       void replace(int index, void *element);
-       void remove(int index) { internalRemove(index, true); }
-   void remove(void *element) { internalRemove(indexOf(element), true); }
-       void unlink(int index) { internalRemove(index, false); }
-       void unlink(void *element) { internalRemove(indexOf(element), false); }
-       void clear();
-   void sort(int (*cb)(const void *, const void *));
-
-       int size() { return m_size; }
-
-       void setOwner(bool owner) { m_objectOwner = owner; }
-       bool isOwner() { return m_objectOwner; }
-};
-
-/**
- * Template class for dynamic array which holds objects
- */
-template <class T> class ObjectArray : public Array
-{
-private:
-       static void destructor(void *object) { delete (T*)object; }
-
-public:
-       ObjectArray(int initial = 0, int grow = 16, bool owner = false) : Array(initial, grow, owner) { m_objectDestructor = destructor; }
-       virtual ~ObjectArray() { }
-
-       int add(T *object) { return Array::add((void *)object); }
-       T *get(int index) { return (T*)Array::get(index); }
-   int indexOf(T *object) { return Array::indexOf((void *)object); }
-       void set(int index, T *object) { Array::set(index, (void *)object); }
-       void replace(int index, T *object) { Array::replace(index, (void *)object); }
-       void remove(int index) { Array::remove(index); }
-   void remove(T *object) { Array::remove((void *)object); }
-       void unlink(int index) { Array::unlink(index); }
-   void unlink(T *object) { Array::unlink((void *)object); }
-};
-
-/**
- * Template class for dynamic array which holds scalar values
- */
-template <class T> class IntegerArray : public Array
-{
-private:
-       static void destructor(void *element) { }
-
-public:
-       IntegerArray(int initial = 0, int grow = 16) : Array(NULL, initial, grow, sizeof(T)) { m_objectDestructor = destructor; m_storePointers = (sizeof(T) == sizeof(void *)); }
-       virtual ~IntegerArray() { }
-
-   int add(T value) { return Array::add(m_storePointers ? CAST_TO_POINTER(value, void *) : &value); }
-   T get(int index) { return m_storePointers ? CAST_FROM_POINTER(Array::get(index), T) : *((T*)Array::get(index)); }
-   int indexOf(T value) { return Array::indexOf(m_storePointers ? CAST_TO_POINTER(value, void *) : &value); }
-   void set(int index, T value) { Array::set(index, m_storePointers ? CAST_TO_POINTER(value, void *) : &value); }
-   void replace(int index, T value) { Array::replace(index, m_storePointers ? CAST_TO_POINTER(value, void *) : &value); }
-
-   T *getBuffer() { return (T*)__getBuffer(); }
-};
-
-/**
- * Auxilliary class to hold dynamically allocated array of structures
- */
-template <class T> class StructArray : public Array
-{
-private:
-       static void destructor(void *element) { }
-
-public:
-       StructArray(int initial = 0, int grow = 16) : Array(NULL, initial, grow, sizeof(T)) { m_objectDestructor = destructor; }
-       StructArray(T *data, int size) : Array(data, size, 16, sizeof(T)) { m_objectDestructor = destructor; }
-       virtual ~StructArray() { }
-
-       int add(T *element) { return Array::add((void *)element); }
-       T *get(int index) { return (T*)Array::get(index); }
-   int indexOf(T *element) { return Array::indexOf((void *)element); }
-       void set(int index, T *element) { Array::set(index, (void *)element); }
-       void replace(int index, T *element) { Array::replace(index, (void *)element); }
-       void remove(int index) { Array::remove(index); }
-   void remove(T *element) { Array::remove((void *)element); }
-       void unlink(int index) { Array::unlink(index); }
-   void unlink(T *element) { Array::unlink((void *)element); }
-
-   T *getBuffer() { return (T*)__getBuffer(); }
-};
-
 /**
  * Auxilliary class for objects which counts references and
  * destroys itself wheren reference count falls to 0
@@ -746,6 +768,50 @@ public:
    void setObjectId(int row, UINT32 id) { TableRow *r = m_data->get(row); if (r != NULL) r->setObjectId(id); }
 };
 
+/**
+ * IP address
+ */
+class LIBNETXMS_EXPORTABLE InetAddress
+{
+private:
+   short m_maskBits;
+   short m_family;
+   union
+   {
+      UINT32 v4;
+      BYTE v6[16];
+   } m_addr;
+
+public:
+   InetAddress();
+   InetAddress(UINT32 addr);
+   InetAddress(BYTE *addr);
+
+   bool isAnyLocal() const;
+   bool isLoopback() const;
+   bool isMulticast() const;
+   bool isBroadcast() const;
+   bool isValid() const { return m_family != AF_UNSPEC; }
+
+   int getFamily() const { return m_family; }
+   UINT32 getAddressV4() const { return (m_family == AF_INET) ? m_addr.v4 : 0; }
+   const BYTE *getAddressV6() const { return (m_family == AF_INET6) ? m_addr.v6 : (const BYTE *)"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; }
+
+   bool contain(const InetAddress &a) const;
+   bool equals(const InetAddress &a) const;
+   int compareTo(const InetAddress &a) const;
+
+   void setMaskBits(int m) { m_maskBits = m; }
+   int getMaskBits() const { return m_maskBits; }
+
+   String toString() const;
+   TCHAR *toString(TCHAR *buffer) const;
+
+   static InetAddress resolveHostName(const WCHAR *hostname, int af = AF_INET);
+   static InetAddress resolveHostName(const char *hostname, int af = AF_INET);
+   static InetAddress createFromSockaddr(struct sockaddr *s);
+};
+
 /**
  * Network connection
  */
@@ -978,163 +1044,165 @@ int LIBNETXMS_EXPORTABLE RecvEx(SOCKET hSocket, void *data, size_t len, int flag
 extern "C"
 {
 #endif
+
 #if defined(_WIN32) || !(HAVE_DECL___BSWAP_32)
-   UINT32 LIBNETXMS_EXPORTABLE __bswap_32(UINT32 dwVal);
+UINT32 LIBNETXMS_EXPORTABLE __bswap_32(UINT32 dwVal);
 #endif
 #if defined(_WIN32) || !(HAVE_DECL___BSWAP_64)
-   UINT64 LIBNETXMS_EXPORTABLE __bswap_64(UINT64 qwVal);
+UINT64 LIBNETXMS_EXPORTABLE __bswap_64(UINT64 qwVal);
 #endif
-   double LIBNETXMS_EXPORTABLE __bswap_double(double dVal);
-   void LIBNETXMS_EXPORTABLE __bswap_wstr(UCS2CHAR *pStr);
+double LIBNETXMS_EXPORTABLE __bswap_double(double dVal);
+void LIBNETXMS_EXPORTABLE __bswap_wstr(UCS2CHAR *pStr);
 
 #if !defined(_WIN32) && !defined(_NETWARE)
 #if defined(UNICODE_UCS2) || defined(UNICODE_UCS4)
-   void LIBNETXMS_EXPORTABLE wcsupr(WCHAR *in);
+void LIBNETXMS_EXPORTABLE __wcsupr(WCHAR *in);
+#define wcsupr __wcsupr
 #endif
-   void LIBNETXMS_EXPORTABLE strupr(char *in);
+void LIBNETXMS_EXPORTABLE __strupr(char *in);
+#define strupr __strupr
 #endif
 
-       void LIBNETXMS_EXPORTABLE QSortEx(void *base, size_t nmemb, size_t size, void *arg,
+void LIBNETXMS_EXPORTABLE QSortEx(void *base, size_t nmemb, size_t size, void *arg,
                                                                                                 int (*compare)(const void *, const void *, void *));
 
-   INT64 LIBNETXMS_EXPORTABLE GetCurrentTimeMs();
+INT64 LIBNETXMS_EXPORTABLE GetCurrentTimeMs();
 
-       UINT64 LIBNETXMS_EXPORTABLE FileSizeW(const WCHAR *pszFileName);
-       UINT64 LIBNETXMS_EXPORTABLE FileSizeA(const char *pszFileName);
+UINT64 LIBNETXMS_EXPORTABLE FileSizeW(const WCHAR *pszFileName);
+UINT64 LIBNETXMS_EXPORTABLE FileSizeA(const char *pszFileName);
 #ifdef UNICODE
 #define FileSize FileSizeW
 #else
 #define FileSize FileSizeA
 #endif
 
-   int LIBNETXMS_EXPORTABLE BitsInMask(UINT32 dwMask);
-   TCHAR LIBNETXMS_EXPORTABLE *IpToStr(UINT32 dwAddr, TCHAR *szBuffer);
+int LIBNETXMS_EXPORTABLE BitsInMask(UINT32 dwMask);
+TCHAR LIBNETXMS_EXPORTABLE *IpToStr(UINT32 dwAddr, TCHAR *szBuffer);
 #ifdef UNICODE
-   char LIBNETXMS_EXPORTABLE *IpToStrA(UINT32 dwAddr, char *szBuffer);
+char LIBNETXMS_EXPORTABLE *IpToStrA(UINT32 dwAddr, char *szBuffer);
 #else
 #define IpToStrA IpToStr
 #endif
-       TCHAR LIBNETXMS_EXPORTABLE *Ip6ToStr(BYTE *addr, TCHAR *buffer);
-       TCHAR LIBNETXMS_EXPORTABLE *SockaddrToStr(struct sockaddr *addr, TCHAR *buffer);
+TCHAR LIBNETXMS_EXPORTABLE *Ip6ToStr(const BYTE *addr, TCHAR *buffer);
+TCHAR LIBNETXMS_EXPORTABLE *SockaddrToStr(struct sockaddr *addr, TCHAR *buffer);
 
-   UINT32 LIBNETXMS_EXPORTABLE ResolveHostNameA(const char *name);
-   UINT32 LIBNETXMS_EXPORTABLE ResolveHostNameW(const WCHAR *name);
+UINT32 LIBNETXMS_EXPORTABLE ResolveHostNameA(const char *name);
+UINT32 LIBNETXMS_EXPORTABLE ResolveHostNameW(const WCHAR *name);
 #ifdef UNICODE
 #define ResolveHostName ResolveHostNameW
 #else
 #define ResolveHostName ResolveHostNameA
 #endif
 
-   void LIBNETXMS_EXPORTABLE *nx_memdup(const void *data, size_t size);
-   void LIBNETXMS_EXPORTABLE nx_memswap(void *block1, void *block2, size_t size);
+void LIBNETXMS_EXPORTABLE *nx_memdup(const void *data, size_t size);
+void LIBNETXMS_EXPORTABLE nx_memswap(void *block1, void *block2, size_t size);
 
-   WCHAR LIBNETXMS_EXPORTABLE *BinToStrW(const BYTE *data, size_t size, WCHAR *pStr);
-   char LIBNETXMS_EXPORTABLE *BinToStrA(const BYTE *data, size_t size, char *pStr);
+WCHAR LIBNETXMS_EXPORTABLE *BinToStrW(const BYTE *data, size_t size, WCHAR *pStr);
+char LIBNETXMS_EXPORTABLE *BinToStrA(const BYTE *data, size_t size, char *pStr);
 #ifdef UNICODE
 #define BinToStr BinToStrW
 #else
 #define BinToStr BinToStrA
 #endif
 
-   size_t LIBNETXMS_EXPORTABLE StrToBinW(const WCHAR *pStr, BYTE *data, size_t size);
-   size_t LIBNETXMS_EXPORTABLE StrToBinA(const char *pStr, BYTE *data, size_t size);
+size_t LIBNETXMS_EXPORTABLE StrToBinW(const WCHAR *pStr, BYTE *data, size_t size);
+size_t LIBNETXMS_EXPORTABLE StrToBinA(const char *pStr, BYTE *data, size_t size);
 #ifdef UNICODE
 #define StrToBin StrToBinW
 #else
 #define StrToBin StrToBinA
 #endif
 
-   TCHAR LIBNETXMS_EXPORTABLE *MACToStr(const BYTE *data, TCHAR *pStr);
+TCHAR LIBNETXMS_EXPORTABLE *MACToStr(const BYTE *data, TCHAR *pStr);
 
-   void LIBNETXMS_EXPORTABLE StrStripA(char *pszStr);
-   void LIBNETXMS_EXPORTABLE StrStripW(WCHAR *pszStr);
+void LIBNETXMS_EXPORTABLE StrStripA(char *pszStr);
+void LIBNETXMS_EXPORTABLE StrStripW(WCHAR *pszStr);
 #ifdef UNICODE
 #define StrStrip StrStripW
 #else
 #define StrStrip StrStripA
 #endif
 
-   const char LIBNETXMS_EXPORTABLE *ExtractWordA(const char *line, char *buffer);
-       const WCHAR LIBNETXMS_EXPORTABLE *ExtractWordW(const WCHAR *line, WCHAR *buffer);
+const char LIBNETXMS_EXPORTABLE *ExtractWordA(const char *line, char *buffer);
+const WCHAR LIBNETXMS_EXPORTABLE *ExtractWordW(const WCHAR *line, WCHAR *buffer);
 #ifdef UNICODE
 #define ExtractWord ExtractWordW
 #else
 #define ExtractWord ExtractWordA
 #endif
 
-   int LIBNETXMS_EXPORTABLE NumCharsA(const char *pszStr, char ch);
-   int LIBNETXMS_EXPORTABLE NumCharsW(const WCHAR *pszStr, WCHAR ch);
+int LIBNETXMS_EXPORTABLE NumCharsA(const char *pszStr, char ch);
+int LIBNETXMS_EXPORTABLE NumCharsW(const WCHAR *pszStr, WCHAR ch);
 #ifdef UNICODE
 #define NumChars NumCharsW
 #else
 #define NumChars NumCharsA
 #endif
 
-       void LIBNETXMS_EXPORTABLE RemoveTrailingCRLFA(char *str);
-       void LIBNETXMS_EXPORTABLE RemoveTrailingCRLFW(WCHAR *str);
+void LIBNETXMS_EXPORTABLE RemoveTrailingCRLFA(char *str);
+void LIBNETXMS_EXPORTABLE RemoveTrailingCRLFW(WCHAR *str);
 #ifdef UNICODE
 #define RemoveTrailingCRLF RemoveTrailingCRLFW
 #else
 #define RemoveTrailingCRLF RemoveTrailingCRLFA
 #endif
 
-       BOOL LIBNETXMS_EXPORTABLE RegexpMatchA(const char *pszStr, const char *pszExpr, BOOL bMatchCase);
-       BOOL LIBNETXMS_EXPORTABLE RegexpMatchW(const WCHAR *pszStr, const WCHAR *pszExpr, BOOL bMatchCase);
+BOOL LIBNETXMS_EXPORTABLE RegexpMatchA(const char *str, const char *expr, bool matchCase);
+BOOL LIBNETXMS_EXPORTABLE RegexpMatchW(const WCHAR *str, const WCHAR *expr, bool matchCase);
 #ifdef UNICODE
 #define RegexpMatch RegexpMatchW
 #else
 #define RegexpMatch RegexpMatchA
 #endif
 
-       const TCHAR LIBNETXMS_EXPORTABLE *ExpandFileName(const TCHAR *name, TCHAR *buffer, size_t bufSize, bool allowShellCommand);
-       void LIBNETXMS_EXPORTABLE Trim(TCHAR *str);
-   bool LIBNETXMS_EXPORTABLE MatchString(const TCHAR *pattern, const TCHAR *str, bool matchCase);
-       TCHAR LIBNETXMS_EXPORTABLE **SplitString(const TCHAR *source, TCHAR sep, int *numStrings);
+const TCHAR LIBNETXMS_EXPORTABLE *ExpandFileName(const TCHAR *name, TCHAR *buffer, size_t bufSize, bool allowShellCommand);
+void LIBNETXMS_EXPORTABLE Trim(TCHAR *str);
+bool LIBNETXMS_EXPORTABLE MatchString(const TCHAR *pattern, const TCHAR *str, bool matchCase);
+TCHAR LIBNETXMS_EXPORTABLE **SplitString(const TCHAR *source, TCHAR sep, int *numStrings);
 
 #ifdef __cplusplus
-   BOOL LIBNETXMS_EXPORTABLE IsValidObjectName(const TCHAR *pszName, BOOL bExtendedChars = FALSE);
+BOOL LIBNETXMS_EXPORTABLE IsValidObjectName(const TCHAR *pszName, BOOL bExtendedChars = FALSE);
 #endif
-   BOOL LIBNETXMS_EXPORTABLE IsValidScriptName(const TCHAR *pszName);
-   /* deprecated */ void LIBNETXMS_EXPORTABLE TranslateStr(TCHAR *pszString, const TCHAR *pszSubStr, const TCHAR *pszReplace);
-   const TCHAR LIBNETXMS_EXPORTABLE *GetCleanFileName(const TCHAR *pszFileName);
-   void LIBNETXMS_EXPORTABLE GetOSVersionString(TCHAR *pszBuffer, int nBufSize);
-       BYTE LIBNETXMS_EXPORTABLE *LoadFile(const TCHAR *pszFileName, UINT32 *pdwFileSize);
+BOOL LIBNETXMS_EXPORTABLE IsValidScriptName(const TCHAR *pszName);
+/* deprecated */ void LIBNETXMS_EXPORTABLE TranslateStr(TCHAR *pszString, const TCHAR *pszSubStr, const TCHAR *pszReplace);
+const TCHAR LIBNETXMS_EXPORTABLE *GetCleanFileName(const TCHAR *pszFileName);
+void LIBNETXMS_EXPORTABLE GetOSVersionString(TCHAR *pszBuffer, int nBufSize);
+BYTE LIBNETXMS_EXPORTABLE *LoadFile(const TCHAR *pszFileName, UINT32 *pdwFileSize);
 #ifdef UNICODE
-       BYTE LIBNETXMS_EXPORTABLE *LoadFileA(const char *pszFileName, UINT32 *pdwFileSize);
+BYTE LIBNETXMS_EXPORTABLE *LoadFileA(const char *pszFileName, UINT32 *pdwFileSize);
 #else
 #define LoadFileA LoadFile
 #endif
 
-   UINT32 LIBNETXMS_EXPORTABLE CalculateCRC32(const unsigned char *data, UINT32 size, UINT32 dwCRC);
-   void LIBNETXMS_EXPORTABLE CalculateMD5Hash(const unsigned char *data, size_t nbytes, unsigned char *hash);
-       void LIBNETXMS_EXPORTABLE MD5HashForPattern(const unsigned char *data, size_t patternSize, size_t fullSize, BYTE *hash);
-   void LIBNETXMS_EXPORTABLE CalculateSHA1Hash(unsigned char *data, size_t nbytes, unsigned char *hash);
-   void LIBNETXMS_EXPORTABLE SHA1HashForPattern(unsigned char *data, size_t patternSize, size_t fullSize, unsigned char *hash);
-   BOOL LIBNETXMS_EXPORTABLE CalculateFileMD5Hash(const TCHAR *pszFileName, BYTE *pHash);
-   BOOL LIBNETXMS_EXPORTABLE CalculateFileSHA1Hash(const TCHAR *pszFileName, BYTE *pHash);
-   BOOL LIBNETXMS_EXPORTABLE CalculateFileCRC32(const TCHAR *pszFileName, UINT32 *pResult);
+UINT32 LIBNETXMS_EXPORTABLE CalculateCRC32(const unsigned char *data, UINT32 size, UINT32 dwCRC);
+void LIBNETXMS_EXPORTABLE CalculateMD5Hash(const unsigned char *data, size_t nbytes, unsigned char *hash);
+void LIBNETXMS_EXPORTABLE MD5HashForPattern(const unsigned char *data, size_t patternSize, size_t fullSize, BYTE *hash);
+void LIBNETXMS_EXPORTABLE CalculateSHA1Hash(unsigned char *data, size_t nbytes, unsigned char *hash);
+void LIBNETXMS_EXPORTABLE SHA1HashForPattern(unsigned char *data, size_t patternSize, size_t fullSize, unsigned char *hash);
+BOOL LIBNETXMS_EXPORTABLE CalculateFileMD5Hash(const TCHAR *pszFileName, BYTE *pHash);
+BOOL LIBNETXMS_EXPORTABLE CalculateFileSHA1Hash(const TCHAR *pszFileName, BYTE *pHash);
+BOOL LIBNETXMS_EXPORTABLE CalculateFileCRC32(const TCHAR *pszFileName, UINT32 *pResult);
 
-       void LIBNETXMS_EXPORTABLE ICEEncryptData(const BYTE *in, int inLen, BYTE *out, const BYTE *key);
-       void LIBNETXMS_EXPORTABLE ICEDecryptData(const BYTE *in, int inLen, BYTE *out, const BYTE *key);
+void LIBNETXMS_EXPORTABLE ICEEncryptData(const BYTE *in, int inLen, BYTE *out, const BYTE *key);
+void LIBNETXMS_EXPORTABLE ICEDecryptData(const BYTE *in, int inLen, BYTE *out, const BYTE *key);
 
-       BOOL LIBNETXMS_EXPORTABLE DecryptPassword(const TCHAR *login, const TCHAR *encryptedPasswd, TCHAR *decryptedPasswd);
+BOOL LIBNETXMS_EXPORTABLE DecryptPassword(const TCHAR *login, const TCHAR *encryptedPasswd, TCHAR *decryptedPasswd);
 
-   UINT32 LIBNETXMS_EXPORTABLE IcmpPing(UINT32 dwAddr, int iNumRetries, UINT32 dwTimeout,
-                                       UINT32 *pdwRTT, UINT32 dwPacketSize);
+UINT32 LIBNETXMS_EXPORTABLE IcmpPing(UINT32 dwAddr, int iNumRetries, UINT32 dwTimeout, UINT32 *pdwRTT, UINT32 dwPacketSize);
 
-   int LIBNETXMS_EXPORTABLE NxDCIDataTypeFromText(const TCHAR *pszText);
+int LIBNETXMS_EXPORTABLE NxDCIDataTypeFromText(const TCHAR *pszText);
 
-   HMODULE LIBNETXMS_EXPORTABLE DLOpen(const TCHAR *pszLibName, TCHAR *pszErrorText);
-   void LIBNETXMS_EXPORTABLE DLClose(HMODULE hModule);
-   void LIBNETXMS_EXPORTABLE *DLGetSymbolAddr(HMODULE hModule, const char *pszSymbol, TCHAR *pszErrorText);
+HMODULE LIBNETXMS_EXPORTABLE DLOpen(const TCHAR *pszLibName, TCHAR *pszErrorText);
+void LIBNETXMS_EXPORTABLE DLClose(HMODULE hModule);
+void LIBNETXMS_EXPORTABLE *DLGetSymbolAddr(HMODULE hModule, const char *pszSymbol, TCHAR *pszErrorText);
 
-       bool LIBNETXMS_EXPORTABLE ExtractNamedOptionValueW(const WCHAR *optString, const WCHAR *option, WCHAR *buffer, int bufSize);
-       bool LIBNETXMS_EXPORTABLE ExtractNamedOptionValueAsBoolW(const WCHAR *optString, const WCHAR *option, bool defVal);
-       long LIBNETXMS_EXPORTABLE ExtractNamedOptionValueAsIntW(const WCHAR *optString, const WCHAR *option, long defVal);
+bool LIBNETXMS_EXPORTABLE ExtractNamedOptionValueW(const WCHAR *optString, const WCHAR *option, WCHAR *buffer, int bufSize);
+bool LIBNETXMS_EXPORTABLE ExtractNamedOptionValueAsBoolW(const WCHAR *optString, const WCHAR *option, bool defVal);
+long LIBNETXMS_EXPORTABLE ExtractNamedOptionValueAsIntW(const WCHAR *optString, const WCHAR *option, long defVal);
 
-       bool LIBNETXMS_EXPORTABLE ExtractNamedOptionValueA(const char *optString, const char *option, char *buffer, int bufSize);
-       bool LIBNETXMS_EXPORTABLE ExtractNamedOptionValueAsBoolA(const char *optString, const char *option, bool defVal);
-       long LIBNETXMS_EXPORTABLE ExtractNamedOptionValueAsIntA(const char *optString, const char *option, long defVal);
+bool LIBNETXMS_EXPORTABLE ExtractNamedOptionValueA(const char *optString, const char *option, char *buffer, int bufSize);
+bool LIBNETXMS_EXPORTABLE ExtractNamedOptionValueAsBoolA(const char *optString, const char *option, bool defVal);
+long LIBNETXMS_EXPORTABLE ExtractNamedOptionValueAsIntA(const char *optString, const char *option, long defVal);
 
 #ifdef UNICODE
 #define ExtractNamedOptionValue ExtractNamedOptionValueW
@@ -1147,181 +1215,181 @@ extern "C"
 #endif
 
 #ifdef __cplusplus
-       const TCHAR LIBNETXMS_EXPORTABLE *CodeToText(int iCode, CODE_TO_TEXT *pTranslator, const TCHAR *pszDefaultText = _T("Unknown"));
+const TCHAR LIBNETXMS_EXPORTABLE *CodeToText(int iCode, CODE_TO_TEXT *pTranslator, const TCHAR *pszDefaultText = _T("Unknown"));
 #else
-       const TCHAR LIBNETXMS_EXPORTABLE *CodeToText(int iCode, CODE_TO_TEXT *pTranslator, const TCHAR *pszDefaultText);
+const TCHAR LIBNETXMS_EXPORTABLE *CodeToText(int iCode, CODE_TO_TEXT *pTranslator, const TCHAR *pszDefaultText);
 #endif
 
 #ifdef _WIN32
-   TCHAR LIBNETXMS_EXPORTABLE *GetSystemErrorText(UINT32 dwError, TCHAR *pszBuffer, size_t iBufSize);
-       BOOL LIBNETXMS_EXPORTABLE GetWindowsVersionString(TCHAR *versionString, int strSize);
-       INT64 LIBNETXMS_EXPORTABLE GetProcessRSS();
+TCHAR LIBNETXMS_EXPORTABLE *GetSystemErrorText(UINT32 dwError, TCHAR *pszBuffer, size_t iBufSize);
+BOOL LIBNETXMS_EXPORTABLE GetWindowsVersionString(TCHAR *versionString, int strSize);
+INT64 LIBNETXMS_EXPORTABLE GetProcessRSS();
 #endif
 
 #if !(HAVE_DAEMON)
-   int LIBNETXMS_EXPORTABLE daemon(int nochdir, int noclose);
+int LIBNETXMS_EXPORTABLE daemon(int nochdir, int noclose);
 #endif
 
-   UINT32 LIBNETXMS_EXPORTABLE inet_addr_w(const WCHAR *pszAddr);
+UINT32 LIBNETXMS_EXPORTABLE inet_addr_w(const WCHAR *pszAddr);
 
 #ifndef _WIN32
-       BOOL LIBNETXMS_EXPORTABLE SetDefaultCodepage(const char *cp);
-   int LIBNETXMS_EXPORTABLE WideCharToMultiByte(int iCodePage, UINT32 dwFlags, const WCHAR *pWideCharStr,
-                                                int cchWideChar, char *pByteStr, int cchByteChar,
-                                                char *pDefaultChar, BOOL *pbUsedDefChar);
-   int LIBNETXMS_EXPORTABLE MultiByteToWideChar(int iCodePage, UINT32 dwFlags, const char *pByteStr,
-                                                int cchByteChar, WCHAR *pWideCharStr,
-                                                int cchWideChar);
+BOOL LIBNETXMS_EXPORTABLE SetDefaultCodepage(const char *cp);
+int LIBNETXMS_EXPORTABLE WideCharToMultiByte(int iCodePage, UINT32 dwFlags, const WCHAR *pWideCharStr,
+                                             int cchWideChar, char *pByteStr, int cchByteChar,
+                                             char *pDefaultChar, BOOL *pbUsedDefChar);
+int LIBNETXMS_EXPORTABLE MultiByteToWideChar(int iCodePage, UINT32 dwFlags, const char *pByteStr,
+                                             int cchByteChar, WCHAR *pWideCharStr,
+                                             int cchWideChar);
 
 #if !defined(UNICODE_UCS2) || !HAVE_WCSLEN
-       int LIBNETXMS_EXPORTABLE ucs2_strlen(const UCS2CHAR *pStr);
+int LIBNETXMS_EXPORTABLE ucs2_strlen(const UCS2CHAR *pStr);
 #endif
 #if !defined(UNICODE_UCS2) || !HAVE_WCSNCPY
-       UCS2CHAR LIBNETXMS_EXPORTABLE *ucs2_strncpy(UCS2CHAR *pDst, const UCS2CHAR *pSrc, int nDstLen);
+UCS2CHAR LIBNETXMS_EXPORTABLE *ucs2_strncpy(UCS2CHAR *pDst, const UCS2CHAR *pSrc, int nDstLen);
 #endif
 #if !defined(UNICODE_UCS2) || !HAVE_WCSDUP
-       UCS2CHAR LIBNETXMS_EXPORTABLE *ucs2__tcsdup(const UCS2CHAR *pStr);
+UCS2CHAR LIBNETXMS_EXPORTABLE *ucs2__tcsdup(const UCS2CHAR *pStr);
 #endif
 
-       size_t LIBNETXMS_EXPORTABLE ucs2_to_mb(const UCS2CHAR *src, int srcLen, char *dst, int dstLen);
-       size_t LIBNETXMS_EXPORTABLE mb_to_ucs2(const char *src, int srcLen, UCS2CHAR *dst, int dstLen);
-       UCS2CHAR LIBNETXMS_EXPORTABLE *UCS2StringFromMBString(const char *pszString);
-       char LIBNETXMS_EXPORTABLE *MBStringFromUCS2String(const UCS2CHAR *pszString);
+size_t LIBNETXMS_EXPORTABLE ucs2_to_mb(const UCS2CHAR *src, int srcLen, char *dst, int dstLen);
+size_t LIBNETXMS_EXPORTABLE mb_to_ucs2(const char *src, int srcLen, UCS2CHAR *dst, int dstLen);
+UCS2CHAR LIBNETXMS_EXPORTABLE *UCS2StringFromMBString(const char *pszString);
+char LIBNETXMS_EXPORTABLE *MBStringFromUCS2String(const UCS2CHAR *pszString);
 
-       int LIBNETXMS_EXPORTABLE nx_wprintf(const WCHAR *format, ...);
-       int LIBNETXMS_EXPORTABLE nx_fwprintf(FILE *fp, const WCHAR *format, ...);
-       int LIBNETXMS_EXPORTABLE nx_swprintf(WCHAR *buffer, size_t size, const WCHAR *format, ...);
-       int LIBNETXMS_EXPORTABLE nx_vwprintf(const WCHAR *format, va_list args);
-       int LIBNETXMS_EXPORTABLE nx_vfwprintf(FILE *fp, const WCHAR *format, va_list args);
-       int LIBNETXMS_EXPORTABLE nx_vswprintf(WCHAR *buffer, size_t size, const WCHAR *format, va_list args);
+int LIBNETXMS_EXPORTABLE nx_wprintf(const WCHAR *format, ...);
+int LIBNETXMS_EXPORTABLE nx_fwprintf(FILE *fp, const WCHAR *format, ...);
+int LIBNETXMS_EXPORTABLE nx_swprintf(WCHAR *buffer, size_t size, const WCHAR *format, ...);
+int LIBNETXMS_EXPORTABLE nx_vwprintf(const WCHAR *format, va_list args);
+int LIBNETXMS_EXPORTABLE nx_vfwprintf(FILE *fp, const WCHAR *format, va_list args);
+int LIBNETXMS_EXPORTABLE nx_vswprintf(WCHAR *buffer, size_t size, const WCHAR *format, va_list args);
 
-       int LIBNETXMS_EXPORTABLE nx_wscanf(const WCHAR *format, ...);
-       int LIBNETXMS_EXPORTABLE nx_fwscanf(FILE *fp, const WCHAR *format, ...);
-       int LIBNETXMS_EXPORTABLE nx_swscanf(const WCHAR *str, const WCHAR *format, ...);
-       int LIBNETXMS_EXPORTABLE nx_vwscanf(const WCHAR *format, va_list args);
-       int LIBNETXMS_EXPORTABLE nx_vfwscanf(FILE *fp, const WCHAR *format, va_list args);
-       int LIBNETXMS_EXPORTABLE nx_vswscanf(const WCHAR *str, const WCHAR *format, va_list args);
+int LIBNETXMS_EXPORTABLE nx_wscanf(const WCHAR *format, ...);
+int LIBNETXMS_EXPORTABLE nx_fwscanf(FILE *fp, const WCHAR *format, ...);
+int LIBNETXMS_EXPORTABLE nx_swscanf(const WCHAR *str, const WCHAR *format, ...);
+int LIBNETXMS_EXPORTABLE nx_vwscanf(const WCHAR *format, va_list args);
+int LIBNETXMS_EXPORTABLE nx_vfwscanf(FILE *fp, const WCHAR *format, va_list args);
+int LIBNETXMS_EXPORTABLE nx_vswscanf(const WCHAR *str, const WCHAR *format, va_list args);
 
 #endif /* _WIN32 */
 
-   WCHAR LIBNETXMS_EXPORTABLE *WideStringFromMBString(const char *pszString);
-       WCHAR LIBNETXMS_EXPORTABLE *WideStringFromUTF8String(const char *pszString);
-   char LIBNETXMS_EXPORTABLE *MBStringFromWideString(const WCHAR *pwszString);
-   char LIBNETXMS_EXPORTABLE *UTF8StringFromWideString(const WCHAR *pwszString);
+WCHAR LIBNETXMS_EXPORTABLE *WideStringFromMBString(const char *pszString);
+WCHAR LIBNETXMS_EXPORTABLE *WideStringFromUTF8String(const char *pszString);
+char LIBNETXMS_EXPORTABLE *MBStringFromWideString(const WCHAR *pwszString);
+char LIBNETXMS_EXPORTABLE *UTF8StringFromWideString(const WCHAR *pwszString);
 
 #ifdef _WITH_ENCRYPTION
-       WCHAR LIBNETXMS_EXPORTABLE *ERR_error_string_W(int nError, WCHAR *pwszBuffer);
+WCHAR LIBNETXMS_EXPORTABLE *ERR_error_string_W(int nError, WCHAR *pwszBuffer);
 #endif
 
 #ifdef UNICODE_UCS4
-       size_t LIBNETXMS_EXPORTABLE ucs2_to_ucs4(const UCS2CHAR *src, int srcLen, WCHAR *dst, int dstLen);
-       size_t LIBNETXMS_EXPORTABLE ucs4_to_ucs2(const WCHAR *src, int srcLen, UCS2CHAR *dst, int dstLen);
-       size_t LIBNETXMS_EXPORTABLE ucs2_to_utf8(const UCS2CHAR *src, int srcLen, char *dst, int dstLen);
-       UCS2CHAR LIBNETXMS_EXPORTABLE *UCS2StringFromUCS4String(const WCHAR *pwszString);
-       WCHAR LIBNETXMS_EXPORTABLE *UCS4StringFromUCS2String(const UCS2CHAR *pszString);
+size_t LIBNETXMS_EXPORTABLE ucs2_to_ucs4(const UCS2CHAR *src, int srcLen, WCHAR *dst, int dstLen);
+size_t LIBNETXMS_EXPORTABLE ucs4_to_ucs2(const WCHAR *src, int srcLen, UCS2CHAR *dst, int dstLen);
+size_t LIBNETXMS_EXPORTABLE ucs2_to_utf8(const UCS2CHAR *src, int srcLen, char *dst, int dstLen);
+UCS2CHAR LIBNETXMS_EXPORTABLE *UCS2StringFromUCS4String(const WCHAR *pwszString);
+WCHAR LIBNETXMS_EXPORTABLE *UCS4StringFromUCS2String(const UCS2CHAR *pszString);
 #endif
 
 #if !defined(_WIN32) && !HAVE_WSTAT
-       int wstat(const WCHAR *_path, struct stat *_sbuf);
+int wstat(const WCHAR *_path, struct stat *_sbuf);
 #endif
 
 #if defined(UNICODE) && !defined(_WIN32)
 
 #if !HAVE_WPOPEN
-       FILE LIBNETXMS_EXPORTABLE *wpopen(const WCHAR *_command, const WCHAR *_type);
+FILE LIBNETXMS_EXPORTABLE *wpopen(const WCHAR *_command, const WCHAR *_type);
 #endif
 #if !HAVE_WFOPEN
-       FILE LIBNETXMS_EXPORTABLE *wfopen(const WCHAR *_name, const WCHAR *_type);
+FILE LIBNETXMS_EXPORTABLE *wfopen(const WCHAR *_name, const WCHAR *_type);
 #endif
 #if HAVE_FOPEN64 && !HAVE_WFOPEN64
-       FILE LIBNETXMS_EXPORTABLE *wfopen64(const WCHAR *_name, const WCHAR *_type);
+FILE LIBNETXMS_EXPORTABLE *wfopen64(const WCHAR *_name, const WCHAR *_type);
 #endif
 #if !HAVE_WOPEN
-       int LIBNETXMS_EXPORTABLE wopen(const WCHAR *, int, ...);
+int LIBNETXMS_EXPORTABLE wopen(const WCHAR *, int, ...);
 #endif
 #if !HAVE_WCHMOD
-       int LIBNETXMS_EXPORTABLE wchmod(const WCHAR *_name, int mode);
+int LIBNETXMS_EXPORTABLE wchmod(const WCHAR *_name, int mode);
 #endif
 #if !HAVE_WCHDIR
-       int wchdir(const WCHAR *_path);
+int wchdir(const WCHAR *_path);
 #endif
 #if !HAVE_WMKDIR
-       int wmkdir(const WCHAR *_path, int mode);
+int wmkdir(const WCHAR *_path, int mode);
 #endif
 #if !HAVE_WRMDIR
-       int wrmdir(const WCHAR *_path);
+int wrmdir(const WCHAR *_path);
 #endif
 #if !HAVE_WRENAME
-       int wrename(const WCHAR *_oldpath, const WCHAR *_newpath);
+int wrename(const WCHAR *_oldpath, const WCHAR *_newpath);
 #endif
 #if !HAVE_WUNLINK
-       int wunlink(const WCHAR *_path);
+int wunlink(const WCHAR *_path);
 #endif
 #if !HAVE_WREMOVE
-       int wremove(const WCHAR *_path);
+int wremove(const WCHAR *_path);
 #endif
 #if !HAVE_WSYSTEM
-       int wsystem(const WCHAR *_cmd);
+int wsystem(const WCHAR *_cmd);
 #endif
 #if !HAVE_WMKSTEMP
-       int wmkstemp(WCHAR *_template);
+int wmkstemp(WCHAR *_template);
 #endif
 #if !HAVE_WACCESS
-       int waccess(const WCHAR *_path, int mode);
+int waccess(const WCHAR *_path, int mode);
 #endif
 #if !HAVE_WGETENV
-       WCHAR *wgetenv(const WCHAR *_string);
+WCHAR *wgetenv(const WCHAR *_string);
 #endif
 #if !HAVE_WCTIME
-       WCHAR *wctime(const time_t *timep);
+WCHAR *wctime(const time_t *timep);
 #endif
 #if !HAVE_PUTWS
-       int putws(const WCHAR *s);
+int putws(const WCHAR *s);
 #endif
 #if !HAVE_WCSERROR && HAVE_STRERROR
-       WCHAR *wcserror(int errnum);
+WCHAR *wcserror(int errnum);
 #endif
 #if !HAVE_WCSERROR_R && HAVE_STRERROR_R
 #if HAVE_POSIX_STRERROR_R
-       int wcserror_r(int errnum, WCHAR *strerrbuf, size_t buflen);
+int wcserror_r(int errnum, WCHAR *strerrbuf, size_t buflen);
 #else
-       WCHAR *wcserror_r(int errnum, WCHAR *strerrbuf, size_t buflen);
+WCHAR *wcserror_r(int errnum, WCHAR *strerrbuf, size_t buflen);
 #endif
 #endif
 
 #endif /* UNICODE && !_WIN32*/
 
 #if !HAVE_STRTOLL
-       INT64 LIBNETXMS_EXPORTABLE strtoll(const char *nptr, char **endptr, int base);
+INT64 LIBNETXMS_EXPORTABLE strtoll(const char *nptr, char **endptr, int base);
 #endif
 #if !HAVE_STRTOULL
-       UINT64 LIBNETXMS_EXPORTABLE strtoull(const char *nptr, char **endptr, int base);
+UINT64 LIBNETXMS_EXPORTABLE strtoull(const char *nptr, char **endptr, int base);
 #endif
 
 #if !HAVE_WCSTOLL
-       INT64 LIBNETXMS_EXPORTABLE wcstoll(const WCHAR *nptr, WCHAR **endptr, int base);
+INT64 LIBNETXMS_EXPORTABLE wcstoll(const WCHAR *nptr, WCHAR **endptr, int base);
 #endif
 #if !HAVE_WCSTOULL
-       UINT64 LIBNETXMS_EXPORTABLE wcstoull(const WCHAR *nptr, WCHAR **endptr, int base);
+UINT64 LIBNETXMS_EXPORTABLE wcstoull(const WCHAR *nptr, WCHAR **endptr, int base);
 #endif
 
 #if !HAVE_WCSLWR && !defined(_WIN32)
-       WCHAR LIBNETXMS_EXPORTABLE *wcslwr(WCHAR *str);
+WCHAR LIBNETXMS_EXPORTABLE *wcslwr(WCHAR *str);
 #endif
 
 #if !HAVE_WCSCASECMP && !defined(_WIN32)
-       int LIBNETXMS_EXPORTABLE wcscasecmp(const wchar_t *s1, const wchar_t *s2);
+int LIBNETXMS_EXPORTABLE wcscasecmp(const wchar_t *s1, const wchar_t *s2);
 #endif
 
 #if !HAVE_WCSNCASECMP && !defined(_WIN32)
-       int LIBNETXMS_EXPORTABLE wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n);
+int LIBNETXMS_EXPORTABLE wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n);
 #endif
 
 #ifdef _WIN32
 #ifdef UNICODE
-    DIRW LIBNETXMS_EXPORTABLE *wopendir(const WCHAR *filename);
-    struct dirent_w LIBNETXMS_EXPORTABLE *wreaddir(DIRW *dirp);
-    int LIBNETXMS_EXPORTABLE wclosedir(DIRW *dirp);
+DIRW LIBNETXMS_EXPORTABLE *wopendir(const WCHAR *filename);
+struct dirent_w LIBNETXMS_EXPORTABLE *wreaddir(DIRW *dirp);
+int LIBNETXMS_EXPORTABLE wclosedir(DIRW *dirp);
 
 #define _topendir wopendir
 #define _treaddir wreaddir
@@ -1332,23 +1400,23 @@ extern "C"
 #define _tclosedir closedir
 #endif
 
-    DIR LIBNETXMS_EXPORTABLE *opendir(const char *filename);
-    struct dirent LIBNETXMS_EXPORTABLE *readdir(DIR *dirp);
-    int LIBNETXMS_EXPORTABLE closedir(DIR *dirp);
+DIR LIBNETXMS_EXPORTABLE *opendir(const char *filename);
+struct dirent LIBNETXMS_EXPORTABLE *readdir(DIR *dirp);
+int LIBNETXMS_EXPORTABLE closedir(DIR *dirp);
 
 #else  /* not _WIN32 */
 
-    DIRW LIBNETXMS_EXPORTABLE *wopendir(const WCHAR *filename);
-    struct dirent_w LIBNETXMS_EXPORTABLE *wreaddir(DIRW *dirp);
-    int LIBNETXMS_EXPORTABLE wclosedir(DIRW *dirp);
+DIRW LIBNETXMS_EXPORTABLE *wopendir(const WCHAR *filename);
+struct dirent_w LIBNETXMS_EXPORTABLE *wreaddir(DIRW *dirp);
+int LIBNETXMS_EXPORTABLE wclosedir(DIRW *dirp);
 
 #endif
 
 #if defined(_WIN32) || !(HAVE_SCANDIR)
-   int LIBNETXMS_EXPORTABLE scandir(const char *dir, struct dirent ***namelist,
-               int (*select)(const struct dirent *),
-               int (*compar)(const struct dirent **, const struct dirent **));
-   int LIBNETXMS_EXPORTABLE alphasort(const struct dirent **a, const struct dirent **b);
+int LIBNETXMS_EXPORTABLE scandir(const char *dir, struct dirent ***namelist,
+              int (*select)(const struct dirent *),
+              int (*compar)(const struct dirent **, const struct dirent **));
+int LIBNETXMS_EXPORTABLE alphasort(const struct dirent **a, const struct dirent **b);
 #endif
 
 TCHAR LIBNETXMS_EXPORTABLE *safe_fgetts(TCHAR *buffer, int len, FILE *f);
index 13d4ddc..53f8890 100644 (file)
@@ -791,6 +791,7 @@ enum
 #define DS_PUSH_AGENT         4
 #define DS_WINPERF            5
 #define DS_SMCLP              6
+#define DS_SCRIPT             7
 
 /**
  * Item status
@@ -1959,11 +1960,9 @@ typedef struct
        TCHAR privPassword[MAX_DB_STRING];
 } NXC_SNMP_USM_CRED;
 
-
-//
-// Connection point information
-//
-
+/**
+ * Connection point information
+ */
 typedef struct
 {
        UINT32 localNodeId;
@@ -1975,43 +1974,62 @@ typedef struct
 } NXC_CONNECTION_POINT;
 
 
-// All situation stuff will be available only in C++
 #ifdef __cplusplus
 
-//
-// Situation instance
-//
-
-typedef struct
+/**
+ * Situation instance
+ */
+struct NXC_SITUATION_INSTANCE
 {
        TCHAR *m_name;
        StringMap *m_attrList;
-} NXC_SITUATION_INSTANCE;
-
-
-//
-// Situation
-//
+};
 
-typedef struct
+/**
+ * Situation
+ */
+struct NXC_SITUATION
 {
        UINT32 m_id;
        TCHAR *m_name;
        TCHAR *m_comments;
        int m_instanceCount;
        NXC_SITUATION_INSTANCE *m_instanceList;
-} NXC_SITUATION;
-
-
-//
-// Situation list
-//
+};
 
-typedef struct
+/**
+ * Situation list
+ */
+struct NXC_SITUATION_LIST
 {
        int m_count;
        NXC_SITUATION *m_situations;
-} NXC_SITUATION_LIST;
+};
+
+/**
+ * Alarm comments
+ */
+class LIBNXCL_EXPORTABLE AlarmComment
+{
+private:
+   UINT32 m_id;
+   UINT32 m_alarmId;
+   UINT32 m_userId;
+   TCHAR *m_userName;
+   time_t m_timestamp;
+   TCHAR *m_text;
+
+public:
+   AlarmComment(CSCPMessage *msg, UINT32 baseId);
+   ~AlarmComment();
+
+   UINT32 getId() { return m_id; }
+   UINT32 getAlarmId() { return m_alarmId; }
+   UINT32 getUserId() { return m_userId; }
+   const TCHAR *getUserName() { return m_userName; }
+   time_t getTimestamp() { return m_timestamp; }
+   const TCHAR *getText() { return m_text; }
+};
 
 #endif /* __cplusplus */
 
@@ -2231,6 +2249,11 @@ UINT32 LIBNXCL_EXPORTABLE NXCTerminateAlarm(NXC_SESSION hSession, UINT32 dwAlarm
 UINT32 LIBNXCL_EXPORTABLE NXCDeleteAlarm(NXC_SESSION hSession, UINT32 dwAlarmId);
 UINT32 LIBNXCL_EXPORTABLE NXCOpenHelpdeskIssue(NXC_SESSION hSession, UINT32 dwAlarmId, TCHAR *pszHelpdeskRef);
 TCHAR LIBNXCL_EXPORTABLE *NXCFormatAlarmText(NXC_SESSION session, NXC_ALARM *alarm, TCHAR *format);
+UINT32 LIBNXCL_EXPORTABLE NXCAddAlarmComment(NXC_SESSION hSession, UINT32 alarmId, const TCHAR *text);
+UINT32 LIBNXCL_EXPORTABLE NXCUpdateAlarmComment(NXC_SESSION hSession, UINT32 alarmId, UINT32 commentId, const TCHAR *text);
+#ifdef __cplusplus
+UINT32 LIBNXCL_EXPORTABLE NXCGetAlarmComments(NXC_SESSION hSession, UINT32 alarmId, ObjectArray<AlarmComment> **comments);
+#endif
 
 /** Actions **/
 UINT32 LIBNXCL_EXPORTABLE NXCLoadActions(NXC_SESSION hSession, UINT32 *pdwNumActions, NXC_ACTION **ppActionList);
index e40cec7..ea89354 100644 (file)
@@ -69,6 +69,7 @@ public:
        bool getValueAsUUID(int index, uuid_t uuid);
 
        void addValue(const TCHAR *value);
+       void addValuePreallocated(TCHAR *value);
        void setValue(const TCHAR*value);
 
        const TCHAR *getSubEntryValue(const TCHAR *name, int index = 0, const TCHAR *defaultValue = NULL);
index b8c7048..322b292 100644 (file)
@@ -103,7 +103,7 @@ public:
 #endif
    void setFieldInt32Array(UINT32 dwVarId, UINT32 dwNumElements, const UINT32 *pdwData);
    void setFieldInt32Array(UINT32 dwVarId, IntegerArray<UINT32> *data);
-   BOOL SetVariableFromFile(UINT32 dwVarId, const TCHAR *pszFileName);
+   bool setFieldFromFile(UINT32 dwVarId, const TCHAR *pszFileName);
 
    INT16 getFieldAsInt16(UINT32 fieldId);
    INT32 getFieldAsInt32(UINT32 fieldId);
index e8e0b2d..6a0c80a 100644 (file)
 #define MAX_DB_PASSWORD       64
 #define MAX_DB_NAME           256
 
-
-//
-// DB events
-//
-
+/**
+ * DB events
+ */
 #define DBEVENT_CONNECTION_LOST        0
 #define DBEVENT_CONNECTION_RESTORED    1
 #define DBEVENT_QUERY_FAILED           2
index 23d6fc9..bd1faec 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
 ** NetXMS - Network Management System
 ** Copyright (C) 2003-2012 Victor Kirhenshtein
 **
 #define EVENT_AP_ADOPTED                  72
 #define EVENT_AP_UNADOPTED                73
 #define EVENT_AP_DOWN                     74
+#define EVENT_IF_MASK_CHANGED             75
 
 #define EVENT_SNMP_UNMATCHED_TRAP         500
 #define EVENT_SNMP_COLD_START             501
index 6c5ebd1..519047d 100644 (file)
@@ -544,6 +544,9 @@ struct NXSL_CatchPoint
  */
 class LIBNXSL_EXPORTABLE NXSL_VM
 {
+private:
+   static bool createConstantsCallback(const TCHAR *key, const void *value, void *data);
+
 protected:
    NXSL_Environment *m_env;
        void *m_userData;
@@ -557,9 +560,9 @@ protected:
    NXSL_Stack *m_catchStack;
    int m_nBindPos;
 
-   NXSL_VariableSystem *m_pConstants;
-   NXSL_VariableSystem *m_pGlobals;
-   NXSL_VariableSystem *m_pLocals;
+   NXSL_VariableSystem *m_constants;
+   NXSL_VariableSystem *m_globals;
+   NXSL_VariableSystem *m_locals;
 
    ObjectArray<NXSL_Function> *m_functions;
    ObjectArray<NXSL_Module> *m_modules;
@@ -591,12 +594,16 @@ public:
    void loadModule(NXSL_Program *module, const TCHAR *name);
 
        void setGlobalVariable(const TCHAR *pszName, NXSL_Value *pValue);
-       NXSL_Variable *findGlobalVariable(const TCHAR *pszName) { return m_pGlobals->find(pszName); }
+       NXSL_Variable *findGlobalVariable(const TCHAR *pszName) { return m_globals->find(pszName); }
 
    bool load(NXSL_Program *program);
-   bool run(UINT32 argc = 0, NXSL_Value **argv = NULL, NXSL_VariableSystem *pUserLocals = NULL,
+   bool run(ObjectArray<NXSL_Value> *args, NXSL_VariableSystem *pUserLocals = NULL,
+            NXSL_VariableSystem **ppGlobals = NULL, NXSL_VariableSystem *pConstants = NULL,
+            const TCHAR *entryPoint = NULL);
+   bool run(int argc, NXSL_Value **argv, NXSL_VariableSystem *pUserLocals = NULL,
             NXSL_VariableSystem **ppGlobals = NULL, NXSL_VariableSystem *pConstants = NULL,
             const TCHAR *entryPoint = NULL);
+   bool run() { ObjectArray<NXSL_Value> args(1, 1, false); return run(&args); }
 
    UINT32 getCodeSize() { return m_instructionSet->size(); }
 
index aac41fb..b742260 100644 (file)
@@ -452,8 +452,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "catalyst", "src\server\driv
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "oracle", "src\agent\subagents\oracle\oracle.vcproj", "{90B762AB-B7BA-42D6-9819-C687AB3F59D0}"
        ProjectSection(ProjectDependencies) = postProject
-               {B1745870-F3ED-4ACB-B813-0C4F47EF0793} = {B1745870-F3ED-4ACB-B813-0C4F47EF0793}
                {F3E29541-3A0E-45EC-8BEC-E193F2401622} = {F3E29541-3A0E-45EC-8BEC-E193F2401622}
+               {406AE5C7-343D-4C88-B8F3-84E46255B830} = {406AE5C7-343D-4C88-B8F3-84E46255B830}
+               {B1745870-F3ED-4ACB-B813-0C4F47EF0793} = {B1745870-F3ED-4ACB-B813-0C4F47EF0793}
        EndProjectSection
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{896A7CDA-423A-460A-83E2-6ED37DAE187C}"
@@ -636,6 +637,33 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "filemgr", "src\agent\subage
                {B1745870-F3ED-4ACB-B813-0C4F47EF0793} = {B1745870-F3ED-4ACB-B813-0C4F47EF0793}
        EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpng", "src\libpng\libpng.vcproj", "{C1A5E28A-CF47-4D96-9656-3312F16E3724}"
+       ProjectSection(ProjectDependencies) = postProject
+               {E7410EB4-3355-4C83-8E05-D2877581CDA1} = {E7410EB4-3355-4C83-8E05-D2877581CDA1}
+       EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nxsagent", "src\agent\nxsagent\nxsagent.vcproj", "{9C6790BA-385D-476D-944A-552C87018733}"
+       ProjectSection(ProjectDependencies) = postProject
+               {C1A5E28A-CF47-4D96-9656-3312F16E3724} = {C1A5E28A-CF47-4D96-9656-3312F16E3724}
+               {B1745870-F3ED-4ACB-B813-0C4F47EF0793} = {B1745870-F3ED-4ACB-B813-0C4F47EF0793}
+       EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{6FC2F162-5E91-47D7-AE00-45C595ED8C85}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-libnetxms", "tests\test-libnetxms\test-libnetxms.vcproj", "{8DD0AA99-52B2-4680-8CB5-89556B566177}"
+       ProjectSection(ProjectDependencies) = postProject
+               {B1745870-F3ED-4ACB-B813-0C4F47EF0793} = {B1745870-F3ED-4ACB-B813-0C4F47EF0793}
+       EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "pds-drivers", "pds-drivers", "{7C6DD495-5A44-4D50-B065-A8CA120272F7}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rrdtool", "src\server\pdsdrv\rrdtool\rrdtool.vcproj", "{1B7CA1B1-C702-49D7-8339-7FF82B188D32}"
+       ProjectSection(ProjectDependencies) = postProject
+               {CB89D905-C8BE-4027-B2D8-F96C245E9160} = {CB89D905-C8BE-4027-B2D8-F96C245E9160}
+               {3B172035-5EEC-45A3-8471-2C390B7ED683} = {3B172035-5EEC-45A3-8471-2C390B7ED683}
+               {B1745870-F3ED-4ACB-B813-0C4F47EF0793} = {B1745870-F3ED-4ACB-B813-0C4F47EF0793}
+       EndProjectSection
+EndProject
 Global
        GlobalSection(SolutionConfigurationPlatforms) = preSolution
                Debug|Win32 = Debug|Win32
@@ -1468,6 +1496,38 @@ Global
                {BBE9028E-725C-45C6-97C9-BFC443F19EA8}.Release|Win32.Build.0 = Release|Win32
                {BBE9028E-725C-45C6-97C9-BFC443F19EA8}.Release|x64.ActiveCfg = Release|x64
                {BBE9028E-725C-45C6-97C9-BFC443F19EA8}.Release|x64.Build.0 = Release|x64
+               {C1A5E28A-CF47-4D96-9656-3312F16E3724}.Debug|Win32.ActiveCfg = Debug|Win32
+               {C1A5E28A-CF47-4D96-9656-3312F16E3724}.Debug|Win32.Build.0 = Debug|Win32
+               {C1A5E28A-CF47-4D96-9656-3312F16E3724}.Debug|x64.ActiveCfg = Debug|x64
+               {C1A5E28A-CF47-4D96-9656-3312F16E3724}.Debug|x64.Build.0 = Debug|x64
+               {C1A5E28A-CF47-4D96-9656-3312F16E3724}.Release|Win32.ActiveCfg = Release|Win32
+               {C1A5E28A-CF47-4D96-9656-3312F16E3724}.Release|Win32.Build.0 = Release|Win32
+               {C1A5E28A-CF47-4D96-9656-3312F16E3724}.Release|x64.ActiveCfg = Release|x64
+               {C1A5E28A-CF47-4D96-9656-3312F16E3724}.Release|x64.Build.0 = Release|x64
+               {9C6790BA-385D-476D-944A-552C87018733}.Debug|Win32.ActiveCfg = Debug|Win32
+               {9C6790BA-385D-476D-944A-552C87018733}.Debug|Win32.Build.0 = Debug|Win32
+               {9C6790BA-385D-476D-944A-552C87018733}.Debug|x64.ActiveCfg = Debug|x64
+               {9C6790BA-385D-476D-944A-552C87018733}.Debug|x64.Build.0 = Debug|x64
+               {9C6790BA-385D-476D-944A-552C87018733}.Release|Win32.ActiveCfg = Release|Win32
+               {9C6790BA-385D-476D-944A-552C87018733}.Release|Win32.Build.0 = Release|Win32
+               {9C6790BA-385D-476D-944A-552C87018733}.Release|x64.ActiveCfg = Release|x64
+               {9C6790BA-385D-476D-944A-552C87018733}.Release|x64.Build.0 = Release|x64
+               {8DD0AA99-52B2-4680-8CB5-89556B566177}.Debug|Win32.ActiveCfg = Debug|Win32
+               {8DD0AA99-52B2-4680-8CB5-89556B566177}.Debug|Win32.Build.0 = Debug|Win32
+               {8DD0AA99-52B2-4680-8CB5-89556B566177}.Debug|x64.ActiveCfg = Debug|x64
+               {8DD0AA99-52B2-4680-8CB5-89556B566177}.Debug|x64.Build.0 = Debug|x64
+               {8DD0AA99-52B2-4680-8CB5-89556B566177}.Release|Win32.ActiveCfg = Release|Win32
+               {8DD0AA99-52B2-4680-8CB5-89556B566177}.Release|Win32.Build.0 = Release|Win32
+               {8DD0AA99-52B2-4680-8CB5-89556B566177}.Release|x64.ActiveCfg = Release|x64
+               {8DD0AA99-52B2-4680-8CB5-89556B566177}.Release|x64.Build.0 = Release|x64
+               {1B7CA1B1-C702-49D7-8339-7FF82B188D32}.Debug|Win32.ActiveCfg = Debug|Win32
+               {1B7CA1B1-C702-49D7-8339-7FF82B188D32}.Debug|Win32.Build.0 = Debug|Win32
+               {1B7CA1B1-C702-49D7-8339-7FF82B188D32}.Debug|x64.ActiveCfg = Debug|x64
+               {1B7CA1B1-C702-49D7-8339-7FF82B188D32}.Debug|x64.Build.0 = Debug|x64
+               {1B7CA1B1-C702-49D7-8339-7FF82B188D32}.Release|Win32.ActiveCfg = Release|Win32
+               {1B7CA1B1-C702-49D7-8339-7FF82B188D32}.Release|Win32.Build.0 = Release|Win32
+               {1B7CA1B1-C702-49D7-8339-7FF82B188D32}.Release|x64.ActiveCfg = Release|x64
+               {1B7CA1B1-C702-49D7-8339-7FF82B188D32}.Release|x64.Build.0 = Release|x64
        EndGlobalSection
        GlobalSection(SolutionProperties) = preSolution
                HideSolutionNode = FALSE
@@ -1484,11 +1544,13 @@ Global
                {C6F495E0-71D7-4B7E-AC3A-ABBEFBFFD2DF} = {71683564-472B-4216-BA74-0F34BC843D92}
                {F4169894-5C48-4E11-A82E-1055F9572EEF} = {71683564-472B-4216-BA74-0F34BC843D92}
                {12D6E037-84D8-406A-8A9B-3E00D3E0D426} = {71683564-472B-4216-BA74-0F34BC843D92}
+               {C1A5E28A-CF47-4D96-9656-3312F16E3724} = {71683564-472B-4216-BA74-0F34BC843D92}
                {451F583D-C2DB-4414-870C-7FA0189BE7DD} = {8BC9D64D-347C-41BE-A506-D21C8FB72D56}
                {57598B02-3295-4FE8-9322-94CE871CC84D} = {8BC9D64D-347C-41BE-A506-D21C8FB72D56}
                {896A7CDA-423A-460A-83E2-6ED37DAE187C} = {8BC9D64D-347C-41BE-A506-D21C8FB72D56}
                {DFE2F1AF-D5E5-49DD-B2AD-4F4FB8651D8A} = {8BC9D64D-347C-41BE-A506-D21C8FB72D56}
                {6B249E47-4BAF-4DE2-B62B-C6DD0330753F} = {8BC9D64D-347C-41BE-A506-D21C8FB72D56}
+               {9C6790BA-385D-476D-944A-552C87018733} = {8BC9D64D-347C-41BE-A506-D21C8FB72D56}
                {E95263B5-A248-4163-95F3-E33CA679AEB3} = {451F583D-C2DB-4414-870C-7FA0189BE7DD}
                {EE54BC06-6B0F-4B91-9FC6-A5BB9ECBE577} = {451F583D-C2DB-4414-870C-7FA0189BE7DD}
                {4E190DD5-70DA-41EC-8D05-5EE8D74F3709} = {451F583D-C2DB-4414-870C-7FA0189BE7DD}
@@ -1509,11 +1571,12 @@ Global
                {BBE9028E-725C-45C6-97C9-BFC443F19EA8} = {451F583D-C2DB-4414-870C-7FA0189BE7DD}
                {CB89D905-C8BE-4027-B2D8-F96C245E9160} = {B93920F5-65F4-4531-B87E-A5B357AF2476}
                {3B172035-5EEC-45A3-8471-2C390B7ED683} = {B93920F5-65F4-4531-B87E-A5B357AF2476}
-               {E417A0C4-41F1-4F87-8C33-8526ECB1F8AF} = {B93920F5-65F4-4531-B87E-A5B357AF2476}
                {64482674-7B36-4A14-A612-247333174315} = {B93920F5-65F4-4531-B87E-A5B357AF2476}
                {5818CCA9-B585-44B8-B29E-98B1DC278A3C} = {B93920F5-65F4-4531-B87E-A5B357AF2476}
                {53997B2A-D94C-428C-816D-938C297A1866} = {B93920F5-65F4-4531-B87E-A5B357AF2476}
                {80EB59BF-5CEC-4248-BF3B-7C30E67063B8} = {B93920F5-65F4-4531-B87E-A5B357AF2476}
+               {7C6DD495-5A44-4D50-B065-A8CA120272F7} = {B93920F5-65F4-4531-B87E-A5B357AF2476}
+               {E417A0C4-41F1-4F87-8C33-8526ECB1F8AF} = {B93920F5-65F4-4531-B87E-A5B357AF2476}
                {7DC90EE4-E31C-4F12-8F1E-81F10E9099FB} = {268BC97D-BFC6-4BD7-BF78-E6AC1D8BA37E}
                {0A4CE471-020A-42C6-91C0-DFEFA7E815E0} = {268BC97D-BFC6-4BD7-BF78-E6AC1D8BA37E}
                {9EA98E79-EB7D-4F6C-8105-AC7B231ABB10} = {268BC97D-BFC6-4BD7-BF78-E6AC1D8BA37E}
@@ -1586,5 +1649,7 @@ Global
                {68B9F17F-A292-4DAB-8EA9-B87473BB0436} = {896A7CDA-423A-460A-83E2-6ED37DAE187C}
                {21D35413-495C-4DD2-BDBF-7BD708C70B74} = {896A7CDA-423A-460A-83E2-6ED37DAE187C}
                {01924916-D158-4370-97C8-D17B8D2A7D4E} = {80EB59BF-5CEC-4248-BF3B-7C30E67063B8}
+               {8DD0AA99-52B2-4680-8CB5-89556B566177} = {6FC2F162-5E91-47D7-AE00-45C595ED8C85}
+               {1B7CA1B1-C702-49D7-8339-7FF82B188D32} = {7C6DD495-5A44-4D50-B065-A8CA120272F7}
        EndGlobalSection
 EndGlobal
index 1df54e6..7d81acc 100755 (executable)
@@ -9,7 +9,7 @@
 # to use the same script.
 
 getproparg() {
-        val=`svcprop -p $1 $SMF_FMRI`
+        val=`svcprop -p $1 $SMF_FMRI 2>/dev/null`
         [ -n "$val" ] && echo $val
 }
 
@@ -29,11 +29,11 @@ if [ -z $SMF_FMRI ]; then
 fi
 
 if [ x"$CONFIGFILE" != "x" ]; then
-       ARGS=$ARGS -c \"$CONFIGFILE\"
+       ARGS="$ARGS -c $CONFIGFILE"
 fi
 
 if [ x"$DEBUGLEVEL" != "x" ]; then
-       ARGS=$ARGS -D $DEBUGLEVEL
+       ARGS="$ARGS -D $DEBUGLEVEL"
 fi
 
 case "$1" in
@@ -42,7 +42,7 @@ case "$1" in
         ;;
 
 'stop')
-       pkill nxagentd
+       pkill -f $NXBIN/nxagentd
         ;;
 
 *)
index 1cc1136..5fa7c78 100644 (file)
@@ -5,7 +5,6 @@ ARCH="sparc"
 CLASSES="none"
 CATEGORY="system"
 VENDOR="Raden Solutions"
-PSTAMP="21thJul13"
 EMAIL="info@netxms.org"
 ISTATES="S s 1 2 3"
 RSTATES="S s 1 2 3"
index 7f3ab61..fefcd52 100644 (file)
@@ -1,3 +1,4 @@
 #!/bin/sh
 
 svccfg import /var/svc/manifest/application/management/nxagentd.xml
+svcadm enable nxagentd || true
index 0ae4bf9..96a8dc1 100644 (file)
@@ -8,5 +8,7 @@ fi
 svcs nxagentd >/dev/null 2>&1
 if [ $? = 0 ]; then
        svcadm disable nxagentd
-       svccfg delete nxagentd
+       if [ x"$UPDATE" != "xyes" ]; then
+               svccfg delete nxagentd
+       fi
 fi
index c47a905..3736f12 100644 (file)
@@ -2,6 +2,8 @@
 
 svcs nxagentd >/dev/null 2>&1
 if [ $? = 0 ]; then
-       svcadm disable nxagentd
-       svccfg delete nxagentd
+       svcadm disable -s -t nxagentd
+       if [ x"$UPDATE" != "xyes" ]; then
+               svccfg delete nxagentd
+       fi
 fi
index f6594e8..1bb02d5 100644 (file)
@@ -10,7 +10,7 @@ endif
 all: package
 
 package:
-       mkdir /opt/netxms/svc
+       mkdir -p /opt/netxms/svc
        cp files/netxmsd.xml /var/svc/manifest/application/management/
        cp ../agent/files/nxagentd.xml /var/svc/manifest/application/management/
        cp files/netxmsd /opt/netxms/svc/
index e95c183..143408e 100755 (executable)
@@ -11,7 +11,7 @@ if [ -z $SMF_FMRI ]; then
 fi
 
 getproparg() {
-    val=`svcprop -p $1 $SMF_FMRI`
+    val=`svcprop -p $1 $SMF_FMRI 2>/dev/null`
     [ -n "$val" ] && echo $val
 }
 
@@ -26,7 +26,7 @@ if [ -f $NXBIN/nxenv ]; then
 fi
 
 if [ x"$CONFIGFILE" != "x" ]; then
-    ARGS="$ARGS -c \"$CONFIGFILE\""
+    ARGS="$ARGS -c $CONFIGFILE"
 fi
 
 if [ x"$DEBUGLEVEL" != "x" ]; then
@@ -39,7 +39,7 @@ case "$1" in
         ;;
 
     'stop')
-        pkill netxmsd
+        pkill -f $NXBIN/netxmsd
         ;;
 
     *)
index bc797e2..97e0184 100644 (file)
 
                 <property_group name='netxms' type='application'>
                         <propval name='bin' type='astring' value='/opt/netxms/bin' />
+                       <!--
                         <propval name='server_config' type='astring' value='' />
                         <propval name='server_debuglevel' type='integer' value='' />
+                       -->
                         <propval name='value_authorization' type='astring' value='solaris.smf.value.netxms' />
                 </property_group>
         </instance>
index 4b69fae..e46ade0 100644 (file)
@@ -5,7 +5,6 @@ ARCH="sparc"
 CLASSES="none"
 CATEGORY="system"
 VENDOR="Raden Solutions"
-PSTAMP="27thSep13"
 EMAIL="info@netxms.org"
 ISTATES="S s 1 2 3"
 RSTATES="S s 1 2 3"
index 36c0396..dc4a724 100644 (file)
@@ -2,3 +2,5 @@
 
 svccfg import /var/svc/manifest/application/management/nxagentd.xml
 svccfg import /var/svc/manifest/application/management/netxmsd.xml
+svcadm enable nxagentd || true
+svcadm enable netxmsd || true
\ No newline at end of file
index 7d2d747..ecf9053 100644 (file)
@@ -1,5 +1,6 @@
 #!/bin/sh
 
+# remove legacy stuff
 if test -x /etc/init.d/netxmsd; then
        /etc/init.d/netxmsd stop
        rm -f /etc/init.d/netxmsd
@@ -8,3 +9,20 @@ if test -x /etc/init.d/nxagentd; then
        /etc/init.d/nxagentd stop
        rm -f /etc/init.d/nxagentd
 fi
+
+# stop services
+svcs netxmsd >/dev/null 2>&1
+if [ $? = 0 ]; then
+       svcadm disable -s -t netxmsd
+       if [ x"$UPDATE" != "xyes" ]; then
+               svccfg delete netxmsd
+       fi
+fi
+
+svcs nxagentd >/dev/null 2>&1
+if [ $? = 0 ]; then
+       svcadm disable -s -t nxagentd
+       if [ x"$UPDATE" != "xyes" ]; then
+               svccfg delete nxagentd
+       fi
+fi
index 686c39c..b07d416 100644 (file)
@@ -2,12 +2,16 @@
 
 svcs netxmsd >/dev/null 2>&1
 if [ $? = 0 ]; then
-       svcadm disable netxmsd
-       svccfg delete netxmsd
+       svcadm disable -s -t netxmsd
+       if [ x"$UPDATE" != "xyes" ]; then
+               svccfg delete netxmsd
+       fi
 fi
 
 svcs nxagentd >/dev/null 2>&1
 if [ $? = 0 ]; then
-       svcadm disable nxagentd
-       svccfg delete nxagentd
+       svcadm disable -s -t nxagentd
+       if [ x"$UPDATE" != "xyes" ]; then
+               svccfg delete nxagentd
+       fi
 fi
index 04c67a1..87efa37 100644 (file)
@@ -162,7 +162,7 @@ INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description)
        );
 INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description) VALUES
        (
-               EVENT_NODE_WARNING, 'SYS_NODE_WARNING', 
+               EVENT_NODE_WARNING, 'SYS_NODE_WARNING',
                EVENT_SEVERITY_WARNING, 1,
                'Node status changed to WARNING',
                'Generated when node status changed to "Warning".' CONCAT CRLF CONCAT
@@ -180,7 +180,7 @@ INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description)
        );
 INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description) VALUES
        (
-               EVENT_NODE_MAJOR, 'SYS_NODE_MAJOR', 
+               EVENT_NODE_MAJOR, 'SYS_NODE_MAJOR',
                EVENT_SEVERITY_MAJOR, 1,
                'Node status changed to MAJOR',
                'Generated when node status changed to "Major Problem".' CONCAT CRLF CONCAT
@@ -189,7 +189,7 @@ INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description)
        );
 INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description) VALUES
        (
-               EVENT_NODE_CRITICAL, 'SYS_NODE_CRITICAL', 
+               EVENT_NODE_CRITICAL, 'SYS_NODE_CRITICAL',
                EVENT_SEVERITY_CRITICAL, 1,
                'Node status changed to CRITICAL',
                'Generated when node status changed to critical.' CONCAT CRLF CONCAT
@@ -226,7 +226,7 @@ INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description)
        );
 INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description) VALUES
        (
-               EVENT_SNMP_FAIL, 'SYS_SNMP_UNREACHABLE', 
+               EVENT_SNMP_FAIL, 'SYS_SNMP_UNREACHABLE',
                EVENT_SEVERITY_WARNING, 1,
                'SNMP agent is not responding',
                'Generated when node''s SNMP agent is not responding.' CONCAT CRLF CONCAT
@@ -292,7 +292,7 @@ INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description)
        );
 INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description) VALUES
        (
-               EVENT_THREAD_HANGS, 'SYS_THREAD_HANG', 
+               EVENT_THREAD_HANGS, 'SYS_THREAD_HANG',
                EVENT_SEVERITY_CRITICAL, 1,
                'Thread "%1" is not responding',
                'Generated when one of the system threads hangs or stops unexpectedly.' CONCAT CRLF CONCAT
@@ -310,7 +310,7 @@ INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description)
        );
 INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description) VALUES
        (
-               EVENT_SMTP_FAILURE, 'SYS_SMTP_FAILURE', 
+               EVENT_SMTP_FAILURE, 'SYS_SMTP_FAILURE',
                EVENT_SEVERITY_WARNING, 1,
                'Unable to send e-mail to <%3>: %2',
                'Generated when server is unable to send e-mail.' CONCAT CRLF CONCAT
@@ -322,7 +322,7 @@ INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description)
        );
 INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description) VALUES
        (
-               EVENT_MAC_ADDR_CHANGED, 'SYS_MAC_ADDR_CHANGED', 
+               EVENT_MAC_ADDR_CHANGED, 'SYS_MAC_ADDR_CHANGED',
                EVENT_SEVERITY_WARNING, 1,
                'MAC address for interface %3 changed from %4 to %5',
                'Generated when server detects change of interface''s MAC address.' CONCAT CRLF CONCAT
@@ -335,7 +335,7 @@ INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description)
        );
 INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description) VALUES
        (
-               EVENT_INCORRECT_NETMASK, 'SYS_INCORRECT_NETMASK', 
+               EVENT_INCORRECT_NETMASK, 'SYS_INCORRECT_NETMASK',
                EVENT_SEVERITY_MINOR, 1,
                'Invalid network mask %4 on interface "%3", should be %5',
                'Generated when server detects invalid network mask on an interface.' CONCAT CRLF CONCAT
@@ -399,7 +399,7 @@ INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description)
        );
 INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description) VALUES
        (
-               EVENT_SMS_FAILURE, 'SYS_SMS_FAILURE', 
+               EVENT_SMS_FAILURE, 'SYS_SMS_FAILURE',
                EVENT_SEVERITY_WARNING, 1,
                'Unable to send SMS to phone %1',
                'Generated when server is unable to send SMS.' CONCAT CRLF CONCAT
@@ -867,6 +867,21 @@ INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description)
                '    7) Access point serial number'
        );
 
+   INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description) VALUES
+      (
+         EVENT_IF_MASK_CHANGED, 'SYS_IF_MASK_CHANGED',
+         EVENT_SEVERITY_NORMAL, 1,
+         'Interface "%2" changed mask from %6 to %4 (IP Addr: %3/%4, IfIndex: %5)',
+         'Generated when when network mask on interface is corrected.' CONCAT CRLF CONCAT
+         'Parameters:' CONCAT CRLF CONCAT
+         '   1) Interface object ID' CONCAT CRLF CONCAT
+         '   2) Interface name' CONCAT CRLF CONCAT
+         '   3) Interface IP address' CONCAT CRLF CONCAT
+         '   4) Interface netmask' CONCAT CRLF CONCAT
+         '   5) Interface index' CONCAT CRLF CONCAT
+         '   6) Interface old mask'
+      );
+
 /*
 ** SNMP traps
 */
index 98b4d01..b8d7aef 100644 (file)
@@ -81,8 +81,8 @@ CREATE TABLE user_groups
        name varchar(63) not null,
        system_access SQL_INT64 not null,
        flags integer not null,
-       description varchar(255) not null,
-   ldap_dn SQL_TEXT null,
+       description varchar(255),
+       ldap_dn SQL_TEXT null,
        PRIMARY KEY(id)
 ) TABLE_TYPE;
 
@@ -1294,8 +1294,8 @@ CREATE TABLE network_map_links
        element2 integer not null,
        link_type integer not null,
        link_name varchar(255) null,
-       connector_name1 varchar(63) null,
-       connector_name2 varchar(63) null,
+       connector_name1 varchar(255) null,
+       connector_name2 varchar(255) null,
        element_data SQL_TEXT null,
        flags integer not null
 ) TABLE_TYPE;
index d5f671e..769e086 100644 (file)
@@ -147,6 +147,7 @@ INSERT INTO config (var_name,var_value,is_visible,need_server_restart) VALUES ('
 INSERT INTO config (var_name,var_value,is_visible,need_server_restart) VALUES ('SyncInterval','60',1,1);
 INSERT INTO config (var_name,var_value,is_visible,need_server_restart) VALUES ('SyncNodeNamesWithDNS','0',1,0);
 INSERT INTO config (var_name,var_value,is_visible,need_server_restart) VALUES ('SyslogListenPort','514',1,1);
+INSERT INTO config (var_name,var_value,is_visible,need_server_restart) VALUES ('SyslogNodeMatchingPolicy','0',1,1);
 INSERT INTO config (var_name,var_value,is_visible,need_server_restart) VALUES ('SyslogRetentionTime','90',1,0);
 INSERT INTO config (var_name,var_value,is_visible,need_server_restart) VALUES ('ThresholdRepeatInterval','0',1,1);
 INSERT INTO config (var_name,var_value,is_visible,need_server_restart) VALUES ('TileServerURL','http://tile.openstreetmap.org/',1,0);
index 78017dc..e8c698f 100644 (file)
@@ -2,9 +2,10 @@ AM_CPPFLAGS=-I@top_srcdir@/include
 bin_PROGRAMS = nxagentd
 nxagentd_SOURCES = messages.c actions.cpp appagent.cpp comm.cpp config.cpp \
                    ctrl.cpp epp.cpp exec.cpp extagent.cpp getparam.cpp \
-                   master.cpp nxagentd.cpp policy.cpp push.cpp register.cpp sd.cpp \
-                   session.cpp snmpproxy.cpp static_subagents.cpp subagent.cpp \
-                   sysinfo.cpp tools.cpp trap.cpp upgrade.cpp watchdog.cpp
+                   master.cpp nxagentd.cpp policy.cpp push.cpp register.cpp \
+                   sa.cpp sd.cpp session.cpp snmpproxy.cpp \
+                   static_subagents.cpp subagent.cpp sysinfo.cpp tools.cpp \
+                   trap.cpp upgrade.cpp watchdog.cpp
 if USE_INTERNAL_EXPAT
 nxagentd_LDADD = ../appagent/libappagent.la @top_srcdir@/src/db/libnxdb/libnxdb.la @top_srcdir@/src/libnetxms/libnetxms.la @top_srcdir@/src/libexpat/libexpat/libnxexpat.la @SUBAGENT_LIBS@
 else
index 6a053b4..081d139 100644 (file)
@@ -1,6 +1,6 @@
 /* 
 ** NetXMS multiplatform core agent
-** Copyright (C) 2003-2013 Victor Kirhenshtein
+** Copyright (C) 2003-2014 Victor Kirhenshtein
 **
 ** This program is free software; you can redistribute it and/or modify
 ** it under the terms of the GNU General Public License as published by
@@ -53,18 +53,19 @@ void InitSessionList()
 /**
  * Validates server's address
  */
-static BOOL IsValidServerAddr(UINT32 dwAddr, BOOL *pbMasterServer, BOOL *pbControlServer)
+static bool IsValidServerAddress(const InetAddress &addr, bool *pbMasterServer, bool *pbControlServer)
 {
-   for(UINT32 i = 0; i < g_dwServerCount; i++)
+   for(int i = 0; i < g_serverList.size(); i++)
        {
-      if ((dwAddr & g_pServerList[i].dwNetMask) == g_pServerList[i].dwIpAddr)
+      ServerInfo *s = g_serverList.get(i);
+      if (s->match(addr))
       {
-         *pbMasterServer = g_pServerList[i].bMasterServer;
-         *pbControlServer = g_pServerList[i].bControlServer;
-         return TRUE;
+         *pbMasterServer = s->isMaster();
+         *pbControlServer = s->isControl();
+         return true;
       }
        }
-   return FALSE;
+   return false;
 }
 
 /**
@@ -104,79 +105,191 @@ void UnregisterSession(UINT32 dwIndex)
  */ 
 THREAD_RESULT THREAD_CALL ListenerThread(void *)
 {
-   SOCKET hSocket, hClientSocket;
-   struct sockaddr_in servAddr;
-   int iNumErrors = 0, nRet;
-   socklen_t iSize;
-   CommSession *pSession;
-   TCHAR szBuffer[256];
-   BOOL bMasterServer, bControlServer;
-   struct timeval tv;
-   fd_set rdfs;
-
-   // Create socket
-   if ((hSocket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
+   // Create socket(s)
+   SOCKET hSocket = (g_dwFlags & AF_DISABLE_IPV4) ? INVALID_SOCKET : socket(AF_INET, SOCK_STREAM, 0);
+#ifdef WITH_IPV6
+   SOCKET hSocket6 = (g_dwFlags & AF_DISABLE_IPV6) ? INVALID_SOCKET : socket(AF_INET6, SOCK_STREAM, 0);
+#endif
+   if (((hSocket == INVALID_SOCKET) && !(g_dwFlags & AF_DISABLE_IPV4))
+#ifdef WITH_IPV6
+       && ((hSocket6 == INVALID_SOCKET) && !(g_dwFlags & AF_DISABLE_IPV6))
+#endif
+      )
    {
       nxlog_write(MSG_SOCKET_ERROR, EVENTLOG_ERROR_TYPE, "e", WSAGetLastError());
       exit(1);
    }
 
-       SetSocketExclusiveAddrUse(hSocket);
-       SetSocketReuseFlag(hSocket);
+   if (!(g_dwFlags & AF_DISABLE_IPV4))
+   {
+          SetSocketExclusiveAddrUse(hSocket);
+          SetSocketReuseFlag(hSocket);
+#ifndef _WIN32
+      fcntl(hSocket, F_SETFD, fcntl(hSocket, F_GETFD) | FD_CLOEXEC);
+#endif
+   }
+
+#ifdef WITH_IPV6
+   if (!(g_dwFlags & AF_DISABLE_IPV6))
+   {
+          SetSocketExclusiveAddrUse(hSocket6);
+          SetSocketReuseFlag(hSocket6);
 #ifndef _WIN32
-   fcntl(hSocket, F_SETFD, fcntl(hSocket, F_GETFD) | FD_CLOEXEC);
+      fcntl(hSocket6, F_SETFD, fcntl(hSocket6, F_GETFD) | FD_CLOEXEC);
+#endif
+   }
 #endif
 
    // Fill in local address structure
+   struct sockaddr_in servAddr;
    memset(&servAddr, 0, sizeof(struct sockaddr_in));
    servAddr.sin_family = AF_INET;
-       if (!_tcscmp(g_szListenAddress, _T("*")))
+
+#ifdef WITH_IPV6
+   struct sockaddr_in6 servAddr6;
+   memset(&servAddr6, 0, sizeof(struct sockaddr_in6));
+   servAddr6.sin6_family = AF_INET6;
+#endif
+
+   if (!_tcscmp(g_szListenAddress, _T("*")))
        {
                servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+#ifdef WITH_IPV6
+               memset(servAddr6.sin6_addr.s6_addr, 0, 16);
+#endif
        }
        else
        {
-               servAddr.sin_addr.s_addr = ResolveHostName(g_szListenAddress);
-               if (servAddr.sin_addr.s_addr == htonl(INADDR_NONE))
-                       servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+      InetAddress bindAddress = InetAddress::resolveHostName(g_szListenAddress, AF_INET);
+      if (bindAddress.isValid() && (bindAddress.getFamily() == AF_INET))
+      {
+                  servAddr.sin_addr.s_addr = bindAddress.getAddressV4();
+      }
+      else
+      {
+               servAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+      }
+#ifdef WITH_IPV6
+      bindAddress = InetAddress::resolveHostName(g_szListenAddress, AF_INET6);
+      if (bindAddress.isValid() && (bindAddress.getFamily() == AF_INET6))
+      {
+                  memcpy(servAddr6.sin6_addr.s6_addr, bindAddress.getAddressV6(), 16);
+      }
+      else
+      {
+               memset(servAddr6.sin6_addr.s6_addr, 0, 15);
+         servAddr6.sin6_addr.s6_addr[15] = 1;
+      }
+#endif
        }
    servAddr.sin_port = htons(g_wListenPort);
+#ifdef WITH_IPV6
+   servAddr6.sin6_port = htons(g_wListenPort);
+#endif
 
    // Bind socket
-       DebugPrintf(INVALID_INDEX, 1, _T("Trying to bind on %s:%d"), IpToStr(ntohl(servAddr.sin_addr.s_addr), szBuffer), ntohs(servAddr.sin_port));
-   if (bind(hSocket, (struct sockaddr *)&servAddr, sizeof(struct sockaddr_in)) != 0)
+   TCHAR buffer[64];
+   int bindFailures = 0;
+   if (!(g_dwFlags & AF_DISABLE_IPV4))
+   {
+          DebugPrintf(INVALID_INDEX, 1, _T("Trying to bind on %s:%d"), SockaddrToStr((struct sockaddr *)&servAddr, buffer), ntohs(servAddr.sin_port));
+      if (bind(hSocket, (struct sockaddr *)&servAddr, sizeof(struct sockaddr_in)) != 0)
+      {
+         nxlog_write(MSG_BIND_ERROR, EVENTLOG_ERROR_TYPE, "e", WSAGetLastError());
+         bindFailures++;
+      }
+   }
+   else
+   {
+      bindFailures++;
+   }
+
+#ifdef WITH_IPV6
+   if (!(g_dwFlags & AF_DISABLE_IPV6))
+   {
+      DebugPrintf(INVALID_INDEX, 1, _T("Trying to bind on [%s]:%d"), SockaddrToStr((struct sockaddr *)&servAddr6, buffer), ntohs(servAddr6.sin6_port));
+      if (bind(hSocket6, (struct sockaddr *)&servAddr6, sizeof(struct sockaddr_in6)) != 0)
+      {
+         nxlog_write(MSG_BIND_ERROR, EVENTLOG_ERROR_TYPE, "e", WSAGetLastError());
+         bindFailures++;
+      }
+   }
+   else
+   {
+      bindFailures++;
+   }
+#else
+   bindFailures++;
+#endif
+
+   // Abort if cannot bind to socket
+   if (bindFailures == 2)
    {
-      nxlog_write(MSG_BIND_ERROR, EVENTLOG_ERROR_TYPE, "e", WSAGetLastError());
       exit(1);
    }
 
    // Set up queue
-   listen(hSocket, SOMAXCONN);
-       nxlog_write(MSG_LISTENING, EVENTLOG_INFORMATION_TYPE, "ad", ntohl(servAddr.sin_addr.s_addr), g_wListenPort);
+   if (!(g_dwFlags & AF_DISABLE_IPV4))
+   {
+      listen(hSocket, SOMAXCONN);
+          nxlog_write(MSG_LISTENING, EVENTLOG_INFORMATION_TYPE, "ad", ntohl(servAddr.sin_addr.s_addr), g_wListenPort);
+   }
+#ifdef WITH_IPV6
+   if (!(g_dwFlags & AF_DISABLE_IPV6))
+   {
+      listen(hSocket6, SOMAXCONN);
+          nxlog_write(MSG_LISTENING, EVENTLOG_INFORMATION_TYPE, "Hd", servAddr6.sin6_addr.s6_addr, g_wListenPort);
+   }
+#endif
 
    // Wait for connection requests
+   int errorCount = 0;
    while(!(g_dwFlags & AF_SHUTDOWN))
    {
+      struct timeval tv;
       tv.tv_sec = 1;
       tv.tv_usec = 0;
+
+      fd_set rdfs;
       FD_ZERO(&rdfs);
-      FD_SET(hSocket, &rdfs);
-      nRet = select(SELECT_NFDS(hSocket + 1), &rdfs, NULL, NULL, &tv);
+      if (hSocket != INVALID_SOCKET)
+         FD_SET(hSocket, &rdfs);
+#ifdef WITH_IPV6
+      if (hSocket6 != INVALID_SOCKET)
+         FD_SET(hSocket6, &rdfs);
+#endif
+
+#if defined(WITH_IPV6) && !defined(_WIN32)
+      SOCKET nfds = 0;
+      if (hSocket != INVALID_SOCKET)
+         nfds = hSocket;
+      if ((hSocket6 != INVALID_SOCKET) && (hSocket6 > nfds))
+         nfds = hSocket6;
+      int nRet = select(SELECT_NFDS(nfds + 1), &rdfs, NULL, NULL, &tv);
+#else
+      int nRet = select(SELECT_NFDS(hSocket + 1), &rdfs, NULL, NULL, &tv);
+#endif
       if ((nRet > 0) && (!(g_dwFlags & AF_SHUTDOWN)))
       {
-         iSize = sizeof(struct sockaddr_in);
-         if ((hClientSocket = accept(hSocket, (struct sockaddr *)&servAddr, &iSize)) == -1)
+         char clientAddr[128];
+         socklen_t size = 128;
+#ifdef WITH_IPV6
+         SOCKET hClientSocket = accept(FD_ISSET(hSocket, &rdfs) ? hSocket : hSocket6, (struct sockaddr *)clientAddr, &size);
+#else
+         SOCKET hClientSocket = accept(hSocket, (struct sockaddr *)clientAddr, &size);
+#endif
+         if (hClientSocket == INVALID_SOCKET)
          {
             int error = WSAGetLastError();
 
             if (error != WSAEINTR)
                nxlog_write(MSG_ACCEPT_ERROR, EVENTLOG_ERROR_TYPE, "e", error);
-            iNumErrors++;
+            errorCount++;
             g_dwAcceptErrors++;
-            if (iNumErrors > 1000)
+            if (errorCount > 1000)
             {
                nxlog_write(MSG_TOO_MANY_ERRORS, EVENTLOG_WARNING_TYPE, NULL);
-               iNumErrors = 0;
+               errorCount = 0;
             }
             ThreadSleepMs(500);
             continue;
@@ -187,25 +300,26 @@ THREAD_RESULT THREAD_CALL ListenerThread(void *)
          fcntl(hClientSocket, F_SETFD, fcntl(hClientSocket, F_GETFD) | FD_CLOEXEC);
 #endif
 
-         iNumErrors = 0;     // Reset consecutive errors counter
-         DebugPrintf(INVALID_INDEX, 5, _T("Incoming connection from %s"), IpToStr(ntohl(servAddr.sin_addr.s_addr), szBuffer));
+         errorCount = 0;     // Reset consecutive errors counter
+         InetAddress addr = InetAddress::createFromSockaddr((struct sockaddr *)clientAddr);
+         DebugPrintf(INVALID_INDEX, 5, _T("Incoming connection from %s"), addr.toString(buffer));
 
-         if (IsValidServerAddr(servAddr.sin_addr.s_addr, &bMasterServer, &bControlServer))
+         bool masterServer, controlServer;
+         if (IsValidServerAddress(addr, &masterServer, &controlServer))
          {
             g_dwAcceptedConnections++;
-            DebugPrintf(INVALID_INDEX, 5, _T("Connection from %s accepted"), szBuffer);
+            DebugPrintf(INVALID_INDEX, 5, _T("Connection from %s accepted"), buffer);
 
             // Create new session structure and threads
-            pSession = new CommSession(hClientSocket, ntohl(servAddr.sin_addr.s_addr), 
-                                       bMasterServer, bControlServer);
+            CommSession *session = new CommSession(hClientSocket, addr, masterServer, controlServer);
                        
-            if (!RegisterSession(pSession))
+            if (!RegisterSession(session))
             {
-               delete pSession;
+               delete session;
             }
             else
             {
-               pSession->run();
+               session->run();
             }
          }
          else     // Unauthorized connection
@@ -213,7 +327,7 @@ THREAD_RESULT THREAD_CALL ListenerThread(void *)
             g_dwRejectedConnections++;
             shutdown(hClientSocket, SHUT_RDWR);
             closesocket(hClientSocket);
-            DebugPrintf(INVALID_INDEX, 5, _T("Connection from %s rejected"), szBuffer);
+            DebugPrintf(INVALID_INDEX, 5, _T("Connection from %s rejected"), buffer);
          }
       }
       else if (nRet == -1)
index 13842b7..e9005d1 100644 (file)
@@ -81,14 +81,11 @@ LONG ParamProvider::getValue(const TCHAR *name, TCHAR *buffer)
 
        lock();
 
-       for(int i = 0; i < m_parameters->size(); i++)
-       {
-               if (!_tcsicmp(m_parameters->getKeyByIndex(i), name))
-               {
-                       nx_strncpy(buffer, m_parameters->getValueByIndex(i), MAX_RESULT_LENGTH);
-                       rc = SYSINFO_RC_SUCCESS;
-                       break;
-               }
+   const TCHAR *value = m_parameters->get(name);
+   if (value != NULL)
+   {
+               nx_strncpy(buffer, value, MAX_RESULT_LENGTH);
+               rc = SYSINFO_RC_SUCCESS;
        }
 
        unlock();
@@ -147,24 +144,53 @@ void ParamProvider::poll()
        m_lastPollTime = time(NULL);
 }
 
+/**
+ * Parameter list callback data
+ */
+struct ParameterListCallbackData
+{
+   CSCPMessage *msg;
+   UINT32 id;
+   UINT32 count;
+};
+
+/**
+ * Parameter list callback
+ */
+static bool ParameterListCallback(const TCHAR *key, const void *value, void *data)
+{
+       ((ParameterListCallbackData *)data)->msg->SetVariable(((ParameterListCallbackData *)data)->id++, key);
+       ((ParameterListCallbackData *)data)->msg->SetVariable(((ParameterListCallbackData *)data)->id++, _T(""));
+       ((ParameterListCallbackData *)data)->msg->SetVariable(((ParameterListCallbackData *)data)->id++, (WORD)DCI_DT_STRING);
+       ((ParameterListCallbackData *)data)->count++;
+   return true;
+}
+
 /**
  * List available parameters
  */
 void ParamProvider::listParameters(CSCPMessage *msg, UINT32 *baseId, UINT32 *count)
 {
-       UINT32 id = *baseId;
+   ParameterListCallbackData data;
+   data.msg = msg;
+   data.id = *baseId;
+   data.count = 0;
 
        lock();
-       for(int i = 0; i < m_parameters->size(); i++)
-       {
-               msg->SetVariable(id++, m_parameters->getKeyByIndex(i));
-               msg->SetVariable(id++, _T(""));
-               msg->SetVariable(id++, (WORD)DCI_DT_STRING);
-               (*count)++;
-       }
+   m_parameters->forEach(ParameterListCallback, &data);
        unlock();
 
-       *baseId = id;
+       *baseId = data.id;
+   *count += data.count;
+}
+
+/**
+ * Parameter list callback
+ */
+static bool ParameterListCallback2(const TCHAR *key, const void *value, void *data)
+{
+   ((StringList *)data)->add(key);
+   return true;
 }
 
 /**
@@ -173,10 +199,7 @@ void ParamProvider::listParameters(CSCPMessage *msg, UINT32 *baseId, UINT32 *cou
 void ParamProvider::listParameters(StringList *list)
 {
        lock();
-       for(int i = 0; i < m_parameters->size(); i++)
-       {
-               list->add(m_parameters->getKeyByIndex(i));
-       }
+   m_parameters->forEach(ParameterListCallback2, list);
        unlock();
 }
 
index 8d7948c..f607056 100644 (file)
@@ -420,7 +420,6 @@ LONG RunExternal(const TCHAR *pszCmd, const TCHAR *pszArg, StringList *value)
                PROCESS_INFORMATION pi;
                SECURITY_ATTRIBUTES sa;
                HANDLE hOutput;
-               DWORD dwBytes;
 
                // Create temporary file to hold process output
                GetTempPath(MAX_PATH - 1, szBuffer);
@@ -450,21 +449,29 @@ LONG RunExternal(const TCHAR *pszCmd, const TCHAR *pszArg, StringList *value)
                                        SetFilePointer(hOutput, 0, NULL, FILE_BEGIN);
 
                                        // Read process output
-                                       char *eptr;
-                                       char buffer[256];
-                                       ReadFile(hOutput, buffer, MAX_RESULT_LENGTH - 1, &dwBytes, NULL);
-                                       buffer[dwBytes] = 0;
-                                       eptr = strchr(buffer, '\r');
-                                       if (eptr != NULL)
-                                               *eptr = 0;
-                                       eptr = strchr(buffer, '\n');
-                                       if (eptr != NULL)
-                                               *eptr = 0;
+               DWORD size = GetFileSize(hOutput, NULL);
+               char *buffer = (char *)malloc(size + 1);
+                                       ReadFile(hOutput, buffer, size, &size, NULL);
+                                       buffer[size] = 0;
+
+               char *line = strtok(buffer, "\n");
+               while(line != NULL)
+               {
+                                          char *eptr = strchr(line, '\r');
+                                          if (eptr != NULL)
+                                                  *eptr = 0;
+                  StrStripA(line);
+
+                  if (line[0] != 0)
+                  {
 #ifdef UNICODE
-               value->addPreallocated(WideStringFromMBString(buffer));
+                     value->addPreallocated(WideStringFromMBString(line));
 #else
-               value->add(buffer);
+                     value->add(line);
 #endif
+                  }
+                  line = strtok(NULL, "\n");
+               }
                                        iStatus = SYSINFO_RC_SUCCESS;
                                }
                                else
index c26e210..b1d24a0 100644 (file)
@@ -40,6 +40,7 @@ LONG H_ActionList(const TCHAR *cmd, const TCHAR *arg, StringList *value);
 LONG H_ExternalParameter(const TCHAR *cmd, const TCHAR *arg, TCHAR *value);
 LONG H_ExternalList(const TCHAR *cmd, const TCHAR *arg, StringList *value);
 LONG H_PlatformName(const TCHAR *cmd, const TCHAR *arg, TCHAR *value);
+LONG H_SessionAgents(const TCHAR *cmd, const TCHAR *arg, Table *value);
 LONG H_SystemTime(const TCHAR *cmd, const TCHAR *arg, TCHAR *value);
 
 #ifdef _WIN32
@@ -263,6 +264,7 @@ static NETXMS_SUBAGENT_LIST m_stdLists[] =
  */
 static NETXMS_SUBAGENT_TABLE m_stdTables[] =
 {
+   { _T("Agent.SessionAgents"), H_SessionAgents, NULL, _T("SESSION_ID"), DCTDESC_AGENT_SUBAGENTS },
    { _T("Agent.SubAgents"), H_SubAgentTable, NULL, _T("NAME"), DCTDESC_AGENT_SUBAGENTS },
 #ifdef _WIN32
    { _T("FileSystem.Volumes"), H_FileSystems, NULL, _T("VOLUME"), DCTDESC_FILESYSTEM_VOLUMES }
index 91b0b55..752fbd6 100644 (file)
@@ -121,8 +121,8 @@ TCHAR g_szRegistrar[MAX_DB_STRING] = _T("not_set");
 TCHAR g_szListenAddress[MAX_PATH] = _T("*");
 TCHAR g_szConfigIncludeDir[MAX_PATH] = AGENT_DEFAULT_CONFIG_D;
 TCHAR g_masterAgent[MAX_PATH] = _T("not_set");
-WORD g_wListenPort = AGENT_LISTEN_PORT;
-SERVER_INFO g_pServerList[MAX_SERVERS];
+UINT16 g_wListenPort = AGENT_LISTEN_PORT;
+ObjectArray<ServerInfo> g_serverList(8, 8, true);
 UINT32 g_dwServerCount = 0;
 UINT32 g_dwExecTimeout = 2000;     // External process execution timeout in milliseconds
 UINT32 g_dwSNMPTimeout = 3000;
@@ -130,6 +130,11 @@ time_t g_tmAgentStartTime;
 UINT32 g_dwStartupDelay = 0;
 UINT32 g_dwMaxSessions = 32;
 UINT32 g_debugLevel = (UINT32)NXCONFIG_UNINITIALIZED_VALUE;
+#ifdef _WIN32
+UINT16 g_sessionAgentPort = 28180;
+#else
+UINT16 g_sessionAgentPort = 0;
+#endif
 Config *g_config;
 #ifdef _WIN32
 UINT32 g_dwIdleTimeout = 60;   // Session idle timeout
@@ -191,6 +196,8 @@ static NX_CFG_TEMPLATE m_cfgTemplate[] =
        { _T("DataDirectory"), CT_STRING, 0, 0, MAX_PATH, 0, g_szDataDirectory, NULL },
    { _T("DailyLogFileSuffix"), CT_STRING, 0, 0, MAX_PATH, 0, m_szDailyLogFileSuffix, NULL },
        { _T("DebugLevel"), CT_LONG, 0, 0, 0, 0, &g_debugLevel, &g_debugLevel },
+   { _T("DisableIPv4"), CT_BOOLEAN, 0, 0, AF_DISABLE_IPV4, 0, &g_dwFlags, NULL },
+   { _T("DisableIPv6"), CT_BOOLEAN, 0, 0, AF_DISABLE_IPV6, 0, &g_dwFlags, NULL },
    { _T("DumpDirectory"), CT_STRING, 0, 0, MAX_PATH, 0, m_szDumpDir, NULL },
    { _T("EnableActions"), CT_BOOLEAN, 0, 0, AF_ENABLE_ACTIONS, 0, &g_dwFlags, NULL },
    { _T("EnabledCiphers"), CT_LONG, 0, 0, 0, 0, &m_dwEnabledCiphers, NULL },
@@ -223,6 +230,7 @@ static NX_CFG_TEMPLATE m_cfgTemplate[] =
    { _T("Servers"), CT_STRING_LIST, ',', 0, 0, 0, &m_pszServerList, NULL },
    { _T("SessionIdleTimeout"), CT_LONG, 0, 0, 0, 0, &g_dwIdleTimeout, NULL },
    { _T("EncryptedSharedSecret"), CT_STRING, 0, 0, MAX_SECRET_LENGTH, 0, g_szEncryptedSharedSecret, NULL },
+   { _T("SessionAgentPort"), CT_WORD, 0, 0, 0, 0, &g_sessionAgentPort, NULL },
    { _T("SharedSecret"), CT_STRING, 0, 0, MAX_SECRET_LENGTH, 0, g_szSharedSecret, NULL },
        { _T("SNMPTimeout"), CT_LONG, 0, 0, 0, 0, &g_dwSNMPTimeout, NULL },
    { _T("StartupDelay"), CT_LONG, 0, 0, 0, 0, &g_dwStartupDelay, NULL },
@@ -271,6 +279,79 @@ static TCHAR m_szHelpText[] =
    _T("   -v         : Display version and exit\n")
    _T("\n");
 
+/**
+ * Server info: constructor
+ */
+ServerInfo::ServerInfo(const TCHAR *name, bool control, bool master)
+{
+#ifdef UNICODE
+   m_name = MBStringFromWideString(name);
+#else
+   m_name = strdup(name);
+#endif
+
+   char *p = strchr(m_name, '/');
+   if (p != NULL)
+   {
+      *p = 0;
+      p++;
+      m_address = InetAddress::resolveHostName(m_name);
+      if (m_address.isValid())
+      {
+         int bits = strtol(p, NULL, 10);
+         if ((bits >= 0) && (bits <= 32))
+            m_address.setMaskBits(bits);
+      }
+      m_redoResolve = false;
+   }
+   else
+   {
+      m_address = InetAddress::resolveHostName(m_name);
+      m_redoResolve = true;
+   }
+
+   m_control = control;
+   m_master = master;
+   m_lastResolveTime = time(NULL);
+   m_mutex = MutexCreate();
+}
+
+/**
+ * Server info: destructor
+ */
+ServerInfo::~ServerInfo()
+{
+   safe_free(m_name);
+   MutexDestroy(m_mutex);
+}
+
+/**
+ * Server info: resolve hostname if needed
+ */
+void ServerInfo::resolve()
+{
+   time_t now = time(NULL);
+   time_t age = now - m_lastResolveTime;
+   if ((age >= 3600) || ((age > 300) && !m_address.isValid()))
+   {
+      m_address = InetAddress::resolveHostName(m_name);
+      m_lastResolveTime = now;
+   }
+}
+
+/**
+ * Server info: match address
+ */
+bool ServerInfo::match(const InetAddress &addr)
+{
+   MutexLock(m_mutex);
+   if (m_redoResolve)
+      resolve();
+   bool result = m_address.isValid() ? m_address.contain(addr) : false;
+   MutexUnlock(m_mutex);
+   return result;
+}
+
 /**
  * Save registry
  */
@@ -560,20 +641,24 @@ static bool SendFileToServer(void *session, UINT32 requestId, const TCHAR *file,
  */
 static bool EnumerateSessionsBySubagent(bool (* pHandler)(AbstractCommSession *, void* ), void *data)
 {
+   bool ret = false;
    MutexLock(g_hSessionListAccess);
    for(UINT32 i = 0; i < g_dwMaxSessions; i++)
    {
       if(!pHandler(g_pSessionList[i], data))
-         return true;
+      {
+         ret = true;
+         break;
+      }
    }
    MutexUnlock(g_hSessionListAccess);
-   return false;
+   return ret;
 }
 
 /**
  * Parser server list
  */
-static void ParseServerList(TCHAR *serverList, BOOL isControl, BOOL isMaster)
+static void ParseServerList(TCHAR *serverList, bool isControl, bool isMaster)
 {
        TCHAR *pItem, *pEnd;
 
@@ -584,56 +669,7 @@ static void ParseServerList(TCHAR *serverList, BOOL isControl, BOOL isMaster)
                        *pEnd = 0;
                StrStrip(pItem);
 
-               UINT32 ipAddr, netMask;
-
-               TCHAR *mask = _tcschr(pItem, _T('/'));
-               if (mask != NULL)
-               {
-                       *mask = 0;
-                       mask++;
-                       ipAddr = _t_inet_addr(pItem);
-
-                       TCHAR *eptr;
-                       int bits = _tcstol(mask, &eptr, 10);
-                       if ((*eptr == 0) && (bits >= 0) && (bits <= 32))
-                       {
-            netMask = (bits > 0) ? htonl(0xFFFFFFFF << (32 - bits)) : 0;
-                       }
-                       else
-                       {
-                               ipAddr = INADDR_NONE;
-                               if (!(g_dwFlags & AF_DAEMON))
-                                       _tprintf(_T("Invalid network mask %s\n"), mask);
-                       }
-               }
-               else
-               {
-                       ipAddr = ResolveHostName(pItem);
-                       if (ipAddr == INADDR_ANY)
-                               ipAddr = INADDR_NONE;
-                       netMask = 0xFFFFFFFF;
-               }
-               if (ipAddr == INADDR_NONE)
-               {
-                       if (!(g_dwFlags & AF_DAEMON))
-                               _tprintf(_T("Invalid server address '%s'\n"), pItem);
-               }
-               else
-               {
-                       UINT32 i;
-
-                       for(i = 0; i < g_dwServerCount; i++)
-                               if ((g_pServerList[i].dwIpAddr == ipAddr) && (g_pServerList[i].dwNetMask == netMask))
-                                       break;
-                       if (i == g_dwServerCount)
-                       {
-                               g_dwServerCount++;
-                               g_pServerList[i].dwIpAddr = ipAddr;
-                               g_pServerList[i].dwNetMask = netMask;
-                       }
-                       g_pServerList[i].bMasterServer = isMaster;
-                       g_pServerList[i].bControlServer = isControl;
-               }
+      g_serverList.add(new ServerInfo(pItem, isControl, isMaster));
        }
        free(serverList);
 }
@@ -941,6 +977,7 @@ BOOL Initialize()
                m_thSessionWatchdog = ThreadCreateEx(SessionWatchdog, 0, NULL);
                StartPushConnector();
                StartStorageDiscoveryConnector();
+      StartSessionAgentConnector();
       if (g_dwFlags & AF_ENABLE_CONTROL_CONNECTOR)
           {
          StartControlConnector();
@@ -1607,7 +1644,8 @@ int main(int argc, char *argv[])
                const TCHAR *dir = g_config->getValue(_T("/agent/ConfigIncludeDir"));
                if (dir != NULL)
                {
-                  validConfig = g_config->loadConfigDirectory(g_szConfigIncludeDir, _T("agent"), false);
+                  validConfig = g_config->loadConfigDirectory(dir, _T("agent"), false);
+                  ConsolePrintf(_T("Error reading additional configuration files from \"%s\"\n"), dir);
                }
             }
 
index dfc7813..d590e62 100644 (file)
 #define AF_CATCH_EXCEPTIONS         0x00010000
 #define AF_WRITE_FULL_DUMP          0x00020000
 #define AF_ENABLE_CONTROL_CONNECTOR 0x00040000
+#define AF_DISABLE_IPV4             0x00080000
+#define AF_DISABLE_IPV6             0x00100000
 
 
 #ifdef _WIN32
@@ -282,12 +284,27 @@ public:
 /**
  * Server information
  */
-struct SERVER_INFO
+class ServerInfo
 {
-   UINT32 dwIpAddr;
-       UINT32 dwNetMask;
-   BOOL bMasterServer;
-   BOOL bControlServer;
+private:
+   char *m_name;
+   InetAddress m_address;
+   bool m_control;
+   bool m_master;
+   time_t m_lastResolveTime;
+   bool m_redoResolve;
+   MUTEX m_mutex;
+
+   void resolve();
+
+public:
+   ServerInfo(const TCHAR *name, bool control, bool master);
+   ~ServerInfo();
+
+   bool match(const InetAddress &addr);
+
+   bool isMaster() { return m_master; }
+   bool isControl() { return m_control; }
 };
 
 /**
@@ -303,13 +320,13 @@ private:
    THREAD m_hWriteThread;
    THREAD m_hProcessingThread;
    THREAD m_hProxyReadThread;
-   UINT32 m_dwHostAddr;        // IP address of connected host (network byte order)
+   InetAddress m_serverAddr;        // IP address of connected host
    UINT32 m_dwIndex;
-   BOOL m_bIsAuthenticated;
-   BOOL m_bMasterServer;
-   BOOL m_bControlServer;
-   BOOL m_bProxyConnection;
-   BOOL m_bAcceptTraps;
+   bool m_authenticated;
+   bool m_masterServer;
+   bool m_controlServer;
+   bool m_proxyConnection;
+   bool m_acceptTraps;
    int m_hCurrFile;
    UINT32 m_dwFileRqId;
        NXCPEncryptionContext *m_pCtx;
@@ -342,17 +359,17 @@ private:
    static THREAD_RESULT THREAD_CALL proxyReadThreadStarter(void *);
 
 public:
-   CommSession(SOCKET hSocket, UINT32 dwHostAddr, BOOL bMasterServer, BOOL bControlServer);
+   CommSession(SOCKET hSocket, const InetAddress &serverAddr, bool masterServer, bool controlServer);
    ~CommSession();
 
    void run();
    void disconnect();
 
-   void sendMessage(CSCPMessage *pMsg) { m_pSendQueue->Put(pMsg->createMessage()); }
-   void sendRawMessage(CSCP_MESSAGE *pMsg) { m_pSendQueue->Put(nx_memdup(pMsg, ntohl(pMsg->dwSize))); }
-       bool sendFile(UINT32 requestId, const TCHAR *file, long offset);
+   virtual void sendMessage(CSCPMessage *pMsg) { m_pSendQueue->Put(pMsg->createMessage()); }
+   virtual void sendRawMessage(CSCP_MESSAGE *pMsg) { m_pSendQueue->Put(nx_memdup(pMsg, ntohl(pMsg->dwSize))); }
+       virtual bool sendFile(UINT32 requestId, const TCHAR *file, long offset);
 
-       UINT32 getServerAddress() { return m_dwHostAddr; }
+       virtual const InetAddress& getServerAddress() { return m_serverAddr; }
 
    UINT32 getIndex() { return m_dwIndex; }
    void setIndex(UINT32 dwIndex) { if (m_dwIndex == INVALID_INDEX) m_dwIndex = dwIndex; }
@@ -360,10 +377,52 @@ public:
    time_t getTimeStamp() { return m_ts; }
        void updateTimeStamp() { m_ts = time(NULL); }
 
-   BOOL canAcceptTraps() { return m_bAcceptTraps; }
+   bool canAcceptTraps() { return m_acceptTraps; }
+   
+   virtual bool isMasterServer() { return m_masterServer; }
+   virtual bool isControlServer() { return m_controlServer; }
+   
+   virtual UINT32 openFile(TCHAR* nameOfFile, UINT32 requestId);
+};
+
+/**
+ * Session agent connector
+ */
+class SessionAgentConnector : public RefCountObject
+{
+private:
+   UINT32 m_id;
+   SOCKET m_socket;
+   MUTEX m_mutex;
+   CSCP_BUFFER m_msgBuffer; 
+   MsgWaitQueue m_msgQueue;
+   UINT32 m_sessionId;
+   TCHAR *m_sessionName;
+   INT16 m_sessionState;
+   TCHAR *m_userName;
+   VolatileCounter m_requestId;
 
-   BOOL isMasterServer() { return m_bMasterServer; }
-   UINT32 openFile(TCHAR* nameOfFile, UINT32 requestId);
+   void readThread();
+   bool sendMessage(CSCPMessage *msg);
+   UINT32 nextRequestId() { return InterlockedIncrement(&m_requestId); }
+
+   static THREAD_RESULT THREAD_CALL readThreadStarter(void *);
+
+public:
+   SessionAgentConnector(UINT32 id, SOCKET s);
+   ~SessionAgentConnector();
+
+   void run();
+   void disconnect();
+
+   UINT32 getId() { return m_id; }
+   UINT32 getSessionId() { return m_sessionId; }
+   INT16 getSessionState() { return m_sessionState; }
+   const TCHAR *getSessionName() { return CHECK_NULL(m_sessionName); }
+   const TCHAR *getUserName() { return CHECK_NULL(m_userName); }
+
+   bool testConnection();
+   void takeScreenshot(CSCPMessage *msg);
 };
 
 /**
@@ -410,7 +469,7 @@ void UnloadAllSubAgents();
 BOOL InitSubAgent(HMODULE hModule, const TCHAR *pszModuleName,
                   BOOL (* SubAgentInit)(NETXMS_SUBAGENT_INFO **, Config *),
                   const TCHAR *pszEntryPoint);
-BOOL ProcessCmdBySubAgent(UINT32 dwCommand, CSCPMessage *pRequest, CSCPMessage *pResponse, void *session);
+BOOL ProcessCmdBySubAgent(UINT32 dwCommand, CSCPMessage *pRequest, CSCPMessage *pResponse, AbstractCommSession *session);
 BOOL AddAction(const TCHAR *pszName, int iType, const TCHAR *pArg,
                LONG (*fpHandler)(const TCHAR *, StringList *, const TCHAR *),
                const TCHAR *pszSubAgent, const TCHAR *pszDescription);
@@ -465,6 +524,9 @@ void StartStorageDiscoveryConnector();
 void StartControlConnector();
 bool SendControlMessage(CSCPMessage *msg);
 
+void StartSessionAgentConnector();
+SessionAgentConnector *AcquireSessionAgentConnector(const TCHAR *sessionName);
+
 #ifdef _WIN32
 
 void InitService();
@@ -495,8 +557,8 @@ extern TCHAR g_szRegistrar[];
 extern TCHAR g_szListenAddress[];
 extern TCHAR g_szConfigIncludeDir[];
 extern TCHAR g_masterAgent[];
-extern WORD g_wListenPort;
-extern SERVER_INFO g_pServerList[];
+extern UINT16 g_wListenPort;
+extern ObjectArray<ServerInfo> g_serverList;
 extern UINT32 g_dwServerCount;
 extern time_t g_tmAgentStartTime;
 extern TCHAR g_szPlatformSuffix[];
@@ -506,6 +568,7 @@ extern UINT32 g_dwMaxSessions;
 extern UINT32 g_dwExecTimeout;
 extern UINT32 g_dwSNMPTimeout;
 extern UINT32 g_debugLevel;
+extern UINT16 g_sessionAgentPort;
 
 extern Config *g_config;
 
index c0277cc..087a77f 100644 (file)
                                RelativePath=".\register.cpp"
                                >
                        </File>
+                       <File
+                               RelativePath=".\sa.cpp"
+                               >
+                       </File>
                        <File
                                RelativePath=".\sd.cpp"
                                >
index b79418c..c33ca4b 100644 (file)
@@ -46,7 +46,7 @@ static void RegisterPolicy(CommSession *session, UINT32 type, uuid_t guid)
        registry->setValue(path, type);
 
        _tcscpy(&path[tail], _T("server"));
-       registry->setValue(path, IpToStr(session->getServerAddress(), buffer));
+   registry->setValue(path, session->getServerAddress().toString(buffer));
 
        CloseRegistry(true);
 }
diff --git a/src/agent/core/sa.cpp b/src/agent/core/sa.cpp
new file mode 100644 (file)
index 0000000..319a167
--- /dev/null
@@ -0,0 +1,454 @@
+/* 
+** NetXMS multiplatform core agent
+** Copyright (C) 2003-2014 Victor Kirhenshtein
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be usefu,,
+** but ITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+**
+** File: sa.cpp
+**
+**/
+
+#include "nxagentd.h"
+
+/**
+ * Session agent list
+ */
+static ObjectArray<SessionAgentConnector> s_agents(8, 8, false);
+static RWLOCK s_lock = RWLockCreate();
+
+/**
+ * Register session agent
+ */
+static void RegisterSessionAgent(SessionAgentConnector *c)
+{
+   RWLockWriteLock(s_lock, INFINITE);
+   s_agents.add(c);
+   RWLockUnlock(s_lock);
+}
+
+/**
+ * Unregister session agent
+ */
+static void UnregisterSessionAgent(UINT32 id)
+{
+   RWLockWriteLock(s_lock, INFINITE);
+   for(int i = 0; i < s_agents.size(); i++)
+   {
+      if (s_agents.get(i)->getId() == id)
+      {
+         s_agents.remove(i);
+         break;
+      }
+   }
+   RWLockUnlock(s_lock);
+}
+
+/**
+ * Session agent connector read thread
+ */
+THREAD_RESULT THREAD_CALL SessionAgentConnector::readThreadStarter(void *arg)
+{
+   ((SessionAgentConnector *)arg)->readThread();
+
+   // When SessionAgentConnector::ReadThread exits, all other
+   // threads are already stopped, so we can safely destroy
+   // session object
+   UnregisterSessionAgent(((SessionAgentConnector *)arg)->getId());
+   ((SessionAgentConnector *)arg)->decRefCount();
+   return THREAD_OK;
+}
+
+/**
+ * Connector constructor
+ */
+SessionAgentConnector::SessionAgentConnector(UINT32 id, SOCKET s)
+{
+   m_id = id;
+   m_socket = s;
+   m_sessionId = 0;
+   m_sessionName = NULL;
+   m_sessionState = USER_SESSION_OTHER;
+   m_userName = NULL;
+   m_mutex = MutexCreate();
+   m_requestId = 0;
+}
+
+/**
+ * Connector destructor
+ */
+SessionAgentConnector::~SessionAgentConnector()
+{
+   MutexDestroy(m_mutex);
+   closesocket(m_socket);
+   safe_free(m_sessionName);
+   safe_free(m_userName);
+}
+
+/**
+ * Start all threads
+ */
+void SessionAgentConnector::run()
+{
+   ThreadCreate(readThreadStarter, 0, this);
+}
+
+/**
+ * Disconnect session
+ */
+void SessionAgentConnector::disconnect()
+{
+   shutdown(m_socket, SHUT_RDWR);
+}
+
+/**
+ * Send message
+ */
+bool SessionAgentConnector::sendMessage(CSCPMessage *msg)
+{
+   CSCP_MESSAGE *rawMsg = msg->createMessage();
+   bool success = (SendEx(m_socket, rawMsg, ntohl(rawMsg->dwSize), 0, m_mutex) == ntohl(rawMsg->dwSize));
+   free(rawMsg);
+   return success;
+}
+
+/**
+ * Reading thread
+ */
+void SessionAgentConnector::readThread()
+{
+   NXCPEncryptionContext *dummyCtx = NULL;
+   RecvNXCPMessage(0, NULL, &m_msgBuffer, 0, NULL, NULL, 0);
+   UINT32 rawMsgSize = 65536;
+   CSCP_MESSAGE *rawMsg = (CSCP_MESSAGE *)malloc(rawMsgSize);
+   while(1)
+   {
+      int err = RecvNXCPMessageEx(m_socket, &rawMsg, &m_msgBuffer, &rawMsgSize, &dummyCtx, NULL, 300000, 4 * 1024 * 1024);
+      if (err <= 0)
+         break;
+
+      // Check if message is too large
+      if (err == 1)
+         continue;
+
+      // Check for decryption failure
+      if (err == 2)
+         continue;
+
+      // Check for timeout
+      if (err == 3)
+      {
+         DebugPrintf(INVALID_INDEX, 5, _T("Session agent connector %d stopped by timeout"), m_id);
+         break;
+      }
+
+      // Check that actual received packet size is equal to encoded in packet
+      if ((int)ntohl(rawMsg->dwSize) != err)
+      {
+         DebugPrintf(INVALID_INDEX, 5, _T("Session agent connector %d: actual message size doesn't match wSize value (%d,%d)"), m_id, err, ntohl(rawMsg->dwSize));
+         continue;   // Bad packet, wait for next
+      }
+
+      if (g_debugLevel >= 8)
+      {
+         String msgDump = CSCPMessage::dump(rawMsg, NXCP_VERSION);
+         DebugPrintf(INVALID_INDEX, 8, _T("SA-%d: Message dump:\n%s"), m_id, (const TCHAR *)msgDump);
+      }
+
+      UINT16 flags = ntohs(rawMsg->wFlags);
+      if (!(flags & MF_BINARY))
+      {
+         // Create message object from raw message
+         CSCPMessage *msg = new CSCPMessage(rawMsg);
+         if (msg->GetCode() == CMD_LOGIN)
+         {
+            m_sessionId = msg->GetVariableLong(VID_SESSION_ID);
+            m_sessionState = msg->getFieldAsInt16(VID_SESSION_STATE);
+
+            safe_free(m_sessionName);
+            m_sessionName = msg->GetVariableStr(VID_NAME);
+
+            safe_free(m_userName);
+            m_userName = msg->GetVariableStr(VID_USER_NAME);
+
+            delete msg;
+            DebugPrintf(INVALID_INDEX, 5, _T("Session agent connector %d: login as %s@%s [%d]"), m_id, getUserName(), getSessionName(), m_sessionId);
+         }
+         else
+         {
+            m_msgQueue.put(msg);
+         }
+      }
+   }
+   free(rawMsg);
+
+   DebugPrintf(INVALID_INDEX, 5, _T("Session agent connector %d stopped"), m_id);
+}
+
+/**
+ * Test connection with session agent
+ */
+bool SessionAgentConnector::testConnection()
+{
+   CSCPMessage msg;
+
+   msg.SetCode(CMD_KEEPALIVE);
+   msg.SetId(nextRequestId());
+   if (!sendMessage(&msg))
+      return false;
+
+   CSCPMessage *response = m_msgQueue.waitForMessage(CMD_REQUEST_COMPLETED, msg.GetId(), 5000);
+   if (response == NULL)
+      return false;
+
+   delete response;
+   return true;
+}
+
+/**
+ * Take screenshot via session agent
+ */
+void SessionAgentConnector::takeScreenshot(CSCPMessage *masterResponse)
+{
+   CSCPMessage msg;
+
+   msg.SetCode(CMD_TAKE_SCREENSHOT);
+   msg.SetId(nextRequestId());
+   if (!sendMessage(&msg))
+   {
+      masterResponse->SetVariable(VID_RCC, ERR_CONNECTION_BROKEN);
+      return;
+   }
+
+   CSCPMessage *response = m_msgQueue.waitForMessage(CMD_REQUEST_COMPLETED, msg.GetId(), 5000);
+   if (response == NULL)
+   {
+      masterResponse->SetVariable(VID_RCC, ERR_REQUEST_TIMEOUT);
+      return;
+   }
+
+   UINT32 rcc = response->GetVariableLong(VID_RCC);
+   if (rcc == ERR_SUCCESS)
+   {
+      masterResponse->SetVariable(VID_RCC, ERR_SUCCESS);
+      size_t imageSize;
+      BYTE *image = response->getBinaryFieldPtr(VID_FILE_DATA, &imageSize);
+      if (image != NULL)
+         masterResponse->SetVariable(VID_FILE_DATA, image, (UINT32)imageSize);
+   }
+   else
+   {
+      masterResponse->SetVariable(VID_RCC, rcc);
+   }
+
+   delete response;
+}
+
+/**
+ * Session agent listener thread
+ */
+static THREAD_RESULT THREAD_CALL SessionAgentListener(void *arg)
+{
+   SOCKET hSocket, hClientSocket;
+   struct sockaddr_in servAddr;
+   int iNumErrors = 0, nRet;
+   socklen_t iSize;
+   TCHAR szBuffer[256];
+   struct timeval tv;
+   fd_set rdfs;
+   UINT32 id = 1;
+
+   // Create socket
+   if ((hSocket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
+   {
+      nxlog_write(MSG_SOCKET_ERROR, EVENTLOG_ERROR_TYPE, "e", WSAGetLastError());
+      DebugPrintf(INVALID_INDEX, 1, _T("Session agent connector terminated (socket error)"));
+      return THREAD_OK;
+   }
+
+       SetSocketExclusiveAddrUse(hSocket);
+       SetSocketReuseFlag(hSocket);
+#ifndef _WIN32
+   fcntl(hSocket, F_SETFD, fcntl(hSocket, F_GETFD) | FD_CLOEXEC);
+#endif
+
+   // Fill in local address structure
+   memset(&servAddr, 0, sizeof(struct sockaddr_in));
+   servAddr.sin_family = AF_INET;
+       servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
+   servAddr.sin_port = htons(g_sessionAgentPort);
+
+   // Bind socket
+       DebugPrintf(INVALID_INDEX, 1, _T("Trying to bind on %s:%d"), IpToStr(ntohl(servAddr.sin_addr.s_addr), szBuffer), ntohs(servAddr.sin_port));
+   if (bind(hSocket, (struct sockaddr *)&servAddr, sizeof(struct sockaddr_in)) != 0)
+   {
+      nxlog_write(MSG_BIND_ERROR, EVENTLOG_ERROR_TYPE, "e", WSAGetLastError());
+      DebugPrintf(INVALID_INDEX, 1, _T("Session agent connector terminated (socket error)"));
+      return THREAD_OK;
+   }
+
+   // Set up queue
+   listen(hSocket, SOMAXCONN);
+   DebugPrintf(INVALID_INDEX, 1, _T("Session agent connector listening on port %d"), (int)g_sessionAgentPort);
+
+   // Wait for connection requests
+   while(!(g_dwFlags & AF_SHUTDOWN))
+   {
+      tv.tv_sec = 1;
+      tv.tv_usec = 0;
+      FD_ZERO(&rdfs);
+      FD_SET(hSocket, &rdfs);
+      nRet = select(SELECT_NFDS(hSocket + 1), &rdfs, NULL, NULL, &tv);
+      if ((nRet > 0) && (!(g_dwFlags & AF_SHUTDOWN)))
+      {
+         iSize = sizeof(struct sockaddr_in);
+         if ((hClientSocket = accept(hSocket, (struct sockaddr *)&servAddr, &iSize)) == -1)
+         {
+            int error = WSAGetLastError();
+
+            if (error != WSAEINTR)
+               nxlog_write(MSG_ACCEPT_ERROR, EVENTLOG_ERROR_TYPE, "e", error);
+            iNumErrors++;
+            if (iNumErrors > 1000)
+            {
+               nxlog_write(MSG_TOO_MANY_ERRORS, EVENTLOG_WARNING_TYPE, NULL);
+               iNumErrors = 0;
+            }
+            ThreadSleepMs(500);
+            continue;
+         }
+
+         // Socket should be closed on successful exec
+#ifndef _WIN32
+         fcntl(hClientSocket, F_SETFD, fcntl(hClientSocket, F_GETFD) | FD_CLOEXEC);
+#endif
+
+         iNumErrors = 0;     // Reset consecutive errors counter
+         DebugPrintf(INVALID_INDEX, 5, _T("Incoming session agent connection"));
+
+         // Create new session structure and threads
+                  SessionAgentConnector *c = new SessionAgentConnector(id++, hClientSocket);
+         RegisterSessionAgent(c);
+         c->run();
+      }
+      else if (nRet == -1)
+      {
+         int error = WSAGetLastError();
+
+         // On AIX, select() returns ENOENT after SIGINT for unknown reason
+#ifdef _WIN32
+         if (error != WSAEINTR)
+#else
+         if ((error != EINTR) && (error != ENOENT))
+#endif
+         {
+            nxlog_write(MSG_SELECT_ERROR, EVENTLOG_ERROR_TYPE, "e", error);
+            ThreadSleepMs(100);
+         }
+      }
+   }
+
+   closesocket(hSocket);
+   DebugPrintf(INVALID_INDEX, 1, _T("Session agent connector thread terminated"));
+   return THREAD_OK;
+}
+
+/**
+ * Session agent listener thread
+ */
+static THREAD_RESULT THREAD_CALL SessionAgentWatchdog(void *arg)
+{
+   while(!(g_dwFlags & AF_SHUTDOWN))
+   {
+      RWLockReadLock(s_lock, INFINITE);
+
+      for(int i = 0; i < s_agents.size(); i++)
+      {
+         SessionAgentConnector *c = s_agents.get(i);
+         if (!c->testConnection())
+         {
+            DebugPrintf(INVALID_INDEX, 5, _T("Session agent connector %d failed connection test"), c->getId());
+            c->disconnect();
+         }
+      }
+
+      RWLockUnlock(s_lock);
+
+      ThreadSleep(30);
+   }
+   return THREAD_OK;
+}
+
+/**
+ * Start session agent connector
+ */
+void StartSessionAgentConnector()
+{
+   if (g_sessionAgentPort != 0)
+   {
+          ThreadCreate(SessionAgentListener, 0, NULL);
+          ThreadCreate(SessionAgentWatchdog, 0, NULL);
+   }
+   else
+   {
+      DebugPrintf(INVALID_INDEX, 1, _T("Session agent connector disabled"));
+   }
+}
+
+/**
+ * Acquire session agent connector
+ */
+SessionAgentConnector *AcquireSessionAgentConnector(const TCHAR *sessionName)
+{
+   SessionAgentConnector *c = NULL;
+
+   RWLockReadLock(s_lock, INFINITE);
+   for(int i = 0; i < s_agents.size(); i++)
+   {
+      if (!_tcsicmp(s_agents.get(i)->getSessionName(), sessionName))
+      {
+         c = s_agents.get(i);
+         c->incRefCount();
+         break;
+      }
+   }
+   RWLockUnlock(s_lock);
+
+   return c;
+}
+
+/**
+ * Get table of registered session agents
+ */
+LONG H_SessionAgents(const TCHAR *cmd, const TCHAR *arg, Table *value)
+{
+   value->addColumn(_T("SESSION_ID"), DCI_DT_UINT, _T("Session ID"), true);
+   value->addColumn(_T("SESSION_NAME"), DCI_DT_STRING, _T("Session"));
+   value->addColumn(_T("USER_NAME"), DCI_DT_STRING, _T("User"));
+   value->addColumn(_T("STATE"), DCI_DT_INT, _T("State"));
+
+   RWLockReadLock(s_lock, INFINITE);
+   for(int i = 0; i < s_agents.size(); i++)
+   {
+      SessionAgentConnector *c = s_agents.get(i);
+      value->addRow();
+      value->set(0, c->getSessionId());
+      value->set(1, c->getSessionName());
+      value->set(2, c->getUserName());
+      value->set(3, c->getSessionState());
+   }
+   RWLockUnlock(s_lock);
+
+   return SYSINFO_RC_SUCCESS;
+}
index 74c36f0..0af31cd 100644 (file)
@@ -86,8 +86,7 @@ THREAD_RESULT THREAD_CALL CommSession::proxyReadThreadStarter(void *pArg)
 /**
  * Client session class constructor
  */
-CommSession::CommSession(SOCKET hSocket, UINT32 dwHostAddr,
-                         BOOL bMasterServer, BOOL bControlServer)
+CommSession::CommSession(SOCKET hSocket, const InetAddress &serverAddr, bool masterServer, bool controlServer)
 {
    m_pSendQueue = new Queue;
    m_pMessageQueue = new Queue;
@@ -97,12 +96,12 @@ CommSession::CommSession(SOCKET hSocket, UINT32 dwHostAddr,
    m_pMsgBuffer = (CSCP_BUFFER *)malloc(sizeof(CSCP_BUFFER));
    m_hWriteThread = INVALID_THREAD_HANDLE;
    m_hProcessingThread = INVALID_THREAD_HANDLE;
-   m_dwHostAddr = dwHostAddr;
-   m_bIsAuthenticated = (g_dwFlags & AF_REQUIRE_AUTH) ? FALSE : TRUE;
-   m_bMasterServer = bMasterServer;
-   m_bControlServer = bControlServer;
-   m_bProxyConnection = FALSE;
-   m_bAcceptTraps = FALSE;
+   m_serverAddr = serverAddr;
+   m_authenticated = (g_dwFlags & AF_REQUIRE_AUTH) ? false : true;
+   m_masterServer = masterServer;
+   m_controlServer = controlServer;
+   m_proxyConnection = false;
+   m_acceptTraps = false;
    m_hCurrFile = -1;
    m_pCtx = NULL;
    m_ts = time(NULL);
@@ -213,7 +212,7 @@ void CommSession::readThread()
          DebugPrintf(m_dwIndex, 8, _T("Message dump:\n%s"), (const TCHAR *)msgDump);
       }
 
-      if (m_bProxyConnection)
+      if (m_proxyConnection)
       {
          // Forward received message to remote peer
          SendEx(m_hProxySocket, (char *)pRawMsg, iErr, 0, NULL);
@@ -325,10 +324,10 @@ void CommSession::readThread()
    // Wait for other threads to finish
    ThreadJoin(m_hWriteThread);
    ThreadJoin(m_hProcessingThread);
-   if (m_bProxyConnection)
+   if (m_proxyConnection)
       ThreadJoin(m_hProxyReadThread);
 
-   DebugPrintf(m_dwIndex, 5, _T("Session with %s closed"), IpToStr(m_dwHostAddr, szBuffer));
+   DebugPrintf(m_dwIndex, 5, _T("Session with %s closed"), (const TCHAR *)m_serverAddr.toString());
 }
 
 /**
@@ -409,7 +408,7 @@ void CommSession::processingThread()
       msg.SetId(pMsg->GetId());
 
       // Check if authentication required
-      if ((!m_bIsAuthenticated) && (dwCommand != CMD_AUTHENTICATE))
+      if ((!m_authenticated) && (dwCommand != CMD_AUTHENTICATE))
       {
                        DebugPrintf(m_dwIndex, 6, _T("Authentication required"));
          msg.SetVariable(VID_RCC, ERR_AUTH_REQUIRED);
@@ -475,9 +474,9 @@ void CommSession::processingThread()
                msg.SetVariable(VID_RCC, dwRet);
                break;
             case CMD_ENABLE_AGENT_TRAPS:
-               if (m_bMasterServer)
+               if (m_masterServer)
                {
-                  m_bAcceptTraps = TRUE;
+                  m_acceptTraps = true;
                   msg.SetVariable(VID_RCC, ERR_SUCCESS);
                }
                else
@@ -486,7 +485,7 @@ void CommSession::processingThread()
                }
                break;
                                case CMD_SNMP_REQUEST:
-                                       if (m_bMasterServer && (g_dwFlags & AF_ENABLE_SNMP_PROXY))
+                                       if (m_masterServer && (g_dwFlags & AF_ENABLE_SNMP_PROXY))
                                        {
                                                ProxySNMPRequest(pMsg, &msg);
                                        }
@@ -496,7 +495,7 @@ void CommSession::processingThread()
                                        }
                                        break;
                                case CMD_DEPLOY_AGENT_POLICY:
-                                       if (m_bMasterServer)
+                                       if (m_masterServer)
                                        {
                                                msg.SetVariable(VID_RCC, DeployPolicy(this, pMsg));
                                        }
@@ -506,7 +505,7 @@ void CommSession::processingThread()
                                        }
                                        break;
                                case CMD_UNINSTALL_AGENT_POLICY:
-                                       if (m_bMasterServer)
+                                       if (m_masterServer)
                                        {
                                                msg.SetVariable(VID_RCC, UninstallPolicy(this, pMsg));
                                        }
@@ -516,7 +515,7 @@ void CommSession::processingThread()
                                        }
                                        break;
                                case CMD_GET_POLICY_INVENTORY:
-                                       if (m_bMasterServer)
+                                       if (m_masterServer)
                                        {
                                                msg.SetVariable(VID_RCC, GetPolicyInventory(this, &msg));
                                        }
@@ -525,6 +524,29 @@ void CommSession::processingThread()
                   msg.SetVariable(VID_RCC, ERR_ACCESS_DENIED);
                                        }
                                        break;
+            case CMD_TAKE_SCREENSHOT:
+                                       if (m_controlServer)
+                                       {
+                  TCHAR sessionName[256];
+                  pMsg->GetVariableStr(VID_NAME, sessionName, 256);
+                  DebugPrintf(m_dwIndex, 6, _T("Take snapshot from session \"%s\""), sessionName);
+                  SessionAgentConnector *conn = AcquireSessionAgentConnector(sessionName);
+                  if (conn != NULL)
+                  {
+                     DebugPrintf(m_dwIndex, 6, _T("Session agent connector acquired"));
+                     conn->takeScreenshot(&msg);
+                     conn->decRefCount();
+                  }
+                  else
+                  {
+                     msg.SetVariable(VID_RCC, ERR_NO_SESSION_AGENT);
+                  }
+                                       }
+                                       else
+                                       {
+                  msg.SetVariable(VID_RCC, ERR_ACCESS_DENIED);
+                                       }
+                                       break;
             default:
                // Attempt to process unknown command by subagents
                if (!ProcessCmdBySubAgent(dwCommand, pMsg, &msg, this))
@@ -548,7 +570,7 @@ stop_processing:
  */
 void CommSession::authenticate(CSCPMessage *pRequest, CSCPMessage *pMsg)
 {
-   if (m_bIsAuthenticated)
+   if (m_authenticated)
    {
       // Already authenticated
       pMsg->SetVariable(VID_RCC, (g_dwFlags & AF_REQUIRE_AUTH) ? ERR_ALREADY_AUTHENTICATED : ERR_AUTH_NOT_REQUIRED);
@@ -566,12 +588,12 @@ void CommSession::authenticate(CSCPMessage *pRequest, CSCPMessage *pMsg)
             pRequest->GetVariableStr(VID_SHARED_SECRET, szSecret, MAX_SECRET_LENGTH);
             if (!_tcscmp(szSecret, g_szSharedSecret))
             {
-               m_bIsAuthenticated = TRUE;
+               m_authenticated = true;
                pMsg->SetVariable(VID_RCC, ERR_SUCCESS);
             }
             else
             {
-               nxlog_write(MSG_AUTH_FAILED, EVENTLOG_WARNING_TYPE, "as", m_dwHostAddr, "PLAIN");
+               nxlog_write(MSG_AUTH_FAILED, EVENTLOG_WARNING_TYPE, "Is", &m_serverAddr, "PLAIN");
                pMsg->SetVariable(VID_RCC, ERR_AUTH_FAILED);
             }
             break;
@@ -589,12 +611,12 @@ void CommSession::authenticate(CSCPMessage *pRequest, CSCPMessage *pMsg)
 #endif
             if (!memcmp(szSecret, hash, MD5_DIGEST_SIZE))
             {
-               m_bIsAuthenticated = TRUE;
+               m_authenticated = true;
                pMsg->SetVariable(VID_RCC, ERR_SUCCESS);
             }
             else
             {
-               nxlog_write(MSG_AUTH_FAILED, EVENTLOG_WARNING_TYPE, "as", m_dwHostAddr, _T("MD5"));
+               nxlog_write(MSG_AUTH_FAILED, EVENTLOG_WARNING_TYPE, "Is", &m_serverAddr, _T("MD5"));
                pMsg->SetVariable(VID_RCC, ERR_AUTH_FAILED);
             }
             break;
@@ -612,12 +634,12 @@ void CommSession::authenticate(CSCPMessage *pRequest, CSCPMessage *pMsg)
 #endif
             if (!memcmp(szSecret, hash, SHA1_DIGEST_SIZE))
             {
-               m_bIsAuthenticated = TRUE;
+               m_authenticated = true;
                pMsg->SetVariable(VID_RCC, ERR_SUCCESS);
             }
             else
             {
-               nxlog_write(MSG_AUTH_FAILED, EVENTLOG_WARNING_TYPE, "as", m_dwHostAddr, _T("SHA1"));
+               nxlog_write(MSG_AUTH_FAILED, EVENTLOG_WARNING_TYPE, "Is", &m_serverAddr, _T("SHA1"));
                pMsg->SetVariable(VID_RCC, ERR_AUTH_FAILED);
             }
             break;
@@ -686,7 +708,7 @@ void CommSession::getTable(CSCPMessage *pRequest, CSCPMessage *pMsg)
  */
 void CommSession::action(CSCPMessage *pRequest, CSCPMessage *pMsg)
 {
-   if ((g_dwFlags & AF_ENABLE_ACTIONS) && m_bControlServer)
+   if ((g_dwFlags & AF_ENABLE_ACTIONS) && m_controlServer)
    {
       // Get action name and arguments
       TCHAR action[MAX_PARAM_NAME];
@@ -723,7 +745,7 @@ void CommSession::recvFile(CSCPMessage *pRequest, CSCPMessage *pMsg)
 {
        TCHAR szFileName[MAX_PATH], szFullPath[MAX_PATH];
 
-       if (m_bMasterServer)
+       if (m_masterServer)
        {
                szFileName[0] = 0;
                pRequest->GetVariableStr(VID_FILE_NAME, szFileName, MAX_PATH);
@@ -765,28 +787,26 @@ UINT32 CommSession::openFile(TCHAR *szFullPath, UINT32 requestId)
    }
 }
 
-//
-// Send file to server
-//
 
 static void SendFileProgressCallback(INT64 bytesTransferred, void *cbArg)
 {
        ((CommSession *)cbArg)->updateTimeStamp();
 }
 
+/**
+ * Send file to server
+ */
 bool CommSession::sendFile(UINT32 requestId, const TCHAR *file, long offset)
 {
        return SendFileOverNXCP(m_hSocket, requestId, file, m_pCtx, offset, SendFileProgressCallback, this, m_socketWriteMutex) ? true : false;
 }
 
-
-//
-// Upgrade agent from package in the file store
-//
-
+/**
+ * Upgrade agent from package in the file store
+ */
 UINT32 CommSession::upgrade(CSCPMessage *pRequest)
 {
-   if (m_bMasterServer)
+   if (m_masterServer)
    {
       TCHAR szPkgName[MAX_PATH], szFullPath[MAX_PATH];
 
@@ -807,17 +827,15 @@ UINT32 CommSession::upgrade(CSCPMessage *pRequest)
    }
 }
 
-
-//
-// Get agent's configuration file
-//
-
+/**
+ * Get agent's configuration file
+ */
 void CommSession::getConfig(CSCPMessage *pMsg)
 {
-   if (m_bMasterServer)
+   if (m_masterServer)
    {
       pMsg->SetVariable(VID_RCC,
-         pMsg->SetVariableFromFile(VID_CONFIG_FILE, g_szConfigFile) ? ERR_SUCCESS : ERR_IO_FAILURE);
+         pMsg->setFieldFromFile(VID_CONFIG_FILE, g_szConfigFile) ? ERR_SUCCESS : ERR_IO_FAILURE);
    }
    else
    {
@@ -830,7 +848,7 @@ void CommSession::getConfig(CSCPMessage *pMsg)
  */
 void CommSession::updateConfig(CSCPMessage *pRequest, CSCPMessage *pMsg)
 {
-   if (m_bMasterServer)
+   if (m_masterServer)
    {
       BYTE *pConfig;
       int hFile;
@@ -888,7 +906,7 @@ UINT32 CommSession::setupProxyConnection(CSCPMessage *pRequest)
    NXCPEncryptionContext *pSavedCtx;
    TCHAR szBuffer[32];
 
-   if (m_bMasterServer && (g_dwFlags & AF_ENABLE_PROXY))
+   if (m_masterServer && (g_dwFlags & AF_ENABLE_PROXY))
    {
       dwAddr = pRequest->GetVariableLong(VID_IP_ADDRESS);
       wPort = pRequest->GetVariableShort(VID_AGENT_PORT);
@@ -915,7 +933,7 @@ UINT32 CommSession::setupProxyConnection(CSCPMessage *pRequest)
             // Finish proxy connection setup
             pSavedCtx = m_pCtx;
             m_pCtx = PROXY_ENCRYPTION_CTX;
-            m_bProxyConnection = TRUE;
+            m_proxyConnection = true;
             dwResult = ERR_SUCCESS;
             m_hProxyReadThread = ThreadCreateEx(proxyReadThreadStarter, 0, this);
 
index 300b191..49ba4ea 100644 (file)
@@ -321,7 +321,7 @@ LONG H_IsSubagentLoaded(const TCHAR *pszCmd, const TCHAR *pArg, TCHAR *pValue)
 /**
  * Process unknown command by subagents
  */
-BOOL ProcessCmdBySubAgent(UINT32 dwCommand, CSCPMessage *pRequest, CSCPMessage *pResponse, void *session)
+BOOL ProcessCmdBySubAgent(UINT32 dwCommand, CSCPMessage *pRequest, CSCPMessage *pResponse, AbstractCommSession *session)
 {
    BOOL bResult = FALSE;
    UINT32 i;
diff --git a/src/agent/nxsagent/main.cpp b/src/agent/nxsagent/main.cpp
new file mode 100644 (file)
index 0000000..50e04a8
--- /dev/null
@@ -0,0 +1,378 @@
+/*
+** NetXMS Session Agent
+** Copyright (C) 2003-2014 Victor Kirhenshtein
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be usefu,,
+** but ITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+**
+** File: main.cpp
+**
+**/
+
+#include "nxsagent.h"
+
+#if HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+
+/**
+ * Connection port
+ */
+static UINT16 s_port = 28180;
+
+/**
+ * Socket
+ */
+static SOCKET s_socket = INVALID_SOCKET;
+
+/**
+ * Socket lock
+ */
+static MUTEX s_socketLock = MutexCreate();
+
+/**
+ * Protocol buffer
+ */
+static CSCP_BUFFER s_msgBuffer;
+
+/**
+ * Connect to master agent
+ */
+static bool ConnectToMasterAgent()
+{
+   _tprintf(_T("Connecting to master agent...\n"));
+   s_socket = socket(AF_INET, SOCK_STREAM, 0);
+   if (s_socket == INVALID_SOCKET)
+   {
+      _tprintf(_T("Call to socket() failed\n"));
+      return false;
+   }
+
+   // Fill in address structure
+   struct sockaddr_in sa;
+   memset(&sa, 0, sizeof(sa));
+   sa.sin_family = AF_INET;
+   sa.sin_addr.s_addr = inet_addr("127.0.0.1");
+   sa.sin_port = htons(s_port);
+
+   // Connect to server
+       if (ConnectEx(s_socket, (struct sockaddr *)&sa, sizeof(sa), 5000) == -1)
+   {
+      _tprintf(_T("Cannot establish connection with master agent\n"));
+      closesocket(s_socket);
+      s_socket = INVALID_SOCKET;
+      return false;
+   }
+   
+   return true;
+}
+
+/**
+ * Send message to master agent
+ */
+static bool SendMsg(CSCPMessage *msg)
+{
+   if (s_socket == INVALID_SOCKET)
+      return false;
+
+   CSCP_MESSAGE *rawMsg = msg->createMessage();
+   bool success = (SendEx(s_socket, rawMsg, ntohl(rawMsg->dwSize), 0, s_socketLock) == ntohl(rawMsg->dwSize));
+   free(rawMsg);
+   return success;
+}
+
+/**
+ * Send login message
+ */
+static void Login()
+{
+   CSCPMessage msg;
+   msg.SetCode(CMD_LOGIN);
+
+   DWORD sid;
+   ProcessIdToSessionId(GetCurrentProcessId(), &sid);
+   msg.SetVariable(VID_SESSION_ID, (UINT32)sid);
+
+   DWORD size;
+   WTS_CONNECTSTATE_CLASS *state;
+   INT16 sessionState = USER_SESSION_OTHER;
+   if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sid, WTSConnectState, (LPTSTR *)&state, &size))
+   {
+      switch(*state)
+      {
+         case WTSActive:
+            sessionState = USER_SESSION_ACTIVE;
+            break;
+         case WTSConnected:
+            sessionState = USER_SESSION_CONNECTED;
+            break;
+         case WTSDisconnected:
+            sessionState = USER_SESSION_DISCONNECTED;
+            break;
+         case WTSIdle:
+            sessionState = USER_SESSION_IDLE;
+            break;
+      }
+      WTSFreeMemory(state);
+   }
+
+   msg.SetVariable(VID_SESSION_STATE, sessionState);
+
+   TCHAR *sessionName;
+   if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sid, WTSWinStationName, &sessionName, &size))
+   {
+      if (*sessionName != 0)
+      {
+         msg.SetVariable(VID_NAME, sessionName);
+      }
+      else
+      {
+         TCHAR buffer[256];
+         _sntprintf(buffer, 256, _T("%s-%d"), (sessionState == USER_SESSION_DISCONNECTED) ? _T("Disconnected") : ((sessionState == USER_SESSION_IDLE) ? _T("Idle") : _T("Session")), sid);
+         msg.SetVariable(VID_NAME, buffer);
+      }
+      WTSFreeMemory(sessionName);
+   }
+
+   TCHAR userName[256];
+   size = 256;
+   if (GetUserName(userName, &size))
+   {
+      msg.SetVariable(VID_USER_NAME, userName);
+   }
+
+   SendMsg(&msg);
+}
+
+/**
+ * Process request from master agent
+ */
+static void ProcessRequest(CSCPMessage *request)
+{
+   CSCPMessage msg;
+
+   msg.SetCode(CMD_REQUEST_COMPLETED);
+   msg.SetId(request->GetId());
+
+   switch(request->GetCode())
+   {
+      case CMD_KEEPALIVE:
+         msg.SetVariable(VID_RCC, ERR_SUCCESS);
+         break;
+      case CMD_TAKE_SCREENSHOT:
+         TakeScreenshot(&msg);
+         break;
+      default:
+         msg.SetVariable(VID_RCC, ERR_UNKNOWN_COMMAND);
+         break;
+   }
+
+   SendMsg(&msg);
+}
+
+/**
+ * Message processing loop
+ */
+static void ProcessMessages()
+{
+   NXCPEncryptionContext *dummyCtx = NULL;
+   RecvNXCPMessage(0, NULL, &s_msgBuffer, 0, NULL, NULL, 0);
+   UINT32 rawMsgSize = 65536;
+   CSCP_MESSAGE *rawMsg = (CSCP_MESSAGE *)malloc(rawMsgSize);
+   while(1)
+   {
+      int err = RecvNXCPMessageEx(s_socket, &rawMsg, &s_msgBuffer, &rawMsgSize, &dummyCtx, NULL, 900000, 4 * 1024 * 1024);
+      if (err <= 0)
+         break;
+
+      // Check if message is too large
+      if (err == 1)
+         continue;
+
+      // Check for decryption failure
+      if (err == 2)
+         continue;
+
+      // Check for timeout
+      if (err == 3)
+      {
+         _tprintf(_T("Socket read timeout"));
+         break;
+      }
+
+      // Check that actual received packet size is equal to encoded in packet
+      if ((int)ntohl(rawMsg->dwSize) != err)
+      {
+         _tprintf(_T("Actual message size doesn't match wSize value (%d,%d)"), err, ntohl(rawMsg->dwSize));
+         continue;   // Bad packet, wait for next
+      }
+
+      UINT16 flags = ntohs(rawMsg->wFlags);
+      if (!(flags & MF_BINARY))
+      {
+         CSCPMessage *msg = new CSCPMessage(rawMsg);
+         TCHAR msgCodeName[256];
+         _tprintf(_T("Received message %s\n"), NXCPMessageCodeName(msg->GetCode(), msgCodeName));
+         ProcessRequest(msg);
+         delete msg;
+      }
+   }
+   free(rawMsg);
+}
+
+#ifdef _WIN32
+
+/**
+ * Window proc for event handling window
+ */
+static LRESULT CALLBACK EventHandlerWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+       switch(uMsg)
+       {
+      case WM_WTSSESSION_CHANGE:
+         _tprintf(_T(">> session change: %d\n"), wParam);
+         if ((wParam == WTS_CONSOLE_CONNECT) || (wParam == WTS_CONSOLE_DISCONNECT) ||
+             (wParam == WTS_REMOTE_CONNECT) || (wParam == WTS_REMOTE_DISCONNECT))
+         {
+            Login();
+         }
+         break;
+               default:
+                       return DefWindowProc(hWnd, uMsg, wParam, lParam);
+       }
+       return 0;
+}
+
+/**
+ * Event handling thread
+ */
+static THREAD_RESULT THREAD_CALL EventHandler(void *arg)
+{
+   HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
+
+       WNDCLASS wc;
+       memset(&wc, 0, sizeof(WNDCLASS));
+       wc.lpfnWndProc = EventHandlerWndProc;
+       wc.hInstance = hInstance;
+       wc.cbWndExtra = 0;
+       wc.lpszClassName = _T("NetXMS_SessionAgent_Wnd");
+       if (RegisterClass(&wc) == 0)
+   {
+      _tprintf(_T("Call to RegisterClass() failed\n"));
+      return THREAD_OK;
+   }
+
+       HWND hWnd = CreateWindow(_T("NetXMS_SessionAgent_Wnd"), _T("NetXMS Session Agent"), 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, hInstance, NULL);
+       if (hWnd == NULL)
+       {
+      _tprintf(_T("Cannot create window: %s"), GetSystemErrorText(GetLastError(), NULL, 0));
+               return THREAD_OK;
+       }
+
+   WTSRegisterSessionNotification(hWnd, NOTIFY_FOR_THIS_SESSION);
+
+       MSG msg;
+       while(GetMessage(&msg, NULL, 0, 0) > 0)
+       {
+               TranslateMessage(&msg);
+               DispatchMessage(&msg);
+       }
+
+   return THREAD_OK;
+}
+
+/**
+ * Get our own console window handle (an alternative to Microsoft's GetConsoleWindow)
+ */
+static HWND GetConsoleHWND()
+{
+       HWND hWnd;
+       DWORD wpid, cpid;
+
+   cpid = GetCurrentProcessId();
+   while(1)
+   {
+          hWnd = FindWindowEx(NULL, NULL, _T("ConsoleWindowClass"), NULL);
+      if (hWnd == NULL)
+         break;
+
+      GetWindowThreadProcessId(hWnd, &wpid);
+          if (cpid == wpid)
+         break;
+   }
+
+       return hWnd;
+}
+
+#endif
+
+/**
+ * Entry point
+ */
+int main(int argc, char *argv[])
+{
+   bool hideConsole = false;
+
+   int ch;
+   while((ch = getopt(argc, argv, "c:Hv")) != -1)
+   {
+               switch(ch)
+               {
+         case 'c':   // config
+            break;
+         case 'H':   // hide console
+            hideConsole = true;
+            break;
+                  case 'v':   // version
+            _tprintf(_T("NetXMS Session Agent Version ") NETXMS_VERSION_STRING _T(" Build ") NETXMS_VERSION_BUILD_STRING _T("\n"));
+                          exit(0);
+                          break;
+                  case '?':
+                          return 3;
+               }
+   }
+
+#ifdef _WIN32
+   WSADATA wsaData;
+       int wrc = WSAStartup(MAKEWORD(2, 2), &wsaData);
+   if (wrc != 0)
+   {
+      _tprintf(_T("WSAStartup() failed"));
+      return 1;
+   }
+
+   ThreadCreate(EventHandler, 0, NULL);
+
+   if (hideConsole)
+   {
+      HWND hWnd = GetConsoleHWND();
+      if (hWnd != NULL)
+         ShowWindow(hWnd, SW_HIDE);
+   }
+#endif
+
+   while(true)
+   {
+      if (!ConnectToMasterAgent())
+      {
+         ThreadSleep(30);
+         continue;
+      }
+
+      _tprintf(_T("*** Connected to master agent ***\n"));
+      Login();
+      ProcessMessages();
+   }
+   return 0;
+}
similarity index 56%
copy from include/netxmsdb.h
copy to src/agent/nxsagent/nxsagent.h
index 7e7891e..59f8bc2 100644 (file)
@@ -1,14 +1,14 @@
 /*
-** NetXMS - Network Management System
-** Copyright (C) 2003-2013 Victor Kirhenshtein
+** NetXMS Session Agent
+** Copyright (C) 2003-2014 Victor Kirhenshtein
 **
 ** This program is free software; you can redistribute it and/or modify
 ** it under the terms of the GNU General Public License as published by
 ** the Free Software Foundation; either version 2 of the License, or
 ** (at your option) any later version.
 **
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** This program is distributed in the hope that it will be usefu,,
+** but ITHOUT ANY WARRANTY; without even the implied warranty of
 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ** GNU General Public License for more details.
 **
 ** along with this program; if not, write to the Free Software
 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 **
-** File: netxmsdb.h
+** File: nxsagent.h
 **
 **/
 
-#ifndef _netxmsdb_h
-#define _netxmsdb_h
+#ifndef _nxsagent_h_
+#define _nxsagent_h_
 
-#define DB_FORMAT_VERSION   333
+#define _WIN32_WINNT 0x0501
+
+#include <nms_common.h>
+#include <nms_util.h>
+#include <nms_threads.h>
+#include <nms_agent.h>
+#include <nms_cscp.h>
+#include <nxcpapi.h>
+#include <wtsapi32.h>
+
+void TakeScreenshot(CSCPMessage *response);
+bool SaveBitmapToPng(HBITMAP hBitmap, const TCHAR *fileName);
 
 #endif
similarity index 76%
copy from src/agent/subagents/winnt/winnt.vcproj
copy to src/agent/nxsagent/nxsagent.vcproj
index be9db8a..ee2e277 100644 (file)
@@ -1,10 +1,10 @@
-<?xml version="1.0" encoding="windows-1251"?>
+<?xml version="1.0" encoding="Windows-1252"?>
 <VisualStudioProject
        ProjectType="Visual C++"
        Version="8.00"
-       Name="winnt"
-       ProjectGUID="{E95263B5-A248-4163-95F3-E33CA679AEB3}"
-       RootNamespace="winnt"
+       Name="nxsagent"
+       ProjectGUID="{9C6790BA-385D-476D-944A-552C87018733}"
+       RootNamespace="nxsagent"
        Keyword="Win32Proj"
        >
        <Platforms>
@@ -22,7 +22,7 @@
                        Name="Debug|Win32"
                        OutputDirectory="$(SolutionDir)$(ConfigurationName)"
                        IntermediateDirectory="$(ConfigurationName)"
-                       ConfigurationType="2"
+                       ConfigurationType="1"
                        CharacterSet="1"
                        >
                        <Tool
                        <Tool
                                Name="VCCLCompilerTool"
                                Optimization="0"
-                               AdditionalIncludeDirectories="..\..\..\..\include"
-                               PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;WINNT_EXPORTS"
+                               AdditionalIncludeDirectories="..\..\..\include;..\..\libpng"
+                               PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
                                MinimalRebuild="true"
                                BasicRuntimeChecks="3"
                                RuntimeLibrary="3"
                                UsePrecompiledHeader="0"
                                WarningLevel="3"
-                               Detect64BitPortabilityProblems="false"
+                               Detect64BitPortabilityProblems="true"
                                DebugInformationFormat="4"
                        />
                        <Tool
                        />
                        <Tool
                                Name="VCLinkerTool"
-                               AdditionalDependencies="netapi32.lib psapi.lib wtsapi32.lib ws2_32.lib iphlpapi.lib msi.lib"
-                               OutputFile="$(OutDir)\$(ProjectName).nsm"
+                               AdditionalDependencies="ws2_32.lib wtsapi32.lib"
                                LinkIncremental="2"
                                GenerateDebugInformation="true"
-                               SubSystem="2"
+                               SubSystem="1"
                                TargetMachine="1"
                        />
                        <Tool
                        />
                </Configuration>
                <Configuration
-                       Name="Debug|x64"
-                       OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
-       &