Merge branch 'develop' into fis
authorVictor Kirhenshtein <victor@netxms.org>
Thu, 6 Feb 2014 18:37:41 +0000 (20:37 +0200)
committerVictor Kirhenshtein <victor@netxms.org>
Thu, 6 Feb 2014 18:37:41 +0000 (20:37 +0200)
417 files changed:
COPYING
ChangeLog
android/src/agent/.classpath
android/src/agent/libs/android-support-v4.jar [new file with mode: 0644]
android/src/agent/res/drawable-hdpi-v11/ic_stat_connected.png [new file with mode: 0644]
android/src/agent/res/drawable-hdpi-v11/ic_stat_disconnected.png [new file with mode: 0644]
android/src/agent/res/drawable-hdpi-v9/ic_stat_connected.png [new file with mode: 0644]
android/src/agent/res/drawable-hdpi-v9/ic_stat_disconnected.png [new file with mode: 0644]
android/src/agent/res/drawable-ldpi-v11/ic_stat_connected.png [new file with mode: 0644]
android/src/agent/res/drawable-ldpi-v11/ic_stat_disconnected.png [new file with mode: 0644]
android/src/agent/res/drawable-ldpi-v9/ic_stat_connected.png [new file with mode: 0644]
android/src/agent/res/drawable-ldpi-v9/ic_stat_disconnected.png [new file with mode: 0644]
android/src/agent/res/drawable-mdpi-v11/ic_stat_connected.png [new file with mode: 0644]
android/src/agent/res/drawable-mdpi-v11/ic_stat_disconnected.png [new file with mode: 0644]
android/src/agent/res/drawable-mdpi-v9/ic_stat_connected.png [new file with mode: 0644]
android/src/agent/res/drawable-mdpi-v9/ic_stat_disconnected.png [new file with mode: 0644]
android/src/agent/res/drawable-xhdpi-v11/ic_stat_connected.png [new file with mode: 0644]
android/src/agent/res/drawable-xhdpi-v11/ic_stat_disconnected.png [new file with mode: 0644]
android/src/agent/res/drawable-xhdpi-v9/ic_stat_connected.png [new file with mode: 0644]
android/src/agent/res/drawable-xhdpi-v9/ic_stat_disconnected.png [new file with mode: 0644]
android/src/agent/res/drawable-xhdpi/ic_stat_connected.png [new file with mode: 0644]
android/src/agent/res/drawable-xhdpi/ic_stat_disconnected.png [new file with mode: 0644]
android/src/agent/res/values/strings.xml
android/src/agent/res/values/strings_arrays.xml
android/src/agent/res/xml-v14/preferences.xml
android/src/agent/res/xml/preferences.xml
android/src/agent/src/org/netxms/agent/android/main/settings/CustomSwitchPreference.java [new file with mode: 0644]
android/src/agent/src/org/netxms/agent/android/service/AgentConnectorService.java
android/src/console/res/drawable-hdpi/entire_network.png [new file with mode: 0644]
android/src/console/res/drawable-ldpi/entire_network.png [new file with mode: 0644]
android/src/console/res/drawable-mdpi/entire_network.png [new file with mode: 0644]
android/src/console/res/drawable-xhdpi/entire_network.png [new file with mode: 0644]
android/src/console/res/drawable/object_subnet.png [new file with mode: 0644]
android/src/console/res/drawable/object_zone.png [new file with mode: 0644]
android/src/console/res/values/strings.xml
android/src/console/res/xml-v14/preference_connection.xml
android/src/console/res/xml-v14/preference_global.xml
android/src/console/res/xml-v14/preference_notifications.xml
android/src/console/res/xml/preference_connection.xml
android/src/console/res/xml/preference_headers.xml
android/src/console/res/xml/preference_headers_legacy.xml
android/src/console/res/xml/preference_interface.xml
android/src/console/src/org/netxms/ui/android/main/activities/HomeScreen.java
android/src/console/src/org/netxms/ui/android/main/activities/NodeBrowser.java
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/ObjectListAdapter.java
android/src/console/src/org/netxms/ui/android/main/settings/CustomSwitchPreference.java [new file with mode: 0644]
android/src/console/src/org/netxms/ui/android/service/ClientConnectorService.java
configure.ac
doc/internal/licensing_problems.txt
doc/misc/embedded_nxcp.c [new file with mode: 0644]
include/netxms-version.h
include/netxmsdb.h
include/nms_agent.h
include/nms_cscp.h
include/nms_util.h
include/nxclapi.h
include/nxcpapi.h
include/nxtools.h
sql/objtools.in
sql/schema.in
sql/setup.in
src/agent/core/comm.cpp
src/agent/core/exec.cpp
src/agent/core/getparam.cpp
src/agent/core/nxagentd.cpp
src/agent/core/nxagentd.h
src/agent/core/register.cpp
src/agent/core/session.cpp
src/agent/install/nxagent-x64.iss
src/agent/install/nxagent.iss
src/agent/install/setup.iss
src/agent/subagents/Makefile.am
src/agent/subagents/dbquery/Makefile.am
src/agent/subagents/dbquery/conn.cpp
src/agent/subagents/dbquery/dbquery.cpp
src/agent/subagents/dbquery/dbquery.h
src/agent/subagents/dbquery/direct.cpp
src/agent/subagents/dbquery/poll.cpp
src/agent/subagents/linux/net.cpp
src/agent/subagents/linux/proc.cpp
src/agent/subagents/linux/system.cpp
src/agent/subagents/portCheck/http.cpp
src/agent/subagents/sunos/cpu.cpp
src/agent/subagents/sunos/disk.cpp
src/agent/subagents/sunos/iostat.cpp
src/agent/subagents/sunos/mac_dlpi.cpp
src/agent/subagents/sunos/main.cpp
src/agent/subagents/sunos/net.cpp
src/agent/subagents/sunos/process.cpp
src/agent/subagents/sunos/sunos_subagent.h
src/agent/subagents/sunos/system.cpp
src/agent/subagents/ups/Makefile.am
src/agent/subagents/ups/apc.cpp
src/agent/subagents/ups/bcmxcp.cpp
src/agent/subagents/ups/main.cpp
src/agent/subagents/ups/metasys.cpp [new file with mode: 0644]
src/agent/subagents/ups/microdowell.cpp
src/agent/subagents/ups/serial.cpp
src/agent/subagents/ups/ups.cpp
src/agent/subagents/ups/ups.h
src/agent/subagents/ups/ups.vcproj
src/agent/subagents/ups/usb.cpp
src/db/dbdrv/informix/informix.cpp
src/db/dbdrv/mysql/mysql.cpp
src/db/dbdrv/mysql/mysqldrv.h
src/db/dbdrv/oracle/oracle.cpp
src/db/dbdrv/pgsql/pgsql.cpp
src/db/dbdrv/sqlite/sqlite.cpp
src/db/libnxdb/session.cpp
src/java/certificate-manager/pom.xml
src/java/mobile-agent/pom.xml
src/java/nebula/org.netxms.nebula.widgets.gallery/src/org/netxms/nebula/animation/movement/BounceOut.java
src/java/nebula/org.netxms.nebula.widgets.gallery/src/org/netxms/nebula/animation/movement/ElasticOut.java
src/java/netxms-base/pom.xml
src/java/netxms-base/src/main/java/org/netxms/base/NXCPCodes.java
src/java/netxms-base/src/main/java/org/netxms/base/NXCommon.java
src/java/netxms-client-api/pom.xml
src/java/netxms-client-api/src/main/java/org/netxms/api/client/users/User.java
src/java/netxms-client-api/src/main/java/org/netxms/api/client/users/UserManager.java
src/java/netxms-client/pom.xml
src/java/netxms-client/src/main/java/org/netxms/client/NXCNotification.java
src/java/netxms-client/src/main/java/org/netxms/client/NXCSession.java
src/java/netxms-client/src/main/java/org/netxms/client/events/Alarm.java
src/java/netxms-client/src/main/java/org/netxms/client/objecttools/ObjectTool.java
src/java/netxms-client/src/test/java/org/netxms/client/ConnectionTest.java
src/java/netxms-client/src/test/java/org/netxms/client/SnmpTest.java
src/java/netxms-eclipse/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/Messages.java
src/java/netxms-eclipse/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/dialogs/AcknowledgeCustomTimeDialog.java [new file with mode: 0644]
src/java/netxms-eclipse/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/dialogs/EditCommentDialog.java
src/java/netxms-eclipse/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/editors/AcknowledgeTimeEditor.java [new file with mode: 0644]
src/java/netxms-eclipse/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/messages.properties
src/java/netxms-eclipse/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/messages_cs.properties
src/java/netxms-eclipse/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/messages_es.properties
src/java/netxms-eclipse/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/messages_ru.properties
src/java/netxms-eclipse/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/messages_zh_CN.properties
src/java/netxms-eclipse/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/preferencepages/Alarms.java
src/java/netxms-eclipse/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/views/AlarmComments.java
src/java/netxms-eclipse/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/views/AlarmDetails.java
src/java/netxms-eclipse/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/widgets/AlarmCommentsEditor.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/AlarmAcknowledgeTimeFunctions.java [new file with mode: 0644]
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/DataComparisonBirtChart.java
src/java/netxms-eclipse/Charts/src/org/netxms/ui/eclipse/charts/widgets/GaugeWidget.java
src/java/netxms-eclipse/Charts/src/org/netxms/ui/eclipse/charts/widgets/GenericBirtChart.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/src/org/netxms/ui/eclipse/tools/WidgetHelper.java
src/java/netxms-eclipse/Dashboard/OSGI-INF/l10n/bundle_es.properties
src/java/netxms-eclipse/Dashboard/OSGI-INF/l10n/bundle_ru.properties
src/java/netxms-eclipse/Dashboard/OSGI-INF/l10n/bundle_zh_CN.properties
src/java/netxms-eclipse/Dashboard/src/org/netxms/ui/eclipse/dashboard/Messages.java
src/java/netxms-eclipse/Dashboard/src/org/netxms/ui/eclipse/dashboard/messages.properties
src/java/netxms-eclipse/Dashboard/src/org/netxms/ui/eclipse/dashboard/messages_cs.properties
src/java/netxms-eclipse/Dashboard/src/org/netxms/ui/eclipse/dashboard/messages_es.properties
src/java/netxms-eclipse/Dashboard/src/org/netxms/ui/eclipse/dashboard/messages_ru.properties
src/java/netxms-eclipse/Dashboard/src/org/netxms/ui/eclipse/dashboard/messages_zh_CN.properties
src/java/netxms-eclipse/Dashboard/src/org/netxms/ui/eclipse/dashboard/propertypages/AbstractChart.java
src/java/netxms-eclipse/Dashboard/src/org/netxms/ui/eclipse/dashboard/propertypages/TableComparisonChart.java
src/java/netxms-eclipse/Dashboard/src/org/netxms/ui/eclipse/dashboard/widgets/BarChartElement.java
src/java/netxms-eclipse/Dashboard/src/org/netxms/ui/eclipse/dashboard/widgets/LineChartElement.java
src/java/netxms-eclipse/Dashboard/src/org/netxms/ui/eclipse/dashboard/widgets/TableBarChartElement.java
src/java/netxms-eclipse/Dashboard/src/org/netxms/ui/eclipse/dashboard/widgets/TableTubeChartElement.java
src/java/netxms-eclipse/Dashboard/src/org/netxms/ui/eclipse/dashboard/widgets/TubeChartElement.java
src/java/netxms-eclipse/Dashboard/src/org/netxms/ui/eclipse/dashboard/widgets/internal/AbstractChartConfig.java
src/java/netxms-eclipse/Dashboard/src/org/netxms/ui/eclipse/dashboard/widgets/internal/LineChartConfig.java
src/java/netxms-eclipse/Dashboard/src/org/netxms/ui/eclipse/dashboard/widgets/internal/TableComparisonChartConfig.java
src/java/netxms-eclipse/LogViewer/src/org/netxms/ui/eclipse/logviewer/widgets/UserConditionEditor.java
src/java/netxms-eclipse/NetworkMaps/META-INF/MANIFEST.MF
src/java/netxms-eclipse/NetworkMaps/plugin.xml
src/java/netxms-eclipse/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/Activator.java
src/java/netxms-eclipse/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/PreferenceInitializer.java [new file with mode: 0644]
src/java/netxms-eclipse/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/propertypages/MapBackground.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/PredefinedMap.java
src/java/netxms-eclipse/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/views/helpers/ExtendedGraphViewer.java
src/java/netxms-eclipse/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/views/helpers/MapContentProvider.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/NodeLastValuesFigure.java
src/java/netxms-eclipse/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/views/helpers/ObjectFigure.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/ObjectFigureLargeLabel.java [new file with mode: 0644]
src/java/netxms-eclipse/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/views/helpers/ObjectFigureSmallLabel.java
src/java/netxms-eclipse/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/widgets/NetworkMapWidget.java
src/java/netxms-eclipse/ObjectBrowser/OSGI-INF/l10n/bundle_es.properties
src/java/netxms-eclipse/ObjectBrowser/OSGI-INF/l10n/bundle_ru.properties
src/java/netxms-eclipse/ObjectBrowser/OSGI-INF/l10n/bundle_zh_CN.properties
src/java/netxms-eclipse/ObjectBrowser/src/org/netxms/ui/eclipse/objectbrowser/Messages.java
src/java/netxms-eclipse/ObjectBrowser/src/org/netxms/ui/eclipse/objectbrowser/dialogs/ObjectSelectionDialog.java
src/java/netxms-eclipse/ObjectBrowser/src/org/netxms/ui/eclipse/objectbrowser/messages.properties
src/java/netxms-eclipse/ObjectBrowser/src/org/netxms/ui/eclipse/objectbrowser/messages_cs.properties
src/java/netxms-eclipse/ObjectBrowser/src/org/netxms/ui/eclipse/objectbrowser/messages_es.properties
src/java/netxms-eclipse/ObjectBrowser/src/org/netxms/ui/eclipse/objectbrowser/messages_ru.properties
src/java/netxms-eclipse/ObjectBrowser/src/org/netxms/ui/eclipse/objectbrowser/messages_zh_CN.properties
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/ObjectTree.java
src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/propertypages/AccessControl.java
src/java/netxms-eclipse/ObjectTools/OSGI-INF/l10n/bundle_cs.properties
src/java/netxms-eclipse/ObjectTools/OSGI-INF/l10n/bundle_es.properties
src/java/netxms-eclipse/ObjectTools/OSGI-INF/l10n/bundle_ru.properties
src/java/netxms-eclipse/ObjectTools/OSGI-INF/l10n/bundle_zh_CN.properties
src/java/netxms-eclipse/ObjectTools/src/org/netxms/ui/eclipse/objecttools/Messages.java
src/java/netxms-eclipse/ObjectTools/src/org/netxms/ui/eclipse/objecttools/ObjectToolsDynamicMenu.java
src/java/netxms-eclipse/ObjectTools/src/org/netxms/ui/eclipse/objecttools/messages.properties
src/java/netxms-eclipse/ObjectTools/src/org/netxms/ui/eclipse/objecttools/messages_cs.properties
src/java/netxms-eclipse/ObjectTools/src/org/netxms/ui/eclipse/objecttools/messages_es.properties
src/java/netxms-eclipse/ObjectTools/src/org/netxms/ui/eclipse/objecttools/messages_ru.properties
src/java/netxms-eclipse/ObjectTools/src/org/netxms/ui/eclipse/objecttools/messages_zh_CN.properties
src/java/netxms-eclipse/ObjectTools/src/org/netxms/ui/eclipse/objecttools/propertypages/AccessControl.java
src/java/netxms-eclipse/ObjectTools/src/org/netxms/ui/eclipse/objecttools/propertypages/General.java
src/java/netxms-eclipse/ObjectTools/src/org/netxms/ui/eclipse/objecttools/views/FileViewer.java
src/java/netxms-eclipse/ObjectTools/src/org/netxms/ui/eclipse/objecttools/views/ObjectToolsEditor.java
src/java/netxms-eclipse/ObjectTools/src/org/netxms/ui/eclipse/objecttools/views/helpers/ObjectToolsLabelProvider.java
src/java/netxms-eclipse/PerfView/OSGI-INF/l10n/bundle_es.properties
src/java/netxms-eclipse/PerfView/OSGI-INF/l10n/bundle_ru.properties
src/java/netxms-eclipse/PerfView/OSGI-INF/l10n/bundle_zh_CN.properties
src/java/netxms-eclipse/PerfView/src/org/netxms/ui/eclipse/perfview/ChartConfig.java
src/java/netxms-eclipse/PerfView/src/org/netxms/ui/eclipse/perfview/Messages.java
src/java/netxms-eclipse/PerfView/src/org/netxms/ui/eclipse/perfview/PerfTabGraphSettings.java
src/java/netxms-eclipse/PerfView/src/org/netxms/ui/eclipse/perfview/messages.properties
src/java/netxms-eclipse/PerfView/src/org/netxms/ui/eclipse/perfview/messages_cs.properties
src/java/netxms-eclipse/PerfView/src/org/netxms/ui/eclipse/perfview/messages_es.properties
src/java/netxms-eclipse/PerfView/src/org/netxms/ui/eclipse/perfview/messages_ru.properties
src/java/netxms-eclipse/PerfView/src/org/netxms/ui/eclipse/perfview/messages_zh_CN.properties
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/objecttabs/internal/PerfTabGraph.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/propertypages/PerfTab.java
src/java/netxms-eclipse/PerfView/src/org/netxms/ui/eclipse/perfview/propertypages/PredefinedGraph.java
src/java/netxms-eclipse/PerfView/src/org/netxms/ui/eclipse/perfview/views/HistoricalGraphView.java
src/java/netxms-eclipse/PerfView/src/org/netxms/ui/eclipse/perfview/widgets/YAxisRangeEditor.java [new file with mode: 0644]
src/java/netxms-eclipse/Reporter/OSGI-INF/l10n/bundle_cs.properties
src/java/netxms-eclipse/Reporter/src/org/netxms/ui/eclipse/reporter/widgets/UserFieldEditor.java
src/java/netxms-eclipse/SNMP/src/org/netxms/ui/eclipse/snmp/Activator.java
src/java/netxms-eclipse/SNMP/src/org/netxms/ui/eclipse/snmp/shared/MibCache.java
src/java/netxms-eclipse/UserManager/OSGI-INF/l10n/bundle.properties
src/java/netxms-eclipse/UserManager/OSGI-INF/l10n/bundle_cs.properties
src/java/netxms-eclipse/UserManager/OSGI-INF/l10n/bundle_es.properties
src/java/netxms-eclipse/UserManager/OSGI-INF/l10n/bundle_ru.properties
src/java/netxms-eclipse/UserManager/OSGI-INF/l10n/bundle_zh_CN.properties
src/java/netxms-eclipse/UserManager/plugin.xml
src/java/netxms-eclipse/UserManager/src/org/netxms/ui/eclipse/usermanager/dialogs/SelectUserDialog.java
src/java/netxms-eclipse/UserManager/src/org/netxms/ui/eclipse/usermanager/messages_cs.properties
src/java/netxms-eclipse/UserManager/src/org/netxms/ui/eclipse/usermanager/messages_es.properties
src/java/netxms-eclipse/UserManager/src/org/netxms/ui/eclipse/usermanager/messages_ru.properties
src/java/netxms-eclipse/UserManager/src/org/netxms/ui/eclipse/usermanager/messages_zh_CN.properties
src/java/netxms-eclipse/UserManager/src/org/netxms/ui/eclipse/usermanager/propertypages/GroupMembership.java [copied from src/java/netxms-eclipse/UserManager/src/org/netxms/ui/eclipse/usermanager/propertypages/Members.java with 77% similarity]
src/java/netxms-eclipse/UserManager/src/org/netxms/ui/eclipse/usermanager/propertypages/Members.java
src/java/pom.xml
src/libnetxms/agent.cpp
src/libnetxms/crypto.cpp
src/libnetxms/dload.cpp
src/libnetxms/getopt.c
src/libnetxms/message.cpp
src/libnetxms/nxcp.cpp
src/libnetxms/serial.cpp
src/libnetxms/tools.cpp
src/libstrophe/sasl.c
src/server/core/actions.cpp
src/server/core/alarm.cpp
src/server/core/config.cpp
src/server/core/dc_nxsl.cpp
src/server/core/dcobject.cpp
src/server/core/dctable.cpp
src/server/core/dctthreshold.cpp
src/server/core/epp.cpp
src/server/core/main.cpp
src/server/core/mdsession.cpp
src/server/core/netinfo.cpp
src/server/core/objtools.cpp
src/server/core/session.cpp
src/server/core/userdb.cpp
src/server/core/userdb_objects.cpp
src/server/include/nms_alarm.h
src/server/include/nms_core.h
src/server/include/nms_users.h
src/server/libnxsrv/snmp.cpp
src/server/netxmsd/netxmsd.cpp
src/server/smsdrv/generic/Makefile.am
src/server/tools/nxdbmgr/upgrade.cpp
src/snmp/libnxsnmp/pdu.cpp
src/sqlite/sqlite3.c
webui/webapp/ActionManager/.settings/org.eclipse.jdt.core.prefs [deleted file]
webui/webapp/AgentManager/.settings/org.eclipse.jdt.core.prefs [deleted file]
webui/webapp/AlarmViewer/plugin.xml
webui/webapp/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/Messages.java
webui/webapp/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/PreferenceInitializer.java [copied from src/java/netxms-client/src/test/java/org/netxms/client/ConnectionTest.java with 50% similarity]
webui/webapp/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/dialogs/AcknowledgeCustomTimeDialog.java [new file with mode: 0644]
webui/webapp/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/dialogs/EditCommentDialog.java
webui/webapp/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/editors/AcknowledgeTimeEditor.java [new file with mode: 0644]
webui/webapp/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/messages.properties
webui/webapp/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/messages_cs.properties
webui/webapp/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/messages_es.properties
webui/webapp/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/messages_ru.properties
webui/webapp/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/messages_zh_CN.properties
webui/webapp/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/preferencepages/Alarms.java [copied from src/java/netxms-eclipse/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/preferencepages/Alarms.java with 70% similarity]
webui/webapp/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/views/AlarmComments.java
webui/webapp/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/views/AlarmDetails.java
webui/webapp/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/widgets/AlarmCommentsEditor.java
webui/webapp/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/widgets/AlarmList.java
webui/webapp/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/widgets/helpers/AlarmAcknowledgeTimeFunctions.java [new file with mode: 0644]
webui/webapp/AlarmViewer/src/org/netxms/ui/eclipse/alarmviewer/widgets/helpers/AlarmListLabelProvider.java
webui/webapp/Charts/src/org/netxms/ui/eclipse/charts/api/DataChart.java
webui/webapp/Charts/src/org/netxms/ui/eclipse/charts/figures/BirtChartFigure.java
webui/webapp/Charts/src/org/netxms/ui/eclipse/charts/widgets/DataComparisonBirtChart.java
webui/webapp/Charts/src/org/netxms/ui/eclipse/charts/widgets/GaugeWidget.java
webui/webapp/Charts/src/org/netxms/ui/eclipse/charts/widgets/GenericBirtChart.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/src/org/netxms/ui/eclipse/tools/WidgetHelper.java
webui/webapp/Dashboard/OSGI-INF/l10n/bundle_es.properties
webui/webapp/Dashboard/OSGI-INF/l10n/bundle_ru.properties
webui/webapp/Dashboard/OSGI-INF/l10n/bundle_zh_CN.properties
webui/webapp/Dashboard/src/org/netxms/ui/eclipse/dashboard/Messages.java
webui/webapp/Dashboard/src/org/netxms/ui/eclipse/dashboard/messages.properties
webui/webapp/Dashboard/src/org/netxms/ui/eclipse/dashboard/messages_cs.properties
webui/webapp/Dashboard/src/org/netxms/ui/eclipse/dashboard/messages_es.properties
webui/webapp/Dashboard/src/org/netxms/ui/eclipse/dashboard/messages_ru.properties
webui/webapp/Dashboard/src/org/netxms/ui/eclipse/dashboard/messages_zh_CN.properties
webui/webapp/Dashboard/src/org/netxms/ui/eclipse/dashboard/propertypages/AbstractChart.java
webui/webapp/Dashboard/src/org/netxms/ui/eclipse/dashboard/propertypages/TableComparisonChart.java
webui/webapp/Dashboard/src/org/netxms/ui/eclipse/dashboard/widgets/BarChartElement.java
webui/webapp/Dashboard/src/org/netxms/ui/eclipse/dashboard/widgets/LineChartElement.java
webui/webapp/Dashboard/src/org/netxms/ui/eclipse/dashboard/widgets/TableBarChartElement.java
webui/webapp/Dashboard/src/org/netxms/ui/eclipse/dashboard/widgets/TableTubeChartElement.java
webui/webapp/Dashboard/src/org/netxms/ui/eclipse/dashboard/widgets/TubeChartElement.java
webui/webapp/Dashboard/src/org/netxms/ui/eclipse/dashboard/widgets/internal/AbstractChartConfig.java
webui/webapp/Dashboard/src/org/netxms/ui/eclipse/dashboard/widgets/internal/LineChartConfig.java
webui/webapp/Dashboard/src/org/netxms/ui/eclipse/dashboard/widgets/internal/TableComparisonChartConfig.java
webui/webapp/LogViewer/src/org/netxms/ui/eclipse/logviewer/widgets/UserConditionEditor.java
webui/webapp/NetworkMaps/META-INF/MANIFEST.MF
webui/webapp/NetworkMaps/plugin.xml
webui/webapp/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/Activator.java
webui/webapp/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/PreferenceInitializer.java [new file with mode: 0644]
webui/webapp/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/propertypages/MapBackground.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/MapContentProvider.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/NodeLastValuesFigure.java
webui/webapp/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/views/helpers/ObjectFigure.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/ObjectFigureLargeLabel.java [new file with mode: 0644]
webui/webapp/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/views/helpers/ObjectFigureSmallLabel.java
webui/webapp/NetworkMaps/src/org/netxms/ui/eclipse/networkmaps/widgets/NetworkMapWidget.java
webui/webapp/ObjectBrowser/OSGI-INF/l10n/bundle_es.properties
webui/webapp/ObjectBrowser/OSGI-INF/l10n/bundle_ru.properties
webui/webapp/ObjectBrowser/OSGI-INF/l10n/bundle_zh_CN.properties
webui/webapp/ObjectBrowser/src/org/netxms/ui/eclipse/objectbrowser/Messages.java
webui/webapp/ObjectBrowser/src/org/netxms/ui/eclipse/objectbrowser/dialogs/ObjectSelectionDialog.java
webui/webapp/ObjectBrowser/src/org/netxms/ui/eclipse/objectbrowser/messages.properties
webui/webapp/ObjectBrowser/src/org/netxms/ui/eclipse/objectbrowser/messages_cs.properties
webui/webapp/ObjectBrowser/src/org/netxms/ui/eclipse/objectbrowser/messages_es.properties
webui/webapp/ObjectBrowser/src/org/netxms/ui/eclipse/objectbrowser/messages_ru.properties
webui/webapp/ObjectBrowser/src/org/netxms/ui/eclipse/objectbrowser/messages_zh_CN.properties
webui/webapp/ObjectBrowser/src/org/netxms/ui/eclipse/objectbrowser/views/ObjectBrowser.java
webui/webapp/ObjectBrowser/src/org/netxms/ui/eclipse/objectbrowser/widgets/ObjectTree.java
webui/webapp/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/propertypages/AccessControl.java
webui/webapp/ObjectTools/OSGI-INF/l10n/bundle_cs.properties
webui/webapp/ObjectTools/OSGI-INF/l10n/bundle_es.properties
webui/webapp/ObjectTools/OSGI-INF/l10n/bundle_ru.properties
webui/webapp/ObjectTools/OSGI-INF/l10n/bundle_zh_CN.properties
webui/webapp/ObjectTools/src/org/netxms/ui/eclipse/objecttools/Messages.java
webui/webapp/ObjectTools/src/org/netxms/ui/eclipse/objecttools/ObjectToolsDynamicMenu.java
webui/webapp/ObjectTools/src/org/netxms/ui/eclipse/objecttools/messages.properties
webui/webapp/ObjectTools/src/org/netxms/ui/eclipse/objecttools/messages_cs.properties
webui/webapp/ObjectTools/src/org/netxms/ui/eclipse/objecttools/messages_es.properties
webui/webapp/ObjectTools/src/org/netxms/ui/eclipse/objecttools/messages_ru.properties
webui/webapp/ObjectTools/src/org/netxms/ui/eclipse/objecttools/messages_zh_CN.properties
webui/webapp/ObjectTools/src/org/netxms/ui/eclipse/objecttools/propertypages/AccessControl.java
webui/webapp/ObjectTools/src/org/netxms/ui/eclipse/objecttools/propertypages/General.java
webui/webapp/ObjectTools/src/org/netxms/ui/eclipse/objecttools/views/ObjectToolsEditor.java
webui/webapp/ObjectTools/src/org/netxms/ui/eclipse/objecttools/views/helpers/ObjectToolsLabelProvider.java
webui/webapp/PerfView/OSGI-INF/l10n/bundle_es.properties
webui/webapp/PerfView/OSGI-INF/l10n/bundle_ru.properties
webui/webapp/PerfView/OSGI-INF/l10n/bundle_zh_CN.properties
webui/webapp/PerfView/src/org/netxms/ui/eclipse/perfview/ChartConfig.java
webui/webapp/PerfView/src/org/netxms/ui/eclipse/perfview/Messages.java
webui/webapp/PerfView/src/org/netxms/ui/eclipse/perfview/PerfTabGraphSettings.java
webui/webapp/PerfView/src/org/netxms/ui/eclipse/perfview/messages.properties
webui/webapp/PerfView/src/org/netxms/ui/eclipse/perfview/messages_cs.properties
webui/webapp/PerfView/src/org/netxms/ui/eclipse/perfview/messages_es.properties
webui/webapp/PerfView/src/org/netxms/ui/eclipse/perfview/messages_ru.properties
webui/webapp/PerfView/src/org/netxms/ui/eclipse/perfview/messages_zh_CN.properties
webui/webapp/PerfView/src/org/netxms/ui/eclipse/perfview/objecttabs/PerformanceTab.java
webui/webapp/PerfView/src/org/netxms/ui/eclipse/perfview/objecttabs/internal/PerfTabGraph.java
webui/webapp/PerfView/src/org/netxms/ui/eclipse/perfview/propertypages/General.java
webui/webapp/PerfView/src/org/netxms/ui/eclipse/perfview/propertypages/PerfTab.java
webui/webapp/PerfView/src/org/netxms/ui/eclipse/perfview/propertypages/PredefinedGraph.java
webui/webapp/PerfView/src/org/netxms/ui/eclipse/perfview/views/HistoricalGraphView.java
webui/webapp/PerfView/src/org/netxms/ui/eclipse/perfview/widgets/YAxisRangeEditor.java [new file with mode: 0644]
webui/webapp/Reporter/OSGI-INF/l10n/bundle_cs.properties
webui/webapp/Reporter/src/org/netxms/ui/eclipse/reporter/widgets/UserFieldEditor.java
webui/webapp/SNMP/src/org/netxms/ui/eclipse/snmp/Activator.java
webui/webapp/SNMP/src/org/netxms/ui/eclipse/snmp/shared/MibCache.java
webui/webapp/UserManager/OSGI-INF/l10n/bundle.properties
webui/webapp/UserManager/OSGI-INF/l10n/bundle_cs.properties
webui/webapp/UserManager/OSGI-INF/l10n/bundle_es.properties
webui/webapp/UserManager/OSGI-INF/l10n/bundle_ru.properties
webui/webapp/UserManager/OSGI-INF/l10n/bundle_zh_CN.properties
webui/webapp/UserManager/plugin.xml
webui/webapp/UserManager/src/org/netxms/ui/eclipse/usermanager/dialogs/CreateNewCertificateDialog.java
webui/webapp/UserManager/src/org/netxms/ui/eclipse/usermanager/dialogs/SelectUserDialog.java
webui/webapp/UserManager/src/org/netxms/ui/eclipse/usermanager/messages_cs.properties
webui/webapp/UserManager/src/org/netxms/ui/eclipse/usermanager/messages_es.properties
webui/webapp/UserManager/src/org/netxms/ui/eclipse/usermanager/messages_ru.properties
webui/webapp/UserManager/src/org/netxms/ui/eclipse/usermanager/messages_zh_CN.properties
webui/webapp/UserManager/src/org/netxms/ui/eclipse/usermanager/propertypages/GroupMembership.java [copied from src/java/netxms-eclipse/UserManager/src/org/netxms/ui/eclipse/usermanager/propertypages/Members.java with 77% similarity]
webui/webapp/UserManager/src/org/netxms/ui/eclipse/usermanager/propertypages/Members.java

diff --git a/COPYING b/COPYING
index 1fb4e5b..e483281 100644 (file)
--- a/COPYING
+++ b/COPYING
@@ -47,3 +47,8 @@ libtre          BSD-like
 scilexer        BSD-like
 sqlite          BSD-like
 zlib            BSD-like
+
+
+Third party code within NetXMS:
+
+ICE            public domain
index 90fd5a5..aaa18a9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,28 @@
 *
+* 1.2.12
+*
+
+- Support for MetaSystem UPS in UPS subagent
+- Timed (temporary) alarm acknowledgement
+- New subagent DBQuery - replacement for ODBCQuery 
+- DCI access functions in NXSL works correctly with table DCIs
+- Management console:
+   - Fixed bug with red zone display in "last value" dashboard element
+   - Edit and delete for alarm comments are working now
+   - Fixed Y axis range can be set for line and bar charts
+   - In alarm menue are not shown incompatible for selected alarm statuses.
+   - Alarm status flow can be changed to strict(terminate status can be set only after alarm is resolved). To change flow set "StrictAlarmStatusFlow" parameter to 1.
+- Android Agent:
+       - Implemented "Connection notification" in status bar (feature #481)
+       - Fix bug in resetting switch preference (settings) 
+- Android Console:
+       - Fix bug in resetting switch preference (settings) 
+       - Implemented "Entire network" root (feature #482)
+       - Manage last alarm from status bar: acknowledge, resolve, terminate (only for Android >= 4.1)
+- Fixed issues: #79, #88, #393, #481, #482, #483, #486, #487, #490
+
+
+*
 * 1.2.11
 *
 
@@ -29,7 +53,7 @@
 - nxapush can push data on behalf of other nodes
 - Transformation script can be run on aggregated DCIs
 - Unknown SNMP trap sources can be automatically added as nodes
-- Syslog processing optinmized for performance
+- Syslog processing optimized for performance
 - Default shared secret for agents can be configured
 - Driver for Ping3 devices
 - Driver for Allied Telesis switches
index a406067..8806b3e 100644 (file)
@@ -8,5 +8,6 @@
        <classpathentry kind="src" path="gen"/>
        <classpathentry kind="lib" path="libs/netxms-base-1.2.11.jar"/>
        <classpathentry kind="lib" path="libs/netxms-mobile-agent-1.2.11.jar"/>
+       <classpathentry kind="lib" path="libs/android-support-v4.jar"/>
        <classpathentry kind="output" path="bin/classes"/>
 </classpath>
diff --git a/android/src/agent/libs/android-support-v4.jar b/android/src/agent/libs/android-support-v4.jar
new file mode 100644 (file)
index 0000000..cf12d28
Binary files /dev/null and b/android/src/agent/libs/android-support-v4.jar differ
diff --git a/android/src/agent/res/drawable-hdpi-v11/ic_stat_connected.png b/android/src/agent/res/drawable-hdpi-v11/ic_stat_connected.png
new file mode 100644 (file)
index 0000000..b6794c1
Binary files /dev/null and b/android/src/agent/res/drawable-hdpi-v11/ic_stat_connected.png differ
diff --git a/android/src/agent/res/drawable-hdpi-v11/ic_stat_disconnected.png b/android/src/agent/res/drawable-hdpi-v11/ic_stat_disconnected.png
new file mode 100644 (file)
index 0000000..daa0829
Binary files /dev/null and b/android/src/agent/res/drawable-hdpi-v11/ic_stat_disconnected.png differ
diff --git a/android/src/agent/res/drawable-hdpi-v9/ic_stat_connected.png b/android/src/agent/res/drawable-hdpi-v9/ic_stat_connected.png
new file mode 100644 (file)
index 0000000..be2455f
Binary files /dev/null and b/android/src/agent/res/drawable-hdpi-v9/ic_stat_connected.png differ
diff --git a/android/src/agent/res/drawable-hdpi-v9/ic_stat_disconnected.png b/android/src/agent/res/drawable-hdpi-v9/ic_stat_disconnected.png
new file mode 100644 (file)
index 0000000..05d64fd
Binary files /dev/null and b/android/src/agent/res/drawable-hdpi-v9/ic_stat_disconnected.png differ
diff --git a/android/src/agent/res/drawable-ldpi-v11/ic_stat_connected.png b/android/src/agent/res/drawable-ldpi-v11/ic_stat_connected.png
new file mode 100644 (file)
index 0000000..2017fe8
Binary files /dev/null and b/android/src/agent/res/drawable-ldpi-v11/ic_stat_connected.png differ
diff --git a/android/src/agent/res/drawable-ldpi-v11/ic_stat_disconnected.png b/android/src/agent/res/drawable-ldpi-v11/ic_stat_disconnected.png
new file mode 100644 (file)
index 0000000..847b664
Binary files /dev/null and b/android/src/agent/res/drawable-ldpi-v11/ic_stat_disconnected.png differ
diff --git a/android/src/agent/res/drawable-ldpi-v9/ic_stat_connected.png b/android/src/agent/res/drawable-ldpi-v9/ic_stat_connected.png
new file mode 100644 (file)
index 0000000..e99bd7e
Binary files /dev/null and b/android/src/agent/res/drawable-ldpi-v9/ic_stat_connected.png differ
diff --git a/android/src/agent/res/drawable-ldpi-v9/ic_stat_disconnected.png b/android/src/agent/res/drawable-ldpi-v9/ic_stat_disconnected.png
new file mode 100644 (file)
index 0000000..1764b24
Binary files /dev/null and b/android/src/agent/res/drawable-ldpi-v9/ic_stat_disconnected.png differ
diff --git a/android/src/agent/res/drawable-mdpi-v11/ic_stat_connected.png b/android/src/agent/res/drawable-mdpi-v11/ic_stat_connected.png
new file mode 100644 (file)
index 0000000..b1edd86
Binary files /dev/null and b/android/src/agent/res/drawable-mdpi-v11/ic_stat_connected.png differ
diff --git a/android/src/agent/res/drawable-mdpi-v11/ic_stat_disconnected.png b/android/src/agent/res/drawable-mdpi-v11/ic_stat_disconnected.png
new file mode 100644 (file)
index 0000000..b86f414
Binary files /dev/null and b/android/src/agent/res/drawable-mdpi-v11/ic_stat_disconnected.png differ
diff --git a/android/src/agent/res/drawable-mdpi-v9/ic_stat_connected.png b/android/src/agent/res/drawable-mdpi-v9/ic_stat_connected.png
new file mode 100644 (file)
index 0000000..3bad642
Binary files /dev/null and b/android/src/agent/res/drawable-mdpi-v9/ic_stat_connected.png differ
diff --git a/android/src/agent/res/drawable-mdpi-v9/ic_stat_disconnected.png b/android/src/agent/res/drawable-mdpi-v9/ic_stat_disconnected.png
new file mode 100644 (file)
index 0000000..30a1a6d
Binary files /dev/null and b/android/src/agent/res/drawable-mdpi-v9/ic_stat_disconnected.png differ
diff --git a/android/src/agent/res/drawable-xhdpi-v11/ic_stat_connected.png b/android/src/agent/res/drawable-xhdpi-v11/ic_stat_connected.png
new file mode 100644 (file)
index 0000000..7601594
Binary files /dev/null and b/android/src/agent/res/drawable-xhdpi-v11/ic_stat_connected.png differ
diff --git a/android/src/agent/res/drawable-xhdpi-v11/ic_stat_disconnected.png b/android/src/agent/res/drawable-xhdpi-v11/ic_stat_disconnected.png
new file mode 100644 (file)
index 0000000..741dd0d
Binary files /dev/null and b/android/src/agent/res/drawable-xhdpi-v11/ic_stat_disconnected.png differ
diff --git a/android/src/agent/res/drawable-xhdpi-v9/ic_stat_connected.png b/android/src/agent/res/drawable-xhdpi-v9/ic_stat_connected.png
new file mode 100644 (file)
index 0000000..b64e7d5
Binary files /dev/null and b/android/src/agent/res/drawable-xhdpi-v9/ic_stat_connected.png differ
diff --git a/android/src/agent/res/drawable-xhdpi-v9/ic_stat_disconnected.png b/android/src/agent/res/drawable-xhdpi-v9/ic_stat_disconnected.png
new file mode 100644 (file)
index 0000000..a09042f
Binary files /dev/null and b/android/src/agent/res/drawable-xhdpi-v9/ic_stat_disconnected.png differ
diff --git a/android/src/agent/res/drawable-xhdpi/ic_stat_connected.png b/android/src/agent/res/drawable-xhdpi/ic_stat_connected.png
new file mode 100644 (file)
index 0000000..a109091
Binary files /dev/null and b/android/src/agent/res/drawable-xhdpi/ic_stat_connected.png differ
diff --git a/android/src/agent/res/drawable-xhdpi/ic_stat_disconnected.png b/android/src/agent/res/drawable-xhdpi/ic_stat_disconnected.png
new file mode 100644 (file)
index 0000000..1090b4e
Binary files /dev/null and b/android/src/agent/res/drawable-xhdpi/ic_stat_disconnected.png differ
index d889bda..69667f4 100644 (file)
@@ -27,6 +27,7 @@
     <string name="pref_connection">Connection</string>
     <string name="pref_parameters">Parameters</string>
     <string name="pref_scheduler">Scheduler</string>
+    <string name="pref_scheduler_summary">Define scheduler behaviour</string>
     <string name="pref_scheduler_daily_enable">Enable scheduler</string>
     <string name="pref_scheduler_daily_enabled">Daily scheduler is enabled (agent operates between the specified range)</string>
     <string name="pref_scheduler_daily_disabled">Daily scheduler is disabled (agent operates 24H per day)</string>
        <string name="pref_notification_toast">Toast notification</string>
        <string name="pref_notification_toast_enabled">Toast notification enabled</string>
        <string name="pref_notification_toast_disabled">Toast notification disabled</string>
-       
+       <string name="pref_notification_icon">Icon notification</string>
+       <string name="pref_notification_icon_enabled">Icon in status bar is enabled</string>
+       <string name="pref_notification_icon_disabled">Icon in status bar is disabled</string>
+       <string name="pref_notification_status">Notification behaviour</string>
+               
        <string name="notify_started">NetXMS agent started</string>
        <string name="notify_disconnected">Disconnected from server</string>
        <string name="notify_connected">Connected to server: %1$s</string>
@@ -66,7 +71,7 @@
        <string name="notify_connection_failed">Connection failed: %1$s</string>
        <string name="notify_no_connection">Data connection not available!"</string>
        <string name="notify_allocation_error">Out of memory!"</string>
-       <string name="notify_pushing_data">Pushing data&#8230;</string>
+       <string name="notify_push_data">Push data</string>
                
        <string name="info_agent_status">%1$s: push every %2$s minutes, between %3$s. %4$s</string>
        <string name="info_agent_range">%1$s and %2$s</string>
index 8fcd9ee..10f333b 100644 (file)
                <item>1</item> 
                <item>2</item> 
        </string-array>      
+       <string-array name="notification_status_labels"> 
+               <item>Never</item> 
+               <item>On connection OK</item> 
+               <item>On connection error</item> 
+               <item>Always</item> 
+       </string-array>
+       <string-array name="notification_status_values"> 
+               <item>0</item> 
+               <item>1</item> 
+               <item>2</item> 
+               <item>3</item> 
+       </string-array>      
 </resources>
index 185af89..2a456d7 100644 (file)
@@ -2,10 +2,10 @@
 <PreferenceScreen
          xmlns:android="http://schemas.android.com/apk/res/android">
        <PreferenceCategory android:title="@string/pref_global">
-           <SwitchPreference android:summaryOff="@string/pref_global_activate_disabled" android:summaryOn="@string/pref_global_activate_enabled" android:key="global.activate" android:enabled="true" android:defaultValue="false" android:title="@string/pref_global_activate"/>
-           <SwitchPreference android:summaryOff="@string/pref_global_autostart_disabled" android:summaryOn="@string/pref_global_autostart_enabled" android:key="global.autostart" android:enabled="true" android:defaultValue="false" android:title="@string/pref_global_autostart" android:dependency="global.activate"/>
-               <PreferenceScreen android:title="@string/pref_scheduler" android:enabled="true" android:dependency="global.activate">
-                       <SwitchPreference android:summaryOn="@string/pref_scheduler_daily_enabled" android:key="scheduler.daily.enable" android:title="@string/pref_scheduler_daily_enabled" android:summaryOff="@string/pref_scheduler_daily_disabled" android:defaultValue="false" android:dependency="global.activate"/>
+           <org.netxms.agent.android.main.settings.CustomSwitchPreference android:summaryOff="@string/pref_global_activate_disabled" android:summaryOn="@string/pref_global_activate_enabled" android:key="global.activate" android:enabled="true" android:defaultValue="false" android:title="@string/pref_global_activate"/>
+           <org.netxms.agent.android.main.settings.CustomSwitchPreference android:summaryOff="@string/pref_global_autostart_disabled" android:summaryOn="@string/pref_global_autostart_enabled" android:key="global.autostart" android:enabled="true" android:defaultValue="false" android:title="@string/pref_global_autostart" android:dependency="global.activate"/>
+               <PreferenceScreen android:title="@string/pref_scheduler" android:summary="@string/pref_scheduler_summary" android:enabled="true" android:dependency="global.activate">
+                       <org.netxms.agent.android.main.settings.CustomSwitchPreference android:summaryOn="@string/pref_scheduler_daily_enabled" android:key="scheduler.daily.enable" android:title="@string/pref_scheduler_daily_enabled" android:summaryOff="@string/pref_scheduler_daily_disabled" android:defaultValue="false" android:dependency="global.activate"/>
                        <org.netxms.agent.android.main.settings.TimePreference android:key="scheduler.daily.on" android:title="@string/pref_scheduler_daily_on" android:dependency="scheduler.daily.enable"/> 
                        <org.netxms.agent.android.main.settings.TimePreference android:key="scheduler.daily.off" android:title="@string/pref_scheduler_daily_off" android:dependency="scheduler.daily.enable"/>
                </PreferenceScreen>
                    <EditTextPreference android:title="@string/pref_port" android:summary="@string/pref_port_summary" android:enabled="true"  android:defaultValue="4747" android:key="connection.port" android:digits="0123456789"/>
                        <EditTextPreference android:title="@string/pref_login" android:summary="@string/pref_login_summary" android:enabled="true" android:defaultValue="admin" android:key="connection.login"/>
                        <EditTextPreference android:enabled="true" android:key="connection.password" android:title="@string/pref_password" android:summary="@string/pref_password_summary" android:password="true"/>
-                       <SwitchPreference android:title="@string/pref_encrypt" android:key="connection.encrypt" android:enabled="true" android:summaryOn="@string/pref_encrypt_summary_enabled" android:summaryOff="@string/pref_encrypt_summary_disabled" android:defaultValue="true"/>
+                       <org.netxms.agent.android.main.settings.CustomSwitchPreference android:title="@string/pref_encrypt" android:key="connection.encrypt" android:enabled="true" android:summaryOn="@string/pref_encrypt_summary_enabled" android:summaryOff="@string/pref_encrypt_summary_disabled" android:defaultValue="true"/>
                </PreferenceScreen>
                <EditTextPreference android:title="@string/pref_connection_activation_interval" android:summary="@string/pref_connection_activation_interval_summary" android:enabled="true" android:defaultValue="15" android:key="connection.interval" android:digits="0123456789" android:dependency="global.activate"/>
-               <SwitchPreference android:summaryOn="@string/pref_connection_override_enabled" android:key="connection.override" android:title="@string/pref_connection_override" android:summaryOff="@string/pref_connection_override_disabled" android:defaultValue="false" android:dependency="global.activate"/>
+               <org.netxms.agent.android.main.settings.CustomSwitchPreference android:summaryOn="@string/pref_connection_override_enabled" android:key="connection.override" android:title="@string/pref_connection_override" android:summaryOff="@string/pref_connection_override_disabled" android:defaultValue="false" android:dependency="global.activate"/>
        </PreferenceCategory>
        <PreferenceCategory android:title="@string/pref_locations" android:dependency="global.activate">
-               <SwitchPreference android:summaryOn="@string/pref_location_force_enabled" android:key="location.force" android:title="@string/pref_location_force" android:summaryOff="@string/pref_location_force_disabled" android:defaultValue="false" android:dependency="global.activate"/>
+               <org.netxms.agent.android.main.settings.CustomSwitchPreference android:summaryOn="@string/pref_location_force_enabled" android:key="location.force" android:title="@string/pref_location_force" android:summaryOff="@string/pref_location_force_disabled" android:defaultValue="false" android:dependency="global.activate"/>
            <EditTextPreference android:title="@string/pref_location_activation_interval" android:summary="@string/pref_location_activation_interval_summary" android:enabled="true" android:defaultValue="30" android:key="location.interval" android:digits="0123456789" android:dependency="global.activate"/>
                <EditTextPreference android:title="@string/pref_location_activation_duration" android:summary="@string/pref_location_activation_duration_summary" android:enabled="true" android:defaultValue="2" android:key="location.duration" android:digits="0123456789" android:dependency="location.force"/>
                <ListPreference android:dialogTitle="@string/pref_location_provider_source" android:title="@string/pref_location_strategy" android:entryValues="@array/location_strategy_values" android:entries="@array/locations_strategy_labels" android:defaultValue="0" android:key="location.strategy" android:dependency="location.force"/>
        </PreferenceCategory>
        <PreferenceCategory android:title="@string/pref_notifications">
-        <SwitchPreference android:summaryOff="@string/pref_notification_toast_disabled" android:summaryOn="@string/pref_notification_toast_enabled" android:key="notification.toast" android:enabled="true" android:defaultValue="false" android:title="@string/pref_notification_toast" android:dependency="global.activate"/>
-       </PreferenceCategory>
+               <ListPreference android:dialogTitle="@string/pref_notification_status" android:key="notification.status" android:title="@string/pref_notification_status" android:entryValues="@array/notification_status_values" android:entries="@array/notification_status_labels" android:defaultValue="2" />
+        <org.netxms.agent.android.main.settings.CustomSwitchPreference android:summaryOff="@string/pref_notification_toast_disabled" android:summaryOn="@string/pref_notification_toast_enabled" android:key="notification.toast" android:enabled="true" android:defaultValue="false" android:title="@string/pref_notification_toast" android:dependency="global.activate"/>
+        <org.netxms.agent.android.main.settings.CustomSwitchPreference android:summaryOff="@string/pref_notification_icon_disabled" android:summaryOn="@string/pref_notification_icon_enabled" android:key="notification.icon" android:enabled="true" android:defaultValue="true" android:title="@string/pref_notification_icon"/>
+    </PreferenceCategory>
 </PreferenceScreen>
index 6b32178..a875179 100644 (file)
@@ -4,7 +4,7 @@
        <PreferenceCategory android:title="@string/pref_global">
            <CheckBoxPreference android:summaryOff="@string/pref_global_activate_disabled" android:summaryOn="@string/pref_global_activate_enabled" android:key="global.activate" android:enabled="true" android:defaultValue="false" android:title="@string/pref_global_activate"/>
            <CheckBoxPreference android:summaryOff="@string/pref_global_autostart_disabled" android:summaryOn="@string/pref_global_autostart_enabled" android:key="global.autostart" android:enabled="true" android:defaultValue="false" android:title="@string/pref_global_autostart" android:dependency="global.activate"/>
-               <PreferenceScreen android:title="@string/pref_scheduler" android:enabled="true" android:dependency="global.activate">
+               <PreferenceScreen android:title="@string/pref_scheduler" android:summary="@string/pref_scheduler_summary" android:enabled="true" android:dependency="global.activate">
                        <CheckBoxPreference android:summaryOn="@string/pref_scheduler_daily_enabled" android:key="scheduler.daily.enable" android:title="@string/pref_scheduler_daily_enabled" android:summaryOff="@string/pref_scheduler_daily_disabled" android:defaultValue="false" android:dependency="global.activate"/>
                        <org.netxms.agent.android.main.settings.TimePreference android:key="scheduler.daily.on" android:title="@string/pref_scheduler_daily_on" android:dependency="scheduler.daily.enable"/> 
                        <org.netxms.agent.android.main.settings.TimePreference android:key="scheduler.daily.off" android:title="@string/pref_scheduler_daily_off" android:dependency="scheduler.daily.enable"/>
@@ -28,6 +28,8 @@
                <ListPreference android:dialogTitle="@string/pref_location_provider_source" android:title="@string/pref_location_strategy" android:entryValues="@array/location_strategy_values" android:entries="@array/locations_strategy_labels" android:defaultValue="0" android:key="location.strategy" android:dependency="location.force"/>
        </PreferenceCategory>
        <PreferenceCategory android:title="@string/pref_notifications">
+               <ListPreference android:dialogTitle="@string/pref_notification_status" android:key="notification.status" android:title="@string/pref_notification_status" android:entryValues="@array/notification_status_values" android:entries="@array/notification_status_labels" android:defaultValue="2" />
         <CheckBoxPreference android:summaryOff="@string/pref_notification_toast_disabled" android:summaryOn="@string/pref_notification_toast_enabled" android:key="notification.toast" android:enabled="true" android:defaultValue="false" android:title="@string/pref_notification_toast" android:dependency="global.activate"/>
-       </PreferenceCategory>
+        <CheckBoxPreference android:summaryOff="@string/pref_notification_icon_disabled" android:summaryOn="@string/pref_notification_icon_enabled" android:key="notification.icon" android:enabled="true" android:defaultValue="true" android:title="@string/pref_notification_icon"/>
+    </PreferenceCategory>
 </PreferenceScreen>
diff --git a/android/src/agent/src/org/netxms/agent/android/main/settings/CustomSwitchPreference.java b/android/src/agent/src/org/netxms/agent/android/main/settings/CustomSwitchPreference.java
new file mode 100644 (file)
index 0000000..c1e0f48
--- /dev/null
@@ -0,0 +1,34 @@
+package org.netxms.agent.android.main.settings;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.os.Build;
+import android.preference.SwitchPreference;
+import android.util.AttributeSet;
+
+/**
+ * Custom handler for switch preference to handle bug (reset of switch when going out of screen)
+ * 
+ * @author Marco Incalcaterra (marco.incalcaterra@thinksoft.it)
+ * 
+ */
+
+@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
+public class CustomSwitchPreference extends SwitchPreference
+{
+
+       public CustomSwitchPreference(Context context)
+       {
+               this(context, null);
+       }
+
+       public CustomSwitchPreference(Context context, AttributeSet attrs)
+       {
+               this(context, attrs, android.R.attr.switchPreferenceStyle);
+       }
+
+       public CustomSwitchPreference(Context context, AttributeSet attrs, int defStyle)
+       {
+               super(context, attrs, defStyle);
+       }
+}
index 6204aa3..6887e6f 100644 (file)
@@ -23,6 +23,8 @@ import org.netxms.mobile.agent.MobileAgentException;
 import org.netxms.mobile.agent.Session;
 
 import android.app.AlarmManager;
+import android.app.Notification;
+import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.Service;
 import android.content.BroadcastReceiver;
@@ -41,6 +43,7 @@ import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.preference.PreferenceManager;
+import android.support.v4.app.NotificationCompat;
 import android.util.Log;
 import android.widget.Toast;
 
@@ -71,6 +74,11 @@ public class AgentConnectorService extends Service implements LocationListener
        private static final int STRATEGY_NET_ONLY = 0;
        private static final int STRATEGY_GPS_ONLY = 1;
        private static final int STRATEGY_NET_AND_GPS = 2;
+       private static final int NOTIFY_STATUS = 1;
+       private static final int NOTIFY_STATUS_NEVER = 0;
+       private static final int NOTIFY_STATUS_ON_CONNECT = 1;
+       private static final int NOTIFY_STATUS_ON_DISCONNECT = 2;
+       private static final int NOTIFY_STATUS_ALWAYS = 3;
 
        private final Binder binder = new AgentConnectorBinder();
        private Handler uiThreadHandler = null;
@@ -79,10 +87,13 @@ public class AgentConnectorService extends Service implements LocationListener
        private BroadcastReceiver receiver = null;
        private SharedPreferences sp;
        private LocationManager locationManager = null;
+       private NotificationManager notificationManager;
        private HomeScreen homeScreen = null;
        private boolean sendDeviceSystemInfo = true;
        private boolean agentActive;
        private boolean notifyToast;
+       private boolean notifyIcon;
+       private int notificationType = NOTIFY_STATUS_NEVER;
        private String connectionServer;
        private int connectionPort;
        private String connectionLogin;
@@ -124,6 +135,7 @@ public class AgentConnectorService extends Service implements LocationListener
                sp = PreferenceManager.getDefaultSharedPreferences(this);
                Logger.setLoggingFacility(new AndroidLoggingFacility());
                locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
+               notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
                configure();
 
                receiver = new BroadcastReceiver()
@@ -198,6 +210,8 @@ public class AgentConnectorService extends Service implements LocationListener
                refreshHomeScreen();
                agentActive = sp.getBoolean("global.activate", false);
                notifyToast = sp.getBoolean("notification.toast", true);
+               notifyIcon = sp.getBoolean("notification.icon", true);
+               notificationType = Integer.parseInt(sp.getString("notification.status", "0"));
                connectionServer = sp.getString("connection.server", "");
                connectionPort = SafeParser.parseInt(sp.getString("connection.port", "4747"), 4747);
                connectionLogin = sp.getString("connection.login", "");
@@ -239,23 +253,33 @@ public class AgentConnectorService extends Service implements LocationListener
        }
 
        /**
-        * Show status notification
+        * Show status notification (toast and icon, depending on settings)
         * 
         * @param status        connection status
-        * @param extra extra text to add at the end of the toast
+        * @param extra extra text to add at the end of the toast/status message
         */
-       public void statusNotification(ConnectionStatus status, String extra)
+       public void notification(ConnectionStatus status, String extra)
        {
                connectionStatus = status;
                String text = "";
+               int icon = -1;
                switch (status)
                {
                        case CS_CONNECTED:
+                               if (notificationType == NOTIFY_STATUS_ON_CONNECT || notificationType == NOTIFY_STATUS_ALWAYS)
+                               {
+                                       icon = R.drawable.ic_stat_connected;
+                               }
                                text = getString(R.string.notify_connected, extra);
                                break;
                        case CS_ERROR:
+                               if (notificationType == NOTIFY_STATUS_ON_DISCONNECT || notificationType == NOTIFY_STATUS_ALWAYS)
+                               {
+                                       icon = R.drawable.ic_stat_disconnected;
+                               }
                                text = getString(R.string.notify_connection_failed, extra);
                                break;
+                       case CS_DISCONNECTED:
                        case CS_NOCONNECTION:
                        case CS_INPROGRESS:
                        case CS_ALREADYCONNECTED:
@@ -264,6 +288,33 @@ public class AgentConnectorService extends Service implements LocationListener
                }
                if (notifyToast)
                        showToast(text);
+               if (icon == -1)
+                       notificationManager.cancel(NOTIFY_STATUS);
+               else if (notifyIcon)
+                       showIcon(text, icon);
+       }
+
+       /**
+        * Show icon notification in status bar
+        * 
+        * @param text  notification text
+        * @param icon  icon to show
+        */
+       public void showIcon(String text, int icon)
+       {
+               Intent notifyIntent = new Intent(getApplicationContext(), HomeScreen.class);
+               PendingIntent intent = PendingIntent.getActivity(getApplicationContext(), 0, notifyIntent, Intent.FLAG_ACTIVITY_NEW_TASK);
+               NotificationCompat.Builder nb = new NotificationCompat.Builder(getApplicationContext())
+                               .setSmallIcon(icon)
+                               .setWhen(System.currentTimeMillis())
+                               .setDefaults(Notification.DEFAULT_LIGHTS)
+                               .setContentText(text)
+                               .setContentTitle(getString(R.string.app_name))
+                               .setContentIntent(intent);
+               notificationManager.notify(NOTIFY_STATUS,
+                               new NotificationCompat.BigTextStyle(nb)
+                                               .bigText(text)
+                                               .build());
        }
 
        /**
@@ -458,7 +509,7 @@ public class AgentConnectorService extends Service implements LocationListener
                protected Boolean doInBackground(Object... params)
                {
                        Log.d(TAG, "PushDataTask.doInBackground: reconnecting...");
-                       statusNotification(ConnectionStatus.CS_INPROGRESS, "");
+                       notification(ConnectionStatus.CS_INPROGRESS, "");
                        if (NetHelper.isInternetOn(getApplicationContext()))
                        {
                                Session session = new Session(server, port, deviceId, login, password, encrypt);
@@ -466,7 +517,7 @@ public class AgentConnectorService extends Service implements LocationListener
                                {
                                        session.connect();
                                        Log.v(TAG, "PushDataTask.doInBackground: connected");
-                                       statusNotification(ConnectionStatus.CS_CONNECTED, getString(R.string.notify_pushing_data));
+                                       notification(ConnectionStatus.CS_CONNECTED, getString(R.string.notify_push_data));
                                        if (sendDeviceSystemInfo)
                                        {
                                                Log.v(TAG, "PushDataTask.doInBackground: sending DeviceSystemInfo");
@@ -507,12 +558,12 @@ public class AgentConnectorService extends Service implements LocationListener
                        if (result == true)
                        {
                                Log.d(TAG, "PushDataTask.onPostExecute: disconnecting...");
-                               statusNotification(ConnectionStatus.CS_DISCONNECTED, "");
+                               notification(ConnectionStatus.CS_DISCONNECTED, "");
                        }
                        else
                        {
                                Log.d(TAG, "PushDataTask.onPostExecute: error: " + connMsg);
-                               statusNotification(ConnectionStatus.CS_ERROR, connMsg);
+                               notification(ConnectionStatus.CS_ERROR, connMsg);
                        }
                        Editor e = sp.edit();
                        e.putLong("scheduler.last_activation", Calendar.getInstance().getTimeInMillis());
diff --git a/android/src/console/res/drawable-hdpi/entire_network.png b/android/src/console/res/drawable-hdpi/entire_network.png
new file mode 100644 (file)
index 0000000..1d9264c
Binary files /dev/null and b/android/src/console/res/drawable-hdpi/entire_network.png differ
diff --git a/android/src/console/res/drawable-ldpi/entire_network.png b/android/src/console/res/drawable-ldpi/entire_network.png
new file mode 100644 (file)
index 0000000..b4e6a22
Binary files /dev/null and b/android/src/console/res/drawable-ldpi/entire_network.png differ
diff --git a/android/src/console/res/drawable-mdpi/entire_network.png b/android/src/console/res/drawable-mdpi/entire_network.png
new file mode 100644 (file)
index 0000000..5ded6fc
Binary files /dev/null and b/android/src/console/res/drawable-mdpi/entire_network.png differ
diff --git a/android/src/console/res/drawable-xhdpi/entire_network.png b/android/src/console/res/drawable-xhdpi/entire_network.png
new file mode 100644 (file)
index 0000000..98b6487
Binary files /dev/null and b/android/src/console/res/drawable-xhdpi/entire_network.png differ
diff --git a/android/src/console/res/drawable/object_subnet.png b/android/src/console/res/drawable/object_subnet.png
new file mode 100644 (file)
index 0000000..ad8382a
Binary files /dev/null and b/android/src/console/res/drawable/object_subnet.png differ
diff --git a/android/src/console/res/drawable/object_zone.png b/android/src/console/res/drawable/object_zone.png
new file mode 100644 (file)
index 0000000..ab74ece
Binary files /dev/null and b/android/src/console/res/drawable/object_zone.png differ
index 1fa6337..98db6a9 100644 (file)
@@ -24,6 +24,7 @@
        <string name="home_screen_alarms">Alarms</string>
        <string name="home_screen_dashboards">Dashboards</string>
        <string name="home_screen_nodes">Nodes</string>
+       <string name="home_screen_entire_network">Entire network</string>
        <string name="home_screen_graphs">Graphics</string>
        <string name="home_screen_macaddress">MACaddress</string>
                        
     <string name="pref_port">Port</string>
     <string name="pref_port_summary">Port of NetXMS server</string>
     <string name="pref_global">Global settings</string>
+    <string name="pref_global_summary">Set global parameters (autostart on boot, &#8230;)</string>
     <string name="pref_connection">Connection</string>
+    <string name="pref_connection_summary">Set connection parameters (server name, port, username, encryption, scheduler &#8230;)</string>
     <string name="pref_parameters">Parameters</string>
     <string name="pref_scheduler">Scheduler</string>
+    <string name="pref_scheduler_summary">Define scheduler behaviour</string>
     <string name="pref_scheduler_enable">Enable scheduler</string>
     <string name="pref_scheduler_enabled">Scheduler is enabled</string>
     <string name="pref_scheduler_disabled">Scheduler is disabled</string>
@@ -59,6 +63,7 @@
        <string name="pref_global_autostart_enabled">Allow automatic start of service</string>
        <string name="pref_global_autostart_disabled">Block automatic start of service</string>
        <string name="pref_notifications">Notifications</string>
+       <string name="pref_notifications_summary">Customize notifications (toast, notification bar, alarms sounds, &#8230;)</string>
        <string name="pref_status">Connection status</string>
        <string name="pref_alarms">Alarms</string>
        <string name="pref_alarm_sound">Alarm sound by severity</string>
@@ -78,7 +83,9 @@
        <string name="pref_global_notification_alarm_enabled">Alarm in status bar is enabled</string>
        <string name="pref_global_notification_alarm_disabled">Alarm in status bar is disabled</string>
        <string name="pref_interface">Interface</string>
+       <string name="pref_interface_summary">Customize interface parameters (multipliers, &#8230;)</string>
        <string name="pref_multipliers">Multipliers</string>
+       <string name="pref_multipliers_summary">Define which multiplier to use in presenting data (last values, graphs, &#8230;)</string>
        <string name="pref_multiplier_title">Choose multiplier</string>
 
        <string name="notification_title">NetXMS</string>
index f401ab8..795855e 100644 (file)
@@ -5,13 +5,13 @@
            <EditTextPreference android:title="@string/pref_port" android:summary="@string/pref_port_summary" android:enabled="true"  android:defaultValue="4701" android:key="connection.port" android:digits="0123456789"/>
                <EditTextPreference android:title="@string/pref_login" android:summary="@string/pref_login_summary" android:enabled="true" android:defaultValue="admin" android:key="connection.login"/>
                <EditTextPreference android:enabled="true" android:key="connection.password" android:title="@string/pref_password" android:summary="@string/pref_password_summary" android:password="true"/>
-               <SwitchPreference android:title="@string/pref_encrypt" android:key="connection.encrypt" android:enabled="true" android:summaryOn="@string/pref_encrypt_summary_enabled" android:summaryOff="@string/pref_encrypt_summary_disabled" android:defaultValue="true"/>
+               <org.netxms.ui.android.main.settings.CustomSwitchPreference android:title="@string/pref_encrypt" android:key="connection.encrypt" android:enabled="true" android:summaryOn="@string/pref_encrypt_summary_enabled" android:summaryOff="@string/pref_encrypt_summary_disabled" android:defaultValue="true"/>
        </PreferenceCategory>
-       <PreferenceCategory android:title="@string/pref_scheduler" android:enabled="true">
-               <SwitchPreference android:summaryOn="@string/pref_scheduler_enabled" android:key="global.scheduler.enable" android:title="@string/pref_scheduler_enable" android:summaryOff="@string/pref_scheduler_disabled" android:defaultValue="false"/>
+       <PreferenceCategory android:title="@string/pref_scheduler" android:summary="@string/pref_scheduler_summary" android:enabled="true">
+               <org.netxms.ui.android.main.settings.CustomSwitchPreference android:summaryOn="@string/pref_scheduler_enabled" android:key="global.scheduler.enable" android:title="@string/pref_scheduler_enable" android:summaryOff="@string/pref_scheduler_disabled" android:defaultValue="false"/>
                <EditTextPreference android:title="@string/pref_scheduler_activation_interval" android:summary="@string/pref_scheduler_activation_interval_summary" android:enabled="true" android:defaultValue="15" android:key="global.scheduler.interval" android:digits="0123456789" android:dependency="global.scheduler.enable"/>
                <EditTextPreference android:title="@string/pref_scheduler_activation_duration" android:summary="@string/pref_scheduler_activation_duration_summary" android:enabled="true" android:defaultValue="1" android:key="global.scheduler.duration" android:digits="0123456789" android:dependency="global.scheduler.enable"/>
-               <SwitchPreference android:summaryOn="@string/pref_scheduler_daily_enabled" android:key="global.scheduler.daily.enable" android:title="@string/pref_scheduler_daily_enable" android:summaryOff="@string/pref_scheduler_daily_disabled" android:defaultValue="false" android:dependency="global.scheduler.enable"/>
+               <org.netxms.ui.android.main.settings.CustomSwitchPreference android:summaryOn="@string/pref_scheduler_daily_enabled" android:key="global.scheduler.daily.enable" android:title="@string/pref_scheduler_daily_enable" android:summaryOff="@string/pref_scheduler_daily_disabled" android:defaultValue="false" android:dependency="global.scheduler.enable"/>
                <org.netxms.ui.android.main.settings.TimePreference android:key="global.scheduler.daily.on" android:title="@string/pref_scheduler_daily_on" android:dependency="global.scheduler.daily.enable"/> 
                <org.netxms.ui.android.main.settings.TimePreference android:key="global.scheduler.daily.off" android:title="@string/pref_scheduler_daily_off" android:dependency="global.scheduler.daily.enable"/>
        </PreferenceCategory>
index 8e2aaed..6268b9b 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
-    <SwitchPreference android:summaryOff="@string/pref_global_autostart_disabled" android:summaryOn="@string/pref_global_autostart_enabled" android:key="global.autostart" android:enabled="true" android:defaultValue="false" android:title="@string/pref_global_autostart"/>
+    <org.netxms.ui.android.main.settings.CustomSwitchPreference android:summaryOff="@string/pref_global_autostart_disabled" android:summaryOn="@string/pref_global_autostart_enabled" android:key="global.autostart" android:enabled="true" android:defaultValue="false" android:title="@string/pref_global_autostart"/>
 </PreferenceScreen>
index 8682c74..c5afe0e 100644 (file)
@@ -2,11 +2,11 @@
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
     <PreferenceCategory android:title="@string/pref_status">
                <ListPreference android:dialogTitle="@string/pref_global_notification_status" android:key="global.notification.status" android:title="@string/pref_global_notification_status" android:entryValues="@array/notification_status_values" android:entries="@array/notification_status_labels" android:defaultValue="3" />
-        <SwitchPreference android:summaryOff="@string/pref_global_notification_toast_disabled" android:summaryOn="@string/pref_global_notification_toast_enabled" android:key="global.notification.toast" android:enabled="true" android:defaultValue="false" android:title="@string/pref_global_notification_toast"/>
-       <SwitchPreference android:summaryOff="@string/pref_global_notification_icon_disabled" android:summaryOn="@string/pref_global_notification_icon_enabled" android:key="global.notification.icon" android:enabled="true" android:defaultValue="true" android:title="@string/pref_global_notification_icon"/>
+        <org.netxms.ui.android.main.settings.CustomSwitchPreference android:summaryOff="@string/pref_global_notification_toast_disabled" android:summaryOn="@string/pref_global_notification_toast_enabled" android:key="global.notification.toast" android:enabled="true" android:defaultValue="false" android:title="@string/pref_global_notification_toast"/>
+       <org.netxms.ui.android.main.settings.CustomSwitchPreference android:summaryOff="@string/pref_global_notification_icon_disabled" android:summaryOn="@string/pref_global_notification_icon_enabled" android:key="global.notification.icon" android:enabled="true" android:defaultValue="true" android:title="@string/pref_global_notification_icon"/>
        </PreferenceCategory>
     <PreferenceCategory android:title="@string/pref_alarms">
-           <SwitchPreference android:key="global.notification.alarm" android:summaryOn="@string/pref_global_notification_alarm_enabled" android:summaryOff="@string/pref_global_notification_alarm_disabled" android:title="@string/pref_global_notification_alarm" android:enabled="true" android:defaultValue="true"/>
+           <org.netxms.ui.android.main.settings.CustomSwitchPreference android:key="global.notification.alarm" android:summaryOn="@string/pref_global_notification_alarm_enabled" android:summaryOff="@string/pref_global_notification_alarm_disabled" android:title="@string/pref_global_notification_alarm" android:enabled="true" android:defaultValue="true"/>
                <RingtonePreference android:title="@string/pref_alarm_sound_normal" android:ringtoneType="all" android:showDefault="true" android:showSilent="true" android:key="alarm.sound.normal" android:icon="@drawable/status_normal" />
                <RingtonePreference android:key="alarm.sound.warning" android:showDefault="true" android:showSilent="true" android:ringtoneType="all" android:title="@string/pref_alarm_sound_warning" android:icon="@drawable/status_warning" />
                <RingtonePreference android:key="alarm.sound.minor" android:showDefault="true" android:showSilent="true" android:ringtoneType="all" android:title="@string/pref_alarm_sound_minor" android:icon="@drawable/status_minor" />
index a8f83e9..dab7d26 100644 (file)
@@ -7,7 +7,7 @@
                <EditTextPreference android:enabled="true" android:key="connection.password" android:title="@string/pref_password" android:summary="@string/pref_password_summary" android:password="true"/>
                <CheckBoxPreference android:title="@string/pref_encrypt" android:key="connection.encrypt" android:enabled="true" android:summaryOn="@string/pref_encrypt_summary_enabled" android:summaryOff="@string/pref_encrypt_summary_disabled" android:defaultValue="true"/>
        </PreferenceCategory>
-       <PreferenceCategory android:title="@string/pref_scheduler" android:enabled="true">
+       <PreferenceCategory android:title="@string/pref_scheduler" android:summary="@string/pref_scheduler_summary" android:enabled="true">
                <CheckBoxPreference android:summaryOn="@string/pref_scheduler_enabled" android:key="global.scheduler.enable" android:title="@string/pref_scheduler_enable" android:summaryOff="@string/pref_scheduler_disabled" android:defaultValue="false"/>
                <EditTextPreference android:title="@string/pref_scheduler_activation_interval" android:summary="@string/pref_scheduler_activation_interval_summary" android:enabled="true" android:defaultValue="15" android:key="global.scheduler.interval" android:digits="0123456789" android:dependency="global.scheduler.enable"/>
                <EditTextPreference android:title="@string/pref_scheduler_activation_duration" android:summary="@string/pref_scheduler_activation_duration_summary" android:enabled="true" android:defaultValue="1" android:key="global.scheduler.duration" android:digits="0123456789" android:dependency="global.scheduler.enable"/>
index 59ccbb7..6a5c0ac 100644 (file)
@@ -3,25 +3,25 @@
        <header
        android:fragment="org.netxms.ui.android.main.fragments.ConsolePreferencesFragment"
         android:title="@string/pref_global"
-        android:summary="@string/pref_global">
+        android:summary="@string/pref_global_summary">
          <extra android:name="settings" android:value="global" />
          </header>
        <header
        android:fragment="org.netxms.ui.android.main.fragments.ConsolePreferencesFragment"
         android:title="@string/pref_connection"
-        android:summary="@string/pref_connection">
+        android:summary="@string/pref_connection_summary">
                <extra android:name="settings" android:value="connection" />
        </header>
        <header
        android:fragment="org.netxms.ui.android.main.fragments.ConsolePreferencesFragment"
         android:title="@string/pref_notifications"
-        android:summary="@string/pref_notifications">
+        android:summary="@string/pref_notifications_summary">
        <extra android:name="settings" android:value="notifications" />
     </header>
        <header
        android:fragment="org.netxms.ui.android.main.fragments.ConsolePreferencesFragment"
         android:title="@string/pref_interface"
-        android:summary="@string/pref_interface">
+        android:summary="@string/pref_interface_summary">
        <extra android:name="settings" android:value="interface" />
     </header>
 </preference-headers>
index b3be65a..c23eb33 100644 (file)
@@ -1,28 +1,28 @@
 <?xml version="1.0" encoding="utf-8"?>
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
        <Preference android:title="@string/pref_global"
-           android:summary="@string/pref_global">
+           android:summary="@string/pref_global_summary">
                        <intent
                            android:targetPackage="org.netxms.ui.android"
                            android:targetClass="org.netxms.ui.android.main.activities.ConsolePreferences"
                            android:action="org.netxms.ui.android.ConsolePreferences.global" />
        </Preference>
        <Preference android:title="@string/pref_connection"
-           android:summary="@string/pref_connection">
+           android:summary="@string/pref_connection_summary">
                        <intent
                            android:targetPackage="org.netxms.ui.android"
                            android:targetClass="org.netxms.ui.android.main.activities.ConsolePreferences"
                            android:action="org.netxms.ui.android.ConsolePreferences.connection" />
        </Preference>
        <Preference android:title="@string/pref_notifications"
-           android:summary="@string/pref_notifications">
+           android:summary="@string/pref_notifications_summary">
                        <intent
                            android:targetPackage="org.netxms.ui.android"
                            android:targetClass="org.netxms.ui.android.main.activities.ConsolePreferences"
                            android:action="org.netxms.ui.android.ConsolePreferences.notifications" />
        </Preference>
        <Preference android:title="@string/pref_interface"
-           android:summary="@string/pref_interface">
+           android:summary="@string/pref_interface_summary">
                        <intent
                            android:targetPackage="org.netxms.ui.android"
                            android:targetClass="org.netxms.ui.android.main.activities.ConsolePreferences"
index b30ca5e..208c9cd 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
-       <ListPreference android:dialogTitle="@string/pref_multiplier_title" android:key="global.multipliers" android:title="@string/pref_multipliers" android:entryValues="@array/multiplier_values" android:entries="@array/multiplier_labels" android:defaultValue="1" />
+       <ListPreference android:dialogTitle="@string/pref_multiplier_title" android:key="global.multipliers" android:title="@string/pref_multipliers" android:summary="@string/pref_multipliers_summary" android:entryValues="@array/multiplier_values" android:entries="@array/multiplier_labels" android:defaultValue="1" />
 </PreferenceScreen>
index f07f677..bdb51ac 100644 (file)
@@ -8,9 +8,9 @@ import org.netxms.client.objects.GenericObject;
 import org.netxms.ui.android.R;
 import org.netxms.ui.android.main.adapters.ActivityListAdapter;
 import org.netxms.ui.android.main.fragments.AlarmBrowserFragment;
-import org.netxms.ui.android.main.fragments.NodeInfoFragment;
 import org.netxms.ui.android.service.ClientConnectorService.ConnectionStatus;
 
+import android.annotation.SuppressLint;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.SharedPreferences;
@@ -20,7 +20,6 @@ import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.preference.PreferenceManager;
-import android.util.Log;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
@@ -43,12 +42,11 @@ public class HomeScreen extends AbstractClientActivity implements OnItemClickLis
        public static final int ACTIVITY_ALARMS = 1;
        public static final int ACTIVITY_DASHBOARDS = 2;
        public static final int ACTIVITY_NODES = 3;
-       public static final int ACTIVITY_GRAPHS = 4;
-       public static final int ACTIVITY_MACADDRESS = 5;
-       public static final int ACTIVITY_TEST = 6;
+       public static final int ACTIVITY_ENTIRENETWORK = 4;
+       public static final int ACTIVITY_GRAPHS = 5;
+       public static final int ACTIVITY_MACADDRESS = 6;
        public static final String INTENTIONAL_EXIT_KEY = "IntentionalExit";
 
-       private static final String TAG = "nxclient/HomeScreen";
        private ActivityListAdapter adapter;
        private TextView statusText;
 
@@ -98,6 +96,7 @@ public class HomeScreen extends AbstractClientActivity implements OnItemClickLis
         * 
         * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
         */
+       @SuppressLint("InlinedApi")
        @Override
        public boolean onCreateOptionsMenu(Menu menu)
        {
@@ -152,7 +151,10 @@ public class HomeScreen extends AbstractClientActivity implements OnItemClickLis
                                        startActivity(new Intent(this, AlarmBrowserFragment.class));
                                        break;
                                case ACTIVITY_NODES:
-                                       startActivity(new Intent(this, NodeBrowser.class));
+                                       startActivity(new Intent(this, NodeBrowser.class).putExtra("parentId", GenericObject.SERVICEROOT));
+                                       break;
+                               case ACTIVITY_ENTIRENETWORK:
+                                       startActivity(new Intent(this, NodeBrowser.class).putExtra("parentId", GenericObject.NETWORK));
                                        break;
                                case ACTIVITY_GRAPHS:
                                        startActivity(new Intent(this, GraphBrowser.class));
@@ -163,18 +165,13 @@ public class HomeScreen extends AbstractClientActivity implements OnItemClickLis
                                case ACTIVITY_DASHBOARDS:
                                        startActivity(new Intent(this, DashboardBrowser.class));
                                        break;
-                               case ACTIVITY_TEST:
-                                       Log.d(TAG, "ACTIVITY_TEST");
-                                       Intent newIntent = new Intent(this, NodeInfoFragment.class);
-                                       newIntent.putExtra("objectId", (long)345);
-                                       startActivity(newIntent);
-                                       break;
                                default:
                                        break;
                        }
                else
                        showToast(getString(R.string.notify_disconnected));
        }
+
        /**
         * @param text
         */
@@ -206,6 +203,7 @@ public class HomeScreen extends AbstractClientActivity implements OnItemClickLis
        {
                refreshPendingAlarms();
                ArrayList<AbstractObject> objList = new ArrayList<AbstractObject>();
+               objList.add(service.findObjectById(GenericObject.NETWORK));
                objList.add(service.findObjectById(GenericObject.SERVICEROOT));
                objList.add(service.findObjectById(GenericObject.DASHBOARDROOT));
                adapter.setTopNodes(objList);
index f94a37b..cddcd1d 100644 (file)
@@ -11,6 +11,7 @@ import java.util.Stack;
 import org.netxms.client.NXCSession;
 import org.netxms.client.constants.NodePoller;
 import org.netxms.client.objects.AbstractObject;
+import org.netxms.client.objects.GenericObject;
 import org.netxms.client.objects.Node;
 import org.netxms.client.objecttools.ObjectTool;
 import org.netxms.ui.android.NXApplication;
@@ -49,10 +50,10 @@ import android.widget.TextView;
 
 public class NodeBrowser extends AbstractClientActivity
 {
-       private static final String TAG = "nxclient/SyncMissingObjectsTask";
+       private static final String TAG = "nxclient/NodeBrowser";
        private ListView listView;
        private ObjectListAdapter adapter;
-       private final long initialParent = 2;
+       private long initialParent;
        private AbstractObject currentParent = null;
        private final Stack<AbstractObject> containerPath = new Stack<AbstractObject>();
        private long[] savedPath = null;
@@ -71,6 +72,8 @@ public class NodeBrowser extends AbstractClientActivity
                TextView title = (TextView)findViewById(R.id.ScreenTitlePrimary);
                title.setText(R.string.nodes_title);
 
+               initialParent = getIntent().getIntExtra("parentId", GenericObject.SERVICEROOT);
+
                // keeps current list of nodes as datasource for listview
                adapter = new ObjectListAdapter(this);
 
@@ -83,7 +86,10 @@ public class NodeBrowser extends AbstractClientActivity
                        public void onItemClick(AdapterView parent, View v, int position, long id)
                        {
                                AbstractObject obj = (AbstractObject)adapter.getItem(position);
-                               if ((obj.getObjectClass() == AbstractObject.OBJECT_CONTAINER) || (obj.getObjectClass() == AbstractObject.OBJECT_CLUSTER))
+                               if ((obj.getObjectClass() == AbstractObject.OBJECT_CONTAINER) ||
+                                               (obj.getObjectClass() == AbstractObject.OBJECT_SUBNET) ||
+                                               (obj.getObjectClass() == AbstractObject.OBJECT_CLUSTER) ||
+                                               (obj.getObjectClass() == AbstractObject.OBJECT_ZONE))
                                {
                                        containerPath.push(currentParent);
                                        currentParent = obj;
index 0cd9898..fea9c75 100644 (file)
@@ -28,13 +28,30 @@ import android.widget.LinearLayout.LayoutParams;
  */
 public class ActivityListAdapter extends BaseAdapter
 {
-       private static final int[] activityId = { HomeScreen.ACTIVITY_ALARMS, HomeScreen.ACTIVITY_DASHBOARDS,
-                       HomeScreen.ACTIVITY_NODES, HomeScreen.ACTIVITY_GRAPHS, HomeScreen.ACTIVITY_MACADDRESS };
-//             HomeScreen.ACTIVITY_NODES, HomeScreen.ACTIVITY_GRAPHS, HomeScreen.ACTIVITY_MACADDRESS, HomeScreen.ACTIVITY_TEST };
-       private static final int[] imageId = { R.drawable.alarms, R.drawable.dashboard,
-                       R.drawable.nodes, R.drawable.graphs, R.drawable.macaddress, R.drawable.icon };
-       private static final int[] textId = { R.string.home_screen_alarms, R.string.home_screen_dashboards,
-                       R.string.home_screen_nodes, R.string.home_screen_graphs, R.string.home_screen_macaddress, R.string.home };
+       private static final int[] activityId = {
+                       HomeScreen.ACTIVITY_ALARMS,
+                       HomeScreen.ACTIVITY_DASHBOARDS,
+                       HomeScreen.ACTIVITY_NODES,
+                       HomeScreen.ACTIVITY_ENTIRENETWORK,
+                       HomeScreen.ACTIVITY_GRAPHS,
+                       HomeScreen.ACTIVITY_MACADDRESS };
+//             HomeScreen.ACTIVITY_TEST };
+       private static final int[] imageId = {
+                       R.drawable.alarms,
+                       R.drawable.dashboard,
+                       R.drawable.nodes,
+                       R.drawable.entire_network,
+                       R.drawable.graphs,
+                       R.drawable.macaddress,
+                       R.drawable.icon };
+       private static final int[] textId = {
+                       R.string.home_screen_alarms,
+                       R.string.home_screen_dashboards,
+                       R.string.home_screen_nodes,
+                       R.string.home_screen_entire_network,
+                       R.string.home_screen_graphs,
+                       R.string.home_screen_macaddress,
+                       R.string.home };
        private static final int[] statusImageId = {
                        R.drawable.status_normal, // STATUS_NORMAL = 0;
                        R.drawable.status_warning, // STATUS_WARNING = 1;
@@ -46,9 +63,17 @@ public class ActivityListAdapter extends BaseAdapter
                        R.drawable.status_disabled, // STATUS_DISABLED = 7;
                        R.drawable.status_testing // STATUS_TESTING = 8;
        };
-       private static final int[] alarmId = { R.drawable.alarm_pg, R.drawable.alarm_p1, R.drawable.alarm_p2,
-                       R.drawable.alarm_p3, R.drawable.alarm_p4, R.drawable.alarm_p5, R.drawable.alarm_p6,
-                       R.drawable.alarm_p7, R.drawable.alarm_p8, R.drawable.alarm_p9 };
+       private static final int[] alarmId = {
+                       R.drawable.alarm_pg,
+                       R.drawable.alarm_p1,
+                       R.drawable.alarm_p2,
+                       R.drawable.alarm_p3,
+                       R.drawable.alarm_p4,
+                       R.drawable.alarm_p5,
+                       R.drawable.alarm_p6,
+                       R.drawable.alarm_p7,
+                       R.drawable.alarm_p8,
+                       R.drawable.alarm_p9 };
        private static final int MAX_ALARMS = alarmId.length;
        private SparseArray<AbstractObject> topNodes = null;
        private final Context context;
@@ -77,6 +102,9 @@ public class ActivityListAdapter extends BaseAdapter
                        if (objList.get(i) != null)
                                switch (objList.get(i).getObjectClass())
                                {
+                                       case AbstractObject.OBJECT_NETWORK:
+                                               topNodes.put(HomeScreen.ACTIVITY_ENTIRENETWORK, objList.get(i));
+                                               break;
                                        case AbstractObject.OBJECT_DASHBOARDROOT:
                                                topNodes.put(HomeScreen.ACTIVITY_DASHBOARDS, objList.get(i));
                                                break;
@@ -157,6 +185,7 @@ public class ActivityListAdapter extends BaseAdapter
                                                infoLayer = parent.getResources().getDrawable(numAlarms >= MAX_ALARMS ? alarmId[0] : alarmId[numAlarms]);
                                        break;
                                case HomeScreen.ACTIVITY_NODES:
+                               case HomeScreen.ACTIVITY_ENTIRENETWORK:
                                case HomeScreen.ACTIVITY_DASHBOARDS:
                                        if (topNodes != null)
                                        {
index cbaa364..9cc922f 100644 (file)
@@ -393,16 +393,16 @@ public class AlarmListAdapter extends BaseAdapter
                                switch (action)
                                {
                                        case ACKNOWLEDGE:
-                                               service.acknowledgeAlarm(params[0], false);
+                                               service.acknowledgeAlarms(params[0], false);
                                                break;
                                        case STICKY_ACKNOWLEDGE:
-                                               service.acknowledgeAlarm(params[0], true);
+                                               service.acknowledgeAlarms(params[0], true);
                                                break;
                                        case RESOLVE:
-                                               service.resolveAlarm(params[0]);
+                                               service.resolveAlarms(params[0]);
                                                break;
                                        case TERMINATE:
-                                               service.terminateAlarm(params[0]);
+                                               service.terminateAlarms(params[0]);
                                                break;
                                }
                        return null;
index 077e193..4234a42 100644 (file)
@@ -205,6 +205,12 @@ public class ObjectListAdapter extends BaseAdapter
                                case AbstractObject.OBJECT_MOBILEDEVICE:
                                        objectIconId = R.drawable.object_mobiledevice;
                                        break;
+                               case AbstractObject.OBJECT_SUBNET:
+                                       objectIconId = R.drawable.object_subnet;
+                                       break;
+                               case AbstractObject.OBJECT_ZONE:
+                                       objectIconId = R.drawable.object_zone;
+                                       break;
                        }
                }
 
diff --git a/android/src/console/src/org/netxms/ui/android/main/settings/CustomSwitchPreference.java b/android/src/console/src/org/netxms/ui/android/main/settings/CustomSwitchPreference.java
new file mode 100644 (file)
index 0000000..5625232
--- /dev/null
@@ -0,0 +1,34 @@
+package org.netxms.ui.android.main.settings;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.os.Build;
+import android.preference.SwitchPreference;
+import android.util.AttributeSet;
+
+/**
+ * Custom handler for switch preference to handle bug (reset of switch when going out of screen)
+ * 
+ * @author Marco Incalcaterra (marco.incalcaterra@thinksoft.it)
+ * 
+ */
+
+@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
+public class CustomSwitchPreference extends SwitchPreference
+{
+
+       public CustomSwitchPreference(Context context)
+       {
+               this(context, null);
+       }
+
+       public CustomSwitchPreference(Context context, AttributeSet attrs)
+       {
+               this(context, attrs, android.R.attr.switchPreferenceStyle);
+       }
+
+       public CustomSwitchPreference(Context context, AttributeSet attrs, int defStyle)
+       {
+               super(context, attrs, defStyle);
+       }
+}
index cbfc633..438bc9b 100644 (file)
@@ -77,11 +77,15 @@ public class ClientConnectorService extends Service implements SessionListener
        public static final String ACTION_FORCE_DISCONNECT = "org.netxms.ui.android.ACTION_FORCE_DISCONNECT";
        public static final String ACTION_RESCHEDULE = "org.netxms.ui.android.ACTION_RESCHEDULE";
        public static final String ACTION_CONFIGURE = "org.netxms.ui.android.ACTION_CONFIGURE";
+       public static final String ACTION_ALARM_ACKNOWLEDGE = "org.netxms.ui.android.ACTION_ALARM_ACKNOWLEDGE";
+       public static final String ACTION_ALARM_RESOLVE = "org.netxms.ui.android.ACTION_ALARM_RESOLVE";
+       public static final String ACTION_ALARM_TERMINATE = "org.netxms.ui.android.ACTION_ALARM_TERMINATE";
        private static final String TAG = "nxclient/ClientConnectorService";
        private static final String LASTALARM_KEY = "LastALarmIdNotified";
 
        private static final int NOTIFY_ALARM = 1;
        private static final int NOTIFY_STATUS = 2;
+       private static final int NOTIFY_STATUS_NEVER = 0;
        private static final int NOTIFY_STATUS_ON_CONNECT = 1;
        private static final int NOTIFY_STATUS_ON_DISCONNECT = 2;
        private static final int NOTIFY_STATUS_ALWAYS = 3;
@@ -117,7 +121,7 @@ public class ClientConnectorService extends Service implements SessionListener
        private boolean encrypt = false;
        private boolean enabled = false;
        private boolean notifyAlarm = false;
-       private int notificationType = 0;
+       private int notificationType = NOTIFY_STATUS_NEVER;
        private boolean notifyIcon = false;
        private boolean notifyToast = false;
        private int schedulerPostpone = 0;
@@ -199,6 +203,12 @@ public class ClientConnectorService extends Service implements SessionListener
                                        disconnect(false);
                        else if (intent.getAction().equals(ACTION_CONFIGURE))
                                reconnect(configure());
+                       else if (intent.getAction().equals(ACTION_ALARM_ACKNOWLEDGE))
+                               acknowledgeAlarm(intent.getLongExtra("alarmId", 0), false);
+                       else if (intent.getAction().equals(ACTION_ALARM_RESOLVE))
+                               resolveAlarm(intent.getLongExtra("alarmId", 0));
+                       else if (intent.getAction().equals(ACTION_ALARM_TERMINATE))
+                               terminateAlarm(intent.getLongExtra("alarmId", 0));
                return super.onStartCommand(intent, flags, startId);
        }
 
@@ -249,11 +259,12 @@ public class ClientConnectorService extends Service implements SessionListener
        /**
         * Show alarm notification
         * 
-        * @param severity      notification severity (used to determine icon and sound)
+        * @param alarm alarm object
         * @param text  notification text
         */
-       public void alarmNotification(int severity, String text)
+       public void alarmNotification(Alarm alarm, String text)
        {
+               int severity = alarm.getCurrentSeverity();
                if (notifyAlarm)
                {
                        Intent notifyIntent = new Intent(getApplicationContext(), AlarmBrowserFragment.class);
@@ -268,7 +279,13 @@ public class ClientConnectorService extends Service implements SessionListener
                        final String sound = GetAlarmSound(severity);
                        if ((sound != null) && (sound.length() > 0))
                                nb.setSound(Uri.parse(sound));
-                       notificationManager.notify(NOTIFY_ALARM, nb.build());
+                       nb.addAction(R.drawable.alarm_acknowledged, getString(R.string.alarm_acknowledge), createPendingIntent(ACTION_ALARM_ACKNOWLEDGE, alarm.getId()));
+                       nb.addAction(R.drawable.alarm_resolved, getString(R.string.alarm_resolve), createPendingIntent(ACTION_ALARM_RESOLVE, alarm.getId()));
+                       nb.addAction(R.drawable.alarm_terminated, getString(R.string.alarm_terminate), createPendingIntent(ACTION_ALARM_TERMINATE, alarm.getId()));
+                       notificationManager.notify(NOTIFY_ALARM,
+                                       new NotificationCompat.BigTextStyle(nb)
+                                                       .bigText(text)
+                                                       .build());
                }
                else
                {
@@ -277,6 +294,22 @@ public class ClientConnectorService extends Service implements SessionListener
                                r.play();
                }
        }
+
+       /**
+        * Creates pending intent for notification area buttons
+        * 
+        * @param action        intent action
+        * @param id    alarm id on which to execute the action
+        */
+       private PendingIntent createPendingIntent(String action, long id)
+       {
+               return PendingIntent.getService(
+                               getApplicationContext(),
+                               0,
+                               new Intent(getApplicationContext(), ClientConnectorService.class).setAction(action).putExtra("alarmId", id),
+                               PendingIntent.FLAG_UPDATE_CURRENT);
+       }
+
        /**
         * Show status notification
         * 
@@ -648,7 +681,7 @@ public class ClientConnectorService extends Service implements SessionListener
                                alarms.put(lastAlarmIdNotified, alarm);
                        }
                        unknownAlarm = object == null ? alarm : null;
-                       alarmNotification(alarm.getCurrentSeverity(), ((object != null) ? object.getObjectName() : getString(R.string.node_unknown)) + ": " + alarm.getMessage());
+                       alarmNotification(alarm, ((object != null) ? object.getObjectName() : getString(R.string.node_unknown)) + ": " + alarm.getMessage());
                        refreshAlarmBrowser();
                }
        }
@@ -735,7 +768,7 @@ public class ClientConnectorService extends Service implements SessionListener
                {
                        if (unknownAlarm != null && unknownAlarm.getSourceObjectId() == object.getObjectId()) // Update <Unknown> notification
                        {
-                               alarmNotification(unknownAlarm.getCurrentSeverity(), object.getObjectName() + ": " + unknownAlarm.getMessage());
+                               alarmNotification(unknownAlarm, object.getObjectName() + ": " + unknownAlarm.getMessage());
                                unknownAlarm = null;
                        }
                        refreshHomeScreen();
@@ -947,14 +980,14 @@ public class ClientConnectorService extends Service implements SessionListener
        }
 
        /**
-        * @param ids
+        * @param id    id of alarm
+        * @param sticky        true for sticky acknwledge 
         */
-       public void acknowledgeAlarm(ArrayList<Long> ids, boolean sticky)
+       public void acknowledgeAlarm(long id, boolean sticky)
        {
                try
                {
-                       for (int i = 0; i < ids.size(); i++)
-                               session.acknowledgeAlarm(ids.get(i).longValue(), sticky);
+                       session.acknowledgeAlarm(id, sticky);
                }
                catch (Exception e)
                {
@@ -963,14 +996,22 @@ public class ClientConnectorService extends Service implements SessionListener
        }
 
        /**
-        * @param ids
+        * @param ids   list of id
+        */
+       public void acknowledgeAlarms(ArrayList<Long> ids, boolean sticky)
+       {
+               for (int i = 0; i < ids.size(); i++)
+                       acknowledgeAlarm(ids.get(i).longValue(), sticky);
+       }
+
+       /**
+        * @param id    id of alarm
         */
-       public void resolveAlarm(ArrayList<Long> ids)
+       public void resolveAlarm(long id)
        {
                try
                {
-                       for (int i = 0; i < ids.size(); i++)
-                               session.resolveAlarm(ids.get(i).longValue());
+                       session.resolveAlarm(id);
                }
                catch (Exception e)
                {
@@ -979,14 +1020,22 @@ public class ClientConnectorService extends Service implements SessionListener
        }
 
        /**
-        * @param ids
+        * @param ids   list of id
+        */
+       public void resolveAlarms(ArrayList<Long> ids)
+       {
+               for (int i = 0; i < ids.size(); i++)
+                       resolveAlarm(ids.get(i).longValue());
+       }
+
+       /**
+        * @param id    id of alarm
         */
-       public void terminateAlarm(ArrayList<Long> ids)
+       public void terminateAlarm(long id)
        {
                try
                {
-                       for (int i = 0; i < ids.size(); i++)
-                               session.terminateAlarm(ids.get(i).longValue());
+                       session.terminateAlarm(id);
                }
                catch (Exception e)
                {
@@ -995,6 +1044,15 @@ public class ClientConnectorService extends Service implements SessionListener
        }
 
        /**
+        * @param ids   list of id
+        */
+       public void terminateAlarms(ArrayList<Long> ids)
+       {
+               for (int i = 0; i < ids.size(); i++)
+                       terminateAlarm(ids.get(i).longValue());
+       }
+
+       /**
         * @param id
         * @param state
         */
index 6eba7a7..478bfd2 100644 (file)
@@ -4,7 +4,7 @@
 # Configure script
 #
 
-AC_INIT([NetXMS], [1.2.11], [bugs@netxms.org])
+AC_INIT([NetXMS], [1.2.12], [bugs@netxms.org])
 AC_CONFIG_AUX_DIR(config)
 AC_CONFIG_HEADERS(config.h)
 AM_INIT_AUTOMAKE
@@ -739,7 +739,7 @@ case "$PLATFORM" in
       fi
       ;;
    SunOS)
-      CPPFLAGS="$CPPFLAGS -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS"
+      CPPFLAGS="$CPPFLAGS -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -D__EXTENSIONS__"
       AC_MSG_CHECKING(whether C compiler accepts -O2)
       OLD_CPPFLAGS="$CPPFLAGS"
       CPPFLAGS="$CPPFLAGS -O2"
@@ -2369,6 +2369,8 @@ AC_CONFIG_FILES([
        src/agent/subagents/Makefile
        src/agent/subagents/aix/Makefile
        src/agent/subagents/darwin/Makefile
+       src/agent/subagents/db2/Makefile
+       src/agent/subagents/dbquery/Makefile
        src/agent/subagents/ecs/Makefile
        src/agent/subagents/freebsd/Makefile
        src/agent/subagents/hpux/Makefile
@@ -2398,8 +2400,7 @@ AC_CONFIG_FILES([
        src/agent/subagents/ups/Makefile
        src/agent/subagents/winnt/Makefile
        src/agent/subagents/winperf/Makefile
-   src/agent/subagents/wmi/Makefile
-   src/agent/subagents/db2/Makefile
+       src/agent/subagents/wmi/Makefile
        src/agent/tools/Makefile
        src/agent/tools/nxappget/Makefile
        src/agent/tools/nxapush/Makefile
index ca329a6..35b9eb2 100644 (file)
@@ -4,7 +4,6 @@ libnetxms:
 
 base64.h       - GPL
 base64.cpp     - GPL
-ice.h          - actual license unknown
-ice.c          - actual license unknown
 netxms-getopt.h        - GPL
 getopt.c       - GPL
+scandir.c   - GPL
diff --git a/doc/misc/embedded_nxcp.c b/doc/misc/embedded_nxcp.c
new file mode 100644 (file)
index 0000000..aaf2747
--- /dev/null
@@ -0,0 +1,231 @@
+/**
+ * NXCP message builder for embedded systems
+ *
+ * Copyright (c) 2014 Raden Solutions
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Configuration
+ */
+#define MAX_MSG_SIZE        512
+#define KEEP_MESSAGE_ID     1
+#define ALLOW_STRING_FIELDS 1
+#define ALLOW_INT64_FIELDS  0
+#define ALLOW_FLOAT_FIELDS  0
+#define ALLOW_BINARY_FIELDS 0
+
+/**
+ * Data types
+ */
+#define CSCP_DT_INTEGER    0
+#define CSCP_DT_STRING     1
+#define CSCP_DT_INT64      2
+#define CSCP_DT_INT16      3
+#define CSCP_DT_BINARY     4
+#define CSCP_DT_FLOAT      5
+
+/**
+ * Message flags
+ */
+#define MF_BINARY          0x0001
+#define MF_END_OF_FILE     0x0002
+#define MF_DONT_ENCRYPT    0x0004
+#define MF_END_OF_SEQUENCE 0x0008
+#define MF_REVERSE_ORDER   0x0010
+#define MF_CONTROL         0x0020
+
+
+#pragma pack(1)
+
+/**
+ * Data field structure
+ */
+typedef struct
+{
+   uint32_t id;      // Variable identifier
+   char type;         // Data type
+   char padding;      // Padding
+   uint16_t wInt16;
+   union
+   {
+      uint32_t dwInteger;
+      uint64_t qwInt64;
+      double dFloat;
+      struct
+      {
+         uint32_t len;
+         uint16_t value[1];
+      } string;
+   } data;
+} NXCP_DF;
+
+#define df_int16  wInt16
+#define df_int32  data.dwInteger
+#define df_int64  data.qwInt64
+#define df_real   data.dFloat
+#define df_string data.string
+
+/**
+ * Message structure
+ */
+typedef struct
+{
+   uint16_t code;      // Message (command) code
+   uint16_t flags;     // Message flags
+   uint32_t size;      // Message size (including header) in bytes
+   uint32_t id;        // Unique message identifier
+   uint32_t numFields; // Number of fields in message
+} NXCP_MESSAGE_HEADER;
+
+#pragma pack()
+
+/**
+ * NXCP message buffer
+ */
+char nxcp_message[MAX_MSG_SIZE] = "\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
+
+#if KEEP_MESSAGE_ID
+static uint32_t nxcp_message_id = 1;
+#endif
+static char *curr;
+
+/**
+ * Initialize message
+ */
+void nxcp_init_message()
+{
+   ((NXCP_MESSAGE_HEADER *)nxcp_message)->numFields = 0;
+   curr = nxcp_message + 16;
+}
+
+/**
+ * Add INT16 field
+ */
+void nxcp_add_int16(uint32_t id, uint16_t value)
+{
+   NXCP_DF *df = (NXCP_DF *)curr;
+   df->id = htonl(id);
+   df->type = CSCP_DT_INT16;
+   df->df_int16 = htons(value);
+   curr += 8;
+   ((NXCP_MESSAGE_HEADER *)nxcp_message)->numFields++;
+}
+
+/**
+ * Add INT32 field
+ */
+void nxcp_add_int32(uint32_t id, uint32_t value)
+{
+   NXCP_DF *df = (NXCP_DF *)curr;
+   df->id = htonl(id);
+   df->type = CSCP_DT_INTEGER;
+   df->df_int32 = htonl(value);
+   curr += 16;
+   ((NXCP_MESSAGE_HEADER *)nxcp_message)->numFields++;
+}
+
+#if ALLOW_INT64_FIELDS
+
+/**
+ * Add INT64 field
+ */
+void nxcp_add_int64(uint32_t id, uint64_t value)
+{
+   NXCP_DF *df = (NXCP_DF *)curr;
+   df->id = htonl(id);
+   df->type = CSCP_DT_INT64;
+   df->df_int64 = htonll(value);
+   curr += 16;
+   ((NXCP_MESSAGE_HEADER *)nxcp_message)->numFields++;
+}
+
+#endif
+
+#if ALLOW_STRING_FIELDS
+
+/**
+ * Add string field
+ */
+void nxcp_add_string(uint32_t id, const char *value)
+{
+   uint32_t l;
+   const char *p;
+   NXCP_DF *df = (NXCP_DF *)curr;
+   df->id = htonl(id);
+   df->type = CSCP_DT_STRING;
+   for(l = 0, p = value, curr += 12; *p != 0; l++, p++)
+   {
+      *(curr++) = 0;
+      *(curr++) = *p;
+   }
+   df->df_string.len = htonl(l);
+   int padding = 8 - (l + 12) % 8;
+   curr += (padding < 8) ? padding : 0;
+   ((NXCP_MESSAGE_HEADER *)nxcp_message)->numFields++;
+}
+
+#endif
+
+#if ALLOW_BINARY_FIELDS
+
+/**
+ * Add binary field
+ */
+void nxcp_add_binary(uint32_t id, const char *value, uint32_t len)
+{
+   NXCP_DF *df = (NXCP_DF *)curr;
+   df->id = htonl(id);
+   df->type = CSCP_DT_BINARY;
+   df->df_string.len = htonl(len);
+   curr += 12;
+   memcpy(curr, value, len);
+   curr += len;
+   int padding = 8 - (len + 12) % 8;
+   curr += (padding < 8) ? padding : 0;
+   ((NXCP_MESSAGE_HEADER *)nxcp_message)->numFields++;
+}
+
+#endif
+
+/**
+ * Finalize message. Returns number of bytes to be sent from nxcp_message array.
+ */
+uint32_t nxcp_finalize()
+{
+   uint32_t l = (uint32_t)(curr - nxcp_message);
+   ((NXCP_MESSAGE_HEADER *)nxcp_message)->size = htonl(l);
+   ((NXCP_MESSAGE_HEADER *)nxcp_message)->numFields = htonl(((NXCP_MESSAGE_HEADER *)nxcp_message)->numFields);
+#if KEEP_MESSAGE_ID
+   ((NXCP_MESSAGE_HEADER *)nxcp_message)->id = htonl(nxcp_message_id++);
+#endif
+   return l;
+}
+#if 0
+
+/**
+ * Example
+ */
+void example()
+{
+   nxcp_init_message();
+   nxcp_add_int16(1, 120);
+   nxcp_add_string(2, "test message");
+   uint32_t l = nxcp_finalize();
+   /* now send l bytes from nxcp_message to the network */
+   send(sock, nxcp_message, l, 0);
+}
+
+#endif
index 010fc09..6955743 100644 (file)
@@ -1,6 +1,6 @@
 /* 
 ** NetXMS - Network Management System
-** 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 Lesser General Public License as published by
@@ -30,9 +30,9 @@
  */
 #define NETXMS_VERSION_MAJOR        1
 #define NETXMS_VERSION_MINOR        2
-#define NETXMS_VERSION_RELEASE      11
-#define NETXMS_VERSION_STRING       _T("1.2.11")
-#define NETXMS_VERSION_STRING_A     "1.2.11"
+#define NETXMS_VERSION_RELEASE      12
+#define NETXMS_VERSION_STRING       _T("1.2.12")
+#define NETXMS_VERSION_STRING_A     "1.2.12"
 
 /**
  * Current client-server protocol version
index c4a28ed..92fc85a 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
 ** NetXMS - Network Management System
 ** Copyright (C) 2003-2013 Victor Kirhenshtein
 **
@@ -23,6 +23,6 @@
 #ifndef _netxmsdb_h
 #define _netxmsdb_h
 
-#define DB_FORMAT_VERSION   302
+#define DB_FORMAT_VERSION   304
 
 #endif
index f2862b4..bc4bc7b 100644 (file)
 #define DCIDESC_SYSTEM_PLATFORMNAME               _T("Platform name")
 #define DCIDESC_PROCESS_COUNT                     _T("Number of {instance} processes")
 #define DCIDESC_PROCESS_COUNTEX                   _T("Number of {instance} processes (extended)")
+#define DCIDESC_PROCESS_ZOMBIE_COUNT              _T("Number of {instance} zombie processes")
 #define DCIDESC_PROCESS_CPUTIME                   _T("Total execution time for process {instance}")
 #define DCIDESC_PROCESS_GDIOBJ                    _T("GDI objects used by process {instance}")
 #define DCIDESC_PROCESS_IO_OTHERB                 _T("")
@@ -382,7 +383,7 @@ typedef struct
    TCHAR name[MAX_PARAM_NAME];
    LONG (* handler)(const TCHAR *, const TCHAR *, Table *);
    const TCHAR *arg;
-       TCHAR instanceColumns[MAX_COLUMN_NAME * MAX_INSTANCE_COLUMNS];
+   TCHAR instanceColumns[MAX_COLUMN_NAME * MAX_INSTANCE_COLUMNS];
    TCHAR description[MAX_DB_STRING];
 } NETXMS_SUBAGENT_TABLE;
 
index c89a8f5..bd9da75 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
 ** NetXMS - Network Management System
 ** Copyright (C) 2003-2013 Victor Kirhenshtein
 **
@@ -484,6 +484,10 @@ typedef struct
 #define CMD_GET_SUBNET_ADDRESS_MAP     0x011C
 #define CMD_FILE_MONITORING            0x011D
 #define CMD_CANCEL_FILE_MONITORING     0x011E
+#define CMD_CHANGE_OBJECT_TOOL_STATUS  0x011F
+#define CMD_SET_ALARM_STATUS_FLOW      0x0120
+#define CMD_DELETE_ALARM_NOTE          0x0121
+
 #define CMD_RS_LIST_REPORTS            0x1100
 #define CMD_RS_GET_REPORT              0x1101
 #define CMD_RS_SCHEDULE_EXECUTION      0x1102
@@ -841,7 +845,7 @@ typedef struct
 #define VID_NUM_ORDERING_COLUMNS    ((UINT32)345)
 #define VID_SYSTEM_TAG              ((UINT32)346)
 #define VID_NUM_ENUMS               ((UINT32)347)
-#define VID_NUM_PUSH_PARAMETERS     ((UINT32)348) 
+#define VID_NUM_PUSH_PARAMETERS     ((UINT32)348)
 #define VID_OLD_PASSWORD            ((UINT32)349)
 #define VID_MIN_PASSWORD_LENGTH     ((UINT32)350)
 #define VID_LAST_LOGIN              ((UINT32)351)
@@ -954,6 +958,8 @@ typedef struct
 #define VID_FILE_SIZE_LIMIT         ((UINT32)458)
 #define VID_FILE_FOLLOW             ((UINT32)459)
 #define VID_FILE_DATA               ((UINT32)460)
+#define VID_ALARM_STATUS_FLOW_STATE ((UINT32)461)
+#define VID_GROUPS                  ((UINT32)462)
 
 // Base variabe for single threshold in message
 #define VID_THRESHOLD_BASE          ((UINT32)0x00800000)
index bb0e0b8..130e879 100644 (file)
@@ -850,8 +850,8 @@ typedef struct _dir_struc_w
 #endif
 
 int LIBNETXMS_EXPORTABLE ConnectEx(SOCKET s, struct sockaddr *addr, int len, UINT32 timeout);
-int LIBNETXMS_EXPORTABLE SendEx(SOCKET, const void *, size_t, int, MUTEX);
-int LIBNETXMS_EXPORTABLE RecvEx(SOCKET nSocket, const void *pBuff, size_t nSize, int nFlags, UINT32 dwTimeout);
+int LIBNETXMS_EXPORTABLE SendEx(SOCKET hSocket, const void *data, size_t len, int flags, MUTEX mutex);
+int LIBNETXMS_EXPORTABLE RecvEx(SOCKET hSocket, void *data, size_t len, int flags, UINT32 timeout);
 #endif   /* __cplusplus */
 
 #ifdef __cplusplus
index a7bf64c..38089bf 100644 (file)
@@ -401,29 +401,30 @@ enum
 /**
  * Notification codes
  */
-#define NX_NOTIFY_SHUTDOWN             1
-#define NX_NOTIFY_EVENTDB_CHANGED      2
-#define NX_NOTIFY_ALARM_DELETED        3
-#define NX_NOTIFY_NEW_ALARM            4
-#define NX_NOTIFY_ALARM_CHANGED        5
-#define NX_NOTIFY_ACTION_CREATED       6
-#define NX_NOTIFY_ACTION_MODIFIED      7
-#define NX_NOTIFY_ACTION_DELETED       8
-#define NX_NOTIFY_OBJTOOLS_CHANGED     9
-#define NX_NOTIFY_DBCONN_STATUS        10
-#define NX_NOTIFY_ALARM_TERMINATED     11
-#define NX_NOTIFY_GRAPHS_CHANGED       12
-#define NX_NOTIFY_ETMPL_CHANGED        13
-#define NX_NOTIFY_ETMPL_DELETED        14
-#define NX_NOTIFY_OBJTOOL_DELETED      15
-#define NX_NOTIFY_TRAPCFG_CREATED      16
-#define NX_NOTIFY_TRAPCFG_MODIFIED     17
-#define NX_NOTIFY_TRAPCFG_DELETED      18
-#define NX_NOTIFY_MAPTBL_CHANGED       19
-#define NX_NOTIFY_MAPTBL_DELETED       20
-#define NX_NOTIFY_DCISUMTBL_CHANGED    21
-#define NX_NOTIFY_DCISUMTBL_DELETED    22
-#define NX_NOTIFY_CERTIFICATE_CHANGED  23
+#define NX_NOTIFY_SHUTDOWN                   1
+#define NX_NOTIFY_EVENTDB_CHANGED            2
+#define NX_NOTIFY_ALARM_DELETED              3
+#define NX_NOTIFY_NEW_ALARM                  4
+#define NX_NOTIFY_ALARM_CHANGED              5
+#define NX_NOTIFY_ACTION_CREATED             6
+#define NX_NOTIFY_ACTION_MODIFIED            7
+#define NX_NOTIFY_ACTION_DELETED             8
+#define NX_NOTIFY_OBJTOOLS_CHANGED           9
+#define NX_NOTIFY_DBCONN_STATUS              10
+#define NX_NOTIFY_ALARM_TERMINATED           11
+#define NX_NOTIFY_GRAPHS_CHANGED             12
+#define NX_NOTIFY_ETMPL_CHANGED              13
+#define NX_NOTIFY_ETMPL_DELETED              14
+#define NX_NOTIFY_OBJTOOL_DELETED            15
+#define NX_NOTIFY_TRAPCFG_CREATED            16
+#define NX_NOTIFY_TRAPCFG_MODIFIED           17
+#define NX_NOTIFY_TRAPCFG_DELETED            18
+#define NX_NOTIFY_MAPTBL_CHANGED             19
+#define NX_NOTIFY_MAPTBL_DELETED             20
+#define NX_NOTIFY_DCISUMTBL_CHANGED          21
+#define NX_NOTIFY_DCISUMTBL_DELETED          22
+#define NX_NOTIFY_CERTIFICATE_CHANGED        23
+#define NX_NOTIFY_ALARM_STATUS_FLOW_CHANGED  24
 
 /**
  * Request completion codes
@@ -681,6 +682,7 @@ enum
 #define USER_MODIFY_TEMP_DISABLE       0x00000200
 #define USER_MODIFY_CUSTOM_ATTRIBUTES  0x00000400
 #define USER_MODIFY_XMPP_ID            0x00000800
+#define USER_MODIFY_GROUP_MEMBERSHIP   0x00001000
 
 /**
  * User certificate mapping methods
@@ -1028,6 +1030,7 @@ typedef struct
    TCHAR szHelpDeskRef[MAX_HELPDESK_REF_LEN];
    void *pUserData;        // Can be freely used by client application
        UINT32 noteCount;        // Number of notes added to alarm
+   UINT32 ackTimeout;  // Sticky acknowledgment end time. If acknowladgmant without timeout put 0
 } NXC_ALARM;
 
 /**
index 7aacff6..174863c 100644 (file)
@@ -117,6 +117,8 @@ public:
    void disableEncryption() { m_wFlags |= MF_DONT_ENCRYPT; }
    void setEndOfSequence() { m_wFlags |= MF_END_OF_SEQUENCE; }
    void setReverseOrderFlag() { m_wFlags |= MF_REVERSE_ORDER; }
+
+   static String dump(CSCP_MESSAGE *msg, int version);
 };
 
 /**
@@ -184,6 +186,7 @@ private:
 #ifdef _WITH_ENCRYPTION
    EVP_CIPHER_CTX m_encryptor;
    EVP_CIPHER_CTX m_decryptor;
+   MUTEX m_encryptorLock;
 #endif
 
        NXCPEncryptionContext();
index b3e292b..1526c5f 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
 ** NetXMS - Network Management System
 ** Copyright (C) 2003-2011 Victor Kirhenshtein
 **
@@ -45,6 +45,7 @@
 #define TF_REQUIRES_AGENT           ((DWORD)0x00000002)
 #define TF_REQUIRES_OID_MATCH       ((DWORD)0x00000004)
 #define TF_ASK_CONFIRMATION         ((DWORD)0x00000008)
+#define TF_DISABLED                 ((DWORD)0x00000020)
 #define TF_SNMP_INDEXED_BY_VALUE    ((DWORD)0x00010000)
 
 
index dc82171..6878352 100644 (file)
@@ -41,7 +41,7 @@ INSERT INTO object_tools_table_columns (tool_id,col_number,col_name,col_oid,col_
        VALUES (9,0,'Parameter',' ',CFMT_STRING,1);
 
 INSERT INTO object_tools (tool_id,tool_name,tool_type,tool_data,flags,matching_oid,description,confirmation_text)
-       VALUES (10,'&Info->&Agent->Supported &enums',TOOL_TYPE_TABLE_AGENT,'Supported enums#7FAgent.SupportedEnums#7F^(.*)',2,' ','Show list of enums supported by agent','#00');
+       VALUES (10,'&Info->&Agent->Supported &lists',TOOL_TYPE_TABLE_AGENT,'Supported lists#7FAgent.SupportedLists#7F^(.*)',2,' ','Show list of lists supported by agent','#00');
 INSERT INTO object_tools_table_columns (tool_id,col_number,col_name,col_oid,col_format,col_substr)
        VALUES (10,0,'Parameter',' ',CFMT_STRING,1);
 
index 3e43425..dd53a08 100644 (file)
@@ -553,7 +553,7 @@ CREATE TABLE trusted_nodes
 /*
 ** Data collection items
 **
-** If node_id != 0, it's an item bound to node,        and template_id points to 
+** If node_id != 0, it's an item bound to node,        and template_id points to
 ** the template used for creating this item. In this case, template_id = 0
 ** means that item was created manually.
 ** If node_id = 0, it's a template item, and template_id points to a template
@@ -563,7 +563,7 @@ CREATE TABLE trusted_nodes
 CREATE TABLE items
 (
        item_id integer not null,
-       node_id integer not null,       
+       node_id integer not null,
        template_id integer not null,
        template_item_id integer not null,
        name varchar(1023) null,
@@ -601,7 +601,7 @@ CREATE INDEX idx_items_node_id ON items(node_id);
 CREATE TABLE dc_tables
 (
        item_id integer not null,
-       node_id integer not null,       
+       node_id integer not null,
        template_id integer not null,
        template_item_id integer not null,
        name varchar(1023) null,
@@ -917,6 +917,7 @@ CREATE TABLE alarms
        term_by integer not null,        // ID of user who was terminated alarm
        timeout integer not null,
        timeout_event integer not null,
+       ack_timeout integer not null,
        PRIMARY KEY(alarm_id)
 ) TABLE_TYPE;
 
@@ -996,7 +997,7 @@ CREATE TABLE agent_pkg
        platform varchar(63),
        pkg_file varchar(255),
        description varchar(255),
-       PRIMARY KEY(pkg_id)     
+       PRIMARY KEY(pkg_id)
 ) TABLE_TYPE;
 
 
index 5deb48e..119eb07 100644 (file)
@@ -124,6 +124,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 ('StatusSingleThreshold','75',1,1);
 INSERT INTO config (var_name,var_value,is_visible,need_server_restart) VALUES ('StatusThresholds','503C2814',1,1);
 INSERT INTO config (var_name,var_value,is_visible,need_server_restart) VALUES ('StatusTranslation','01020304',1,1);
+INSERT INTO config (var_name,var_value,is_visible,need_server_restart) VALUES ('StrictAlarmStatusFlow','0',1,0);
 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);
@@ -194,7 +195,7 @@ INSERT INTO acl (object_id,user_id,access_rights) VALUES (9,-2147483647,2047);
 #define ID_GROUP_1 -2147483647
 #define ID_GROUP_2 -2147483646
 
-INSERT INTO event_groups (id,name,description,range_start,range_end) 
+INSERT INTO event_groups (id,name,description,range_start,range_end)
    VALUES (ID_GROUP_1,'NodeStatus','All events reporting about node status change',0,0);
 INSERT INTO event_groups (id,name,description,range_start,range_end)
    VALUES (ID_GROUP_2,'NewObjects','All events reporting about new objects creation',0,0);
index f9d936d..6a053b4 100644 (file)
@@ -33,11 +33,9 @@ UINT32 g_dwRejectedConnections = 0;
 CommSession **g_pSessionList = NULL;
 MUTEX g_hSessionListAccess;
 
-
-//
-// Static data
-//
-
+/**
+ * Static data
+ */
 static MUTEX m_mutexWatchdogActive = INVALID_MUTEX_HANDLE;
 
 /**
@@ -69,11 +67,9 @@ static BOOL IsValidServerAddr(UINT32 dwAddr, BOOL *pbMasterServer, BOOL *pbContr
    return FALSE;
 }
 
-
-//
-// Register new session in list
-//
-
+/**
+ * Register new session in list
+ */
 static BOOL RegisterSession(CommSession *pSession)
 {
    UINT32 i;
@@ -93,11 +89,9 @@ static BOOL RegisterSession(CommSession *pSession)
    return FALSE;
 }
 
-
-//
-// Unregister session
-//
-
+/**
+ * Unregister session
+ */
 void UnregisterSession(UINT32 dwIndex)
 {
    MutexLock(g_hSessionListAccess);
@@ -256,20 +250,15 @@ THREAD_RESULT THREAD_CALL ListenerThread(void *)
  */
 THREAD_RESULT THREAD_CALL SessionWatchdog(void *)
 {
-   UINT32 i;
-   time_t now;
-
    m_mutexWatchdogActive = MutexCreate();
    MutexLock(m_mutexWatchdogActive);
 
    ThreadSleep(5);
    while(!(g_dwFlags & AF_SHUTDOWN))
    {
-      ThreadSleep(1);
-
       MutexLock(g_hSessionListAccess);
-      now = time(NULL);
-      for(i = 0; i < g_dwMaxSessions; i++)
+      time_t now = time(NULL);
+      for(UINT32 i = 0; i < g_dwMaxSessions; i++)
          if (g_pSessionList[i] != NULL)
          {
             if (g_pSessionList[i]->getTimeStamp() < (now - (time_t)g_dwIdleTimeout))
@@ -279,11 +268,12 @@ THREAD_RESULT THREAD_CALL SessionWatchdog(void *)
                                }
          }
       MutexUnlock(g_hSessionListAccess);
+      ThreadSleep(5);
    }
 
    // Disconnect all sessions
    MutexLock(g_hSessionListAccess);
-   for(i = 0; i < g_dwMaxSessions; i++)
+   for(UINT32 i = 0; i < g_dwMaxSessions; i++)
       if (g_pSessionList[i] != NULL)
          g_pSessionList[i]->disconnect();
    MutexUnlock(g_hSessionListAccess);
@@ -295,11 +285,9 @@ THREAD_RESULT THREAD_CALL SessionWatchdog(void *)
    return THREAD_OK;
 }
 
-
-//
-// Handler for Agent.ActiveConnections parameter
-//
-
+/**
+ * Handler for Agent.ActiveConnections parameter
+ */
 LONG H_ActiveConnections(const TCHAR *pszCmd, const TCHAR *pArg, TCHAR *pValue)
 {
    int nCounter;
index ce8cd3e..a077495 100644 (file)
@@ -297,11 +297,15 @@ UINT32 ExecuteCommand(TCHAR *pszCommand, StringList *args, pid_t *pid)
 /**
  * Structure for passing data to popen() worker
  */
-struct POPEN_WORKER_DATA
+class POPEN_WORKER_DATA
 {
+public:
+   POPEN_WORKER_DATA() {}
+   virtual ~POPEN_WORKER_DATA() {}
+
        int status;
        TCHAR *cmdLine;
-       TCHAR value[MAX_RESULT_LENGTH];
+   StringList values;
        CONDITION finished;
        CONDITION released;
 };
@@ -316,27 +320,35 @@ static THREAD_RESULT THREAD_CALL POpenWorker(void *arg)
 
        if ((hPipe = _tpopen(data->cmdLine, _T("r"))) != NULL)
        {
-               TCHAR *pTmp;
+      data->status = SYSINFO_RC_SUCCESS;
 
-               data->value[0] = 0;
-               TCHAR *ret = safe_fgetts(data->value, MAX_RESULT_LENGTH, hPipe);
-      if ((ret == NULL) && feof(hPipe))
-         ret = data->value;
-               pclose(hPipe);
-          DebugPrintf(INVALID_INDEX, 4, _T("H_ExternalParameter/POpenWorker: worker thread pipe read result: %p"), ret);
-               if (ret != NULL)
-               {
-                       if ((pTmp = _tcschr(data->value, _T('\n'))) != NULL)
+      while (true)
+      {
+         TCHAR value[MAX_RESULT_LENGTH];
+
+         TCHAR *ret = safe_fgetts(value, MAX_RESULT_LENGTH, hPipe);
+         if (ret == NULL)
+         {
+            if (!feof(hPipe))
+            {
+               DebugPrintf(INVALID_INDEX, 4, _T("H_ExternalParameter/POpenWorker: worker thread pipe read error: %s"), _tcserror(errno));
+               data->status = SYSINFO_RC_ERROR;
+            }
+            break;
+         }
+
+         DebugPrintf(INVALID_INDEX, 4, _T("H_ExternalParameter/POpenWorker: worker thread pipe read result: %p"), ret);
+         TCHAR *pTmp;
+                       if ((pTmp = _tcschr(value, _T('\n'))) != NULL)
                        {
                                *pTmp = 0;
                        }
-                       data->status = SYSINFO_RC_SUCCESS;
-               }
-               else
-               {
-                  DebugPrintf(INVALID_INDEX, 4, _T("H_ExternalParameter/POpenWorker: worker thread pipe read error: %s"), _tcserror(errno));
-                       data->status = SYSINFO_RC_ERROR;
-               }
+         if (value[0] != 0)
+         {
+            data->values.add(value);
+         }
+      }
+               pclose(hPipe);
        }
        else
        {
@@ -350,21 +362,21 @@ static THREAD_RESULT THREAD_CALL POpenWorker(void *arg)
        ConditionWait(data->released, INFINITE);
        ConditionDestroy(data->finished);
        ConditionDestroy(data->released);
-       free(data);
+       delete data;
 
        return THREAD_OK;
 }
 
 /**
- * Handler function for external (user-defined) parameters
+ * Exec function for external (user-defined) parameters and lists
  */
-LONG H_ExternalParameter(const TCHAR *pszCmd, const TCHAR *pszArg, TCHAR *pValue)
+LONG RunExternal(const TCHAR *pszCmd, const TCHAR *pszArg, StringList *value)
 {
        TCHAR *pszCmdLine, szBuffer[1024], szTempFile[MAX_PATH];
        const TCHAR *sptr;
        int i, iSize, iStatus;
 
-   DebugPrintf(INVALID_INDEX, 4, _T("H_ExternalParameter called for \"%s\" \"%s\""), pszCmd, pszArg);
+   DebugPrintf(INVALID_INDEX, 4, _T("RunExternal called for \"%s\" \"%s\""), pszCmd, pszArg);
 
    // Substitute $1 .. $9 with actual arguments
    iSize = (int)_tcslen(pszArg) * sizeof(TCHAR);  // we don't need _tcslen + 1 because loop starts from &pszArg[1]
@@ -399,7 +411,7 @@ LONG H_ExternalParameter(const TCHAR *pszCmd, const TCHAR *pszArg, TCHAR *pValue
          pszCmdLine[i++] = *sptr;
       }
    pszCmdLine[i] = 0;
-   DebugPrintf(INVALID_INDEX, 4, _T("H_ExternalParameter: command line is \"%s\""), pszCmdLine);
+   DebugPrintf(INVALID_INDEX, 4, _T("RunExternal: command line is \"%s\""), pszCmdLine);
 
 #if defined(_WIN32)
        if (*pszArg == _T('E'))
@@ -439,22 +451,19 @@ LONG H_ExternalParameter(const TCHAR *pszCmd, const TCHAR *pszArg, TCHAR *pValue
 
                                        // Read process output
                                        char *eptr;
-#ifdef UNICODE
                                        char buffer[256];
-#define __valueptr buffer
-#else
-#define __valueptr pValue
-#endif
-                                       ReadFile(hOutput, __valueptr, MAX_RESULT_LENGTH - 1, &dwBytes, NULL);
-                                       __valueptr[dwBytes] = 0;
-                                       eptr = strchr(__valueptr, '\r');
+                                       ReadFile(hOutput, buffer, MAX_RESULT_LENGTH - 1, &dwBytes, NULL);
+                                       buffer[dwBytes] = 0;
+                                       eptr = strchr(buffer, '\r');
                                        if (eptr != NULL)
                                                *eptr = 0;
-                                       eptr = strchr(__valueptr, '\n');
+                                       eptr = strchr(buffer, '\n');
                                        if (eptr != NULL)
                                                *eptr = 0;
 #ifdef UNICODE
-                                       MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, buffer, -1, pValue, MAX_RESULT_LENGTH);
+               value->addPreallocated(WideStringFromMBString(buffer));
+#else
+               value->add(buffer);
 #endif
                                        iStatus = SYSINFO_RC_SUCCESS;
                                }
@@ -488,30 +497,31 @@ LONG H_ExternalParameter(const TCHAR *pszCmd, const TCHAR *pszArg, TCHAR *pValue
        else
        {
 #endif
-
                {
                        POPEN_WORKER_DATA *data;
 
-                       data = (POPEN_WORKER_DATA *)malloc(sizeof(POPEN_WORKER_DATA));
+                       data = new POPEN_WORKER_DATA;
                        data->cmdLine = pszCmdLine;
                        data->finished = ConditionCreate(TRUE);
                        data->released = ConditionCreate(TRUE);
                        ThreadCreate(POpenWorker, 0, data);
-                  DebugPrintf(INVALID_INDEX, 4, _T("H_ExternalParameter (shell exec): worker thread created"));
+                  DebugPrintf(INVALID_INDEX, 4, _T("RunExternal (shell exec): worker thread created"));
                        if (ConditionWait(data->finished, g_dwExecTimeout))
                        {
                                iStatus = data->status;
                                if (iStatus == SYSINFO_RC_SUCCESS)
-                                       _tcscpy(pValue, data->value);
+            {
+               value->addAll(&data->values);
+            }
                        }
                        else
                        {
                                // Timeout
-                          DebugPrintf(INVALID_INDEX, 4, _T("H_ExternalParameter (shell exec): execution timeout"));
+                          DebugPrintf(INVALID_INDEX, 4, _T("RunExternal (shell exec): execution timeout"));
                                iStatus = SYSINFO_RC_ERROR;
                        }
                        ConditionSet(data->released);   // Allow worker to destroy data
-                  DebugPrintf(INVALID_INDEX, 4, _T("H_ExternalParameter (shell exec): execution status %d"), iStatus);
+                  DebugPrintf(INVALID_INDEX, 4, _T("RunExternal (shell exec): execution status %d"), iStatus);
                }
 
 #ifdef _WIN32
@@ -522,11 +532,39 @@ LONG H_ExternalParameter(const TCHAR *pszCmd, const TCHAR *pszArg, TCHAR *pValue
    return iStatus;
 }
 
+/**
+ * Handler function for external (user-defined) parameters
+ */
+LONG H_ExternalParameter(const TCHAR *cmd, const TCHAR *arg, TCHAR *value)
+{
+   DebugPrintf(INVALID_INDEX, 4, _T("H_ExternalParameter called for \"%s\" \"%s\""), cmd, arg);
+   StringList values;
+   LONG status = RunExternal(cmd, arg, &values);
+   if (status == SYSINFO_RC_SUCCESS)
+   {
+      ret_string(value, values.getSize() > 0 ? values.getValue(0) : _T(""));
+   }
+   return status;
+}
 
-//
-// Execute external command via shell
-//
+/**
+ * Handler function for external (user-defined) lists
+ */
+LONG H_ExternalList(const TCHAR *cmd, const TCHAR *arg, StringList *value)
+{
+   DebugPrintf(INVALID_INDEX, 4, _T("H_ExternalList called for \"%s\" \"%s\""), cmd, arg);
+   StringList values;
+   LONG status = RunExternal(cmd, arg, &values);
+   if (status == SYSINFO_RC_SUCCESS)
+   {
+      value->addAll(&values);
+   }
+   return status;
+}
 
+/**
+ * Execute external command via shell
+ */
 UINT32 ExecuteShellCommand(TCHAR *pszCommand, StringList *args)
 {
    TCHAR *pszCmdLine, *sptr;
index b2b63e0..77d2e7e 100644 (file)
@@ -38,6 +38,7 @@ LONG H_SubAgentList(const TCHAR *cmd, const TCHAR *arg, StringList *value);
 LONG H_SubAgentTable(const TCHAR *cmd, const TCHAR *arg, Table *value);
 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_SystemTime(const TCHAR *cmd, const TCHAR *arg, TCHAR *value);
 
@@ -440,7 +441,7 @@ void AddTable(const TCHAR *name, LONG (* handler)(const TCHAR *, const TCHAR *,
 /**
  * Add external parameter
  */  
-BOOL AddExternalParameter(TCHAR *pszCfgLine, BOOL bShellExec) //to be TCHAR
+BOOL AddExternalParameter(TCHAR *pszCfgLine, BOOL bShellExec, BOOL bIsList) //to be TCHAR
 {
    TCHAR *pszCmdLine, *pszArg;
 
@@ -458,7 +459,14 @@ BOOL AddExternalParameter(TCHAR *pszCfgLine, BOOL bShellExec) //to be TCHAR
        pszArg = (TCHAR *)malloc((_tcslen(pszCmdLine) + 2) * sizeof(TCHAR));
        pszArg[0] = bShellExec ? _T('S') : _T('E');
        _tcscpy(&pszArg[1], pszCmdLine);
-   AddParameter(pszCfgLine, H_ExternalParameter, pszArg, DCI_DT_STRING, _T(""));
+   if (bIsList)
+   {
+      AddList(pszCfgLine, H_ExternalList, pszArg);
+   }
+   else
+   {
+      AddParameter(pszCfgLine, H_ExternalParameter, pszArg, DCI_DT_STRING, _T(""));
+   }
    return TRUE;
 }
 
index 40b691c..99cbce8 100644 (file)
@@ -149,6 +149,7 @@ static TCHAR *m_pszControlServerList = NULL;
 static TCHAR *m_pszMasterServerList = NULL;
 static TCHAR *m_pszSubagentList = NULL;
 static TCHAR *m_pszExtParamList = NULL;
+static TCHAR *m_pszExtListsList = NULL;
 static TCHAR *m_pszShExtParamList = NULL;
 static TCHAR *m_pszParamProviderList = NULL;
 static TCHAR *m_pszExtSubagentList = NULL;
@@ -165,6 +166,7 @@ static UINT32 m_dwLogHistorySize = 4;
 static UINT32 m_dwLogRotationMode = NXLOG_ROTATION_BY_SIZE;
 static TCHAR m_szDailyLogFileSuffix[64] = _T("");
 static Config *s_registry = NULL;
+static TCHAR s_executableName[MAX_PATH];
 
 #if defined(_WIN32)
 static CONDITION m_hCondShutdown = INVALID_CONDITION_HANDLE;
@@ -199,6 +201,7 @@ static NX_CFG_TEMPLATE m_cfgTemplate[] =
    { _T("ExecTimeout"), CT_LONG, 0, 0, 0, 0, &g_dwExecTimeout, NULL },
        { _T("ExternalMasterAgent"), CT_STRING, 0, 0, MAX_PATH, 0, g_masterAgent, NULL },
    { _T("ExternalParameter"), CT_STRING_LIST, '\n', 0, 0, 0, &m_pszExtParamList, NULL },
+   { _T("ExternalList"), CT_STRING_LIST, '\n', 0, 0, 0, &m_pszExtListsList, NULL },
    { _T("ExternalParameterShellExec"), CT_STRING_LIST, '\n', 0, 0, 0, &m_pszShExtParamList, NULL },
    { _T("ExternalParametersProvider"), CT_STRING_LIST, '\n', 0, 0, 0, &m_pszParamProviderList, NULL },
    { _T("ExternalSubagent"), CT_STRING_LIST, '\n', 0, 0, 0, &m_pszExtSubagentList, NULL },
@@ -365,6 +368,7 @@ static THREAD_RESULT THREAD_CALL ShutdownThread(void *pArg)
 
 #endif   /* _WIN32 */
 
+
 /**
  * Restart agent
  */
@@ -373,16 +377,6 @@ static LONG H_RestartAgent(const TCHAR *action, StringList *args, const TCHAR *d
        DebugPrintf(INVALID_INDEX, 1, _T("H_RestartAgent() called"));
 
    TCHAR szCmdLine[4096], szPlatformSuffixOption[MAX_PSUFFIX_LENGTH + 16];
-#ifdef _WIN32
-   TCHAR szExecName[MAX_PATH];
-   DWORD dwResult;
-   STARTUPINFO si;
-   PROCESS_INFORMATION pi;
-
-   GetModuleFileName(GetModuleHandle(NULL), szExecName, MAX_PATH);
-#else
-   TCHAR szExecName[MAX_PATH] = PREFIX _T("/bin/nxagentd");
-#endif
 
        if (g_szPlatformSuffix[0] != 0)
        {
@@ -394,7 +388,7 @@ static LONG H_RestartAgent(const TCHAR *action, StringList *args, const TCHAR *d
        }
 
 #ifdef _WIN32
-   _sntprintf(szCmdLine, 4096, _T("\"%s\" -c \"%s\" -n \"%s\" -e \"%s\" %s%s%s%s%s-D %d %s-X %u"), szExecName,
+   _sntprintf(szCmdLine, 4096, _T("\"%s\" -c \"%s\" -n \"%s\" -e \"%s\" %s%s%s%s%s-D %d %s-X %u"), s_executableName,
               g_szConfigFile, g_windowsServiceName, g_windowsEventSourceName,
                                  (g_dwFlags & AF_DAEMON) ? _T("-d ") : _T(""),
               (g_dwFlags & AF_HIDE_WINDOW) ? _T("-H ") : _T(""),
@@ -405,6 +399,10 @@ static LONG H_RestartAgent(const TCHAR *action, StringList *args, const TCHAR *d
               (g_dwFlags & AF_DAEMON) ? 0 : GetCurrentProcessId());
        DebugPrintf(INVALID_INDEX, 1, _T("Restarting agent with command line '%s'"), szCmdLine);
 
+   DWORD dwResult;
+   STARTUPINFO si;
+   PROCESS_INFORMATION pi;
+   
    // Fill in process startup info structure
    memset(&si, 0, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
@@ -437,7 +435,7 @@ static LONG H_RestartAgent(const TCHAR *action, StringList *args, const TCHAR *d
    }
    return dwResult;
 #else
-   _sntprintf(szCmdLine, 4096, _T("\"%s\" -c \"%s\" %s%s%s%s-D %d %s-X %lu"), szExecName,
+   _sntprintf(szCmdLine, 4096, _T("\"%s\" -c \"%s\" %s%s%s%s-D %d %s-X %lu"), s_executableName,
               g_szConfigFile, (g_dwFlags & AF_DAEMON) ? _T("-d ") : _T(""),
                                  (g_dwFlags & AF_CENTRAL_CONFIG) ? _T("-M ") : _T(""),
                                  (g_dwFlags & AF_CENTRAL_CONFIG) ? g_szConfigServer : _T(""),
@@ -478,11 +476,13 @@ static THREAD_RESULT THREAD_CALL SignalHandler(void *pArg)
        sigemptyset(&signals);
        sigaddset(&signals, SIGTERM);
        sigaddset(&signals, SIGINT);
-       sigaddset(&signals, SIGPIPE);
        sigaddset(&signals, SIGSEGV);
        sigaddset(&signals, SIGHUP);
        sigaddset(&signals, SIGUSR1);
        sigaddset(&signals, SIGUSR2);
+#if !defined(__sun) && !defined(_AIX) && !defined(__hpux)
+       sigaddset(&signals, SIGPIPE);
+#endif
 
        sigprocmask(SIG_BLOCK, &signals, NULL);
 
@@ -595,7 +595,7 @@ static void ParseServerList(TCHAR *serverList, BOOL isControl, BOOL isMaster)
                                ipAddr = INADDR_NONE;
                        netMask = 0xFFFFFFFF;
                }
-               if (g_pServerList[g_dwServerCount].dwIpAddr == INADDR_NONE)
+               if (ipAddr == INADDR_NONE)
                {
                        if (!(g_dwFlags & AF_DAEMON))
                                _tprintf(_T("Invalid server address '%s'\n"), pItem);
@@ -786,7 +786,7 @@ BOOL Initialize()
          if (pEnd != NULL)
             *pEnd = 0;
          StrStrip(pItem);
-         if (!AddExternalParameter(pItem, FALSE))
+         if (!AddExternalParameter(pItem, FALSE, FALSE))
             nxlog_write(MSG_ADD_EXT_PARAM_FAILED, EVENTLOG_WARNING_TYPE, "s", pItem);
       }
       free(m_pszExtParamList);
@@ -799,12 +799,27 @@ BOOL Initialize()
          if (pEnd != NULL)
             *pEnd = 0;
          StrStrip(pItem);
-         if (!AddExternalParameter(pItem, TRUE))
+         if (!AddExternalParameter(pItem, TRUE, FALSE))
             nxlog_write(MSG_ADD_EXT_PARAM_FAILED, EVENTLOG_WARNING_TYPE, "s", pItem);
       }
       free(m_pszShExtParamList);
    }
 
+   // Parse external lists
+   if (m_pszExtListsList != NULL)
+   {
+      for(pItem = pEnd = m_pszExtListsList; pEnd != NULL && *pItem != 0; pItem = pEnd + 1)
+      {
+         pEnd = _tcschr(pItem, _T('\n'));
+         if (pEnd != NULL)
+            *pEnd = 0;
+         StrStrip(pItem);
+         if (!AddExternalParameter(pItem, FALSE, TRUE))
+            nxlog_write(MSG_ADD_EXT_PARAM_FAILED, EVENTLOG_WARNING_TYPE, "s", pItem);
+      }
+      free(m_pszExtListsList);
+   }
+
    // Parse external parameters providers list
    if (m_pszParamProviderList != NULL)
    {
@@ -1128,7 +1143,6 @@ int main(int argc, char *argv[])
 #if defined(__sun) || defined(_AIX) || defined(__hpux)
    signal(SIGPIPE, SIG_IGN);
    signal(SIGHUP, SIG_IGN);
-   signal(SIGINT, SIG_IGN);
    signal(SIGQUIT, SIG_IGN);
    signal(SIGUSR1, SIG_IGN);
    signal(SIGUSR2, SIG_IGN);
@@ -1413,6 +1427,29 @@ int main(int argc, char *argv[])
                                g_config->loadConfigDirectory(g_szConfigIncludeDir, _T("agent"));
                                if (g_config->parseTemplate(_T("agent"), m_cfgTemplate))
                                {
+               // try to guess executable path
+#ifdef _WIN32
+               GetModuleFileName(GetModuleHandle(NULL), s_executableName, MAX_PATH);
+#else
+#ifdef UNICODE
+               char __buffer[PATH_MAX];
+#else
+#define __buffer s_executableName
+#endif
+               if (realpath(argv[0], __buffer) == NULL)
+               {
+                  // fallback
+                  nx_strncpy(s_executableName, PREFIX _T("/bin/nxagentd"), sizeof(s_executableName) / sizeof(s_executableName[0]));
+               }
+               else
+               {
+#ifdef UNICODE
+                  int len = strlen(__buffer);
+                  MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, __buffer, len, s_executableName, len);
+#endif
+               }
+#endif
+
                                        // Set exception handler
 #ifdef _WIN32
                                        if (g_dwFlags & AF_CATCH_EXCEPTIONS)
index c71c0d1..42ca3ec 100644 (file)
@@ -397,7 +397,7 @@ void AddParameter(const TCHAR *szName, LONG (* fpHandler)(const TCHAR *, const T
 void AddPushParameter(const TCHAR *name, int dataType, const TCHAR *description);
 void AddList(const TCHAR *name, LONG (* handler)(const TCHAR *, const TCHAR *, StringList *), const TCHAR *arg);
 void AddTable(const TCHAR *name, LONG (* handler)(const TCHAR *, const TCHAR *, Table *), const TCHAR *arg, const TCHAR *instanceColumns, const TCHAR *description);
-BOOL AddExternalParameter(TCHAR *pszCfgLine, BOOL bShellExec);
+BOOL AddExternalParameter(TCHAR *pszCfgLine, BOOL bShellExec, BOOL bIsList);
 UINT32 GetParameterValue(UINT32 dwSessionId, TCHAR *pszParam, TCHAR *pszValue);
 UINT32 GetListValue(UINT32 dwSessionId, TCHAR *pszParam, StringList *pValue);
 UINT32 GetTableValue(UINT32 dwSessionId, TCHAR *pszParam, Table *pValue);
index 2e37f32..24fb3cb 100644 (file)
@@ -1,6 +1,6 @@
 /* 
 ** NetXMS multiplatform core agent
-** Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 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
 
 #include "nxagentd.h"
 
-
-//
-// Externals
-//
-
+/**
+ * Externals
+ */
 LONG H_PlatformName(const TCHAR *cmd, const TCHAR *arg, TCHAR *value);
 
-
-//
-// Constants
-//
-
+/**
+ * Constants
+ */
 #define MAX_MSG_SIZE    262144
 
-
-//
-// Register agent on management server
-//
-
-BOOL RegisterOnServer(TCHAR *pszServer)
+/**
+ * Register agent on management server
+ */
+BOOL RegisterOnServer(const TCHAR *pszServer)
 {
    DWORD dwAddr;
    SOCKET hSocket;
index 6165719..c1cf957 100644 (file)
@@ -170,8 +170,7 @@ void CommSession::readThread()
 #endif
    while(1)
    {
-      if ((iErr = RecvNXCPMessage(m_hSocket, pRawMsg, m_pMsgBuffer, RAW_MSG_SIZE,
-                                  &m_pCtx, pDecryptionBuffer, INFINITE)) <= 0)
+      if ((iErr = RecvNXCPMessage(m_hSocket, pRawMsg, m_pMsgBuffer, RAW_MSG_SIZE, &m_pCtx, pDecryptionBuffer, (g_dwIdleTimeout + 1) * 1000)) <= 0)
       {
          break;
       }
@@ -187,6 +186,17 @@ void CommSession::readThread()
          continue;
       }
 
+      // Check for timeout
+      if (iErr == 3)
+      {
+         if (m_ts < time(NULL) - (time_t)g_dwIdleTimeout)
+         {
+                               DebugPrintf(m_dwIndex, 5, _T("Session disconnected by timeout (last activity timestamp is %d)"), (int)m_ts);
+            break;
+         }
+         continue;
+      }
+
       // Check that actual received packet size is equal to encoded in packet
       if ((int)ntohl(pRawMsg->dwSize) != iErr)
       {
index 683fdf4..412f519 100644 (file)
@@ -3,7 +3,7 @@
 
 [Setup]
 #include "setup.iss"
-OutputBaseFilename=nxagent-1.2.11-x64
+OutputBaseFilename=nxagent-1.2.12-x64
 ArchitecturesInstallIn64BitMode=x64
 ArchitecturesAllowed=x64
 
index e091860..c866c23 100644 (file)
@@ -3,7 +3,7 @@
 
 [Setup]
 #include "setup.iss"
-OutputBaseFilename=nxagent-1.2.11
+OutputBaseFilename=nxagent-1.2.12
 
 [Files]
 Source: "..\..\..\Release\libnetxms.dll"; DestDir: "{app}\bin"; BeforeInstall: StopService; Flags: ignoreversion
index 59cc2f6..63fa8b9 100644 (file)
@@ -1,6 +1,6 @@
 AppName=NetXMS Agent
-AppVerName=NetXMS Agent 1.2.11
-AppVersion=1.2.11
+AppVerName=NetXMS Agent 1.2.12
+AppVersion=1.2.12
 AppPublisher=NetXMS Team
 AppPublisherURL=http://www.netxms.org
 AppSupportURL=http://www.netxms.org
index aa0556e..df7355b 100644 (file)
@@ -14,4 +14,4 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-SUBDIRS = winnt winperf wmi portCheck ping sms ups ecs logwatch ${SUBAGENT_DIRS}
+SUBDIRS = dbquery winnt winperf wmi portCheck ping sms ups ecs logwatch ${SUBAGENT_DIRS}
index a0a406b..b4d82bc 100644 (file)
@@ -1,11 +1,10 @@
-INCLUDES=-I@top_srcdir@/include
-
 SUBAGENT = dbquery
 
 pkglib_LTLIBRARIES = dbquery.la
-odbcquery_la_SOURCES = dbquery.cpp
-odbcquery_la_LDFLAGS = -module -avoid-version
-odbcquery_la_LIBADD = ../../../libnetxms/libnetxms.la ../../../db/libnxdb/libnxdb.la
+dbquery_la_SOURCES = conn.cpp dbquery.cpp direct.cpp poll.cpp
+dbquery_la_CPPFLAGS = -I@top_srcdir@/include
+dbquery_la_LDFLAGS = -module -avoid-version
+dbquery_la_LIBADD = ../../../libnetxms/libnetxms.la ../../../db/libnxdb/libnxdb.la
 
 EXTRA_DIST = dbquery.vcproj dbquery.h
 
index 7f21f07..8befaa3 100644 (file)
@@ -81,7 +81,19 @@ DBConnection *DBConnection::createFromConfig(const TCHAR *config)
    conn->m_server = ReadAttribute(config, _T("server"));
    conn->m_dbName = ReadAttribute(config, _T("dbname")); 
    conn->m_login = ReadAttribute(config, _T("login"));
-   conn->m_password = ReadAttribute(config, _T("password"));
+
+   TCHAR *password = ReadAttribute(config, _T("encryptedPassword"));
+   if (password != NULL)
+   {
+      TCHAR buffer[256];
+      DecryptPassword(CHECK_NULL_EX(conn->m_login), password, buffer);
+      free(password);
+      conn->m_password = _tcsdup(buffer);
+   }
+   else
+   {
+      conn->m_password = ReadAttribute(config, _T("password"));
+   }
 
    if ((conn->m_id == NULL) || (conn->m_driver == NULL))
    {
index 2007c0b..7bff250 100644 (file)
@@ -1,6 +1,6 @@
 /* 
 ** NetXMS - Network Management System
-** 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 Lesser General Public License as published
@@ -65,9 +65,7 @@ static BOOL SubAgentInit(Config *config)
 
    // Create shutdown condition and start poller threads
    g_condShutdown = ConditionCreate(TRUE);
-   //for(i = 0; i < (int)m_dwNumQueries; i++)
-   //   m_pQueryList[i].hThread = ThreadCreateEx(PollerThread, 0, &m_pQueryList[i]);
-
+   StartPollingThreads();  
    return TRUE;
 }
 
@@ -77,11 +75,12 @@ static BOOL SubAgentInit(Config *config)
 static void SubAgentShutdown()
 {
    ConditionSet(g_condShutdown);
+   StopPollingThreads();
    ShutdownConnections();
 }
 
 /**
- * Subagent information
+ * Parameters supported by agent
  */
 static NETXMS_SUBAGENT_PARAM m_parameters[] =
 {
@@ -91,11 +90,18 @@ static NETXMS_SUBAGENT_PARAM m_parameters[] =
    { _T("DB.QueryStatusText(*)"), H_PollResult, _T("T"), DCI_DT_STRING, _T("Database query status as text") }
 };
 
+/**
+ * Tables supported by agent
+ */
 static NETXMS_SUBAGENT_TABLE m_tables[] =
 {
-   { _T("DB.Query(*)"), H_DirectQueryTable, NULL, NULL, _T("Direct database query result") },
+   { _T("DB.Query(*)"), H_DirectQueryTable, NULL, _T(""), _T("Direct database query result") },
+   { _T("DB.QueryResult(*)"), H_PollResultTable, NULL, _T(""), _T("Database query result") }
 };
 
+/**
+ * Subagent information
+ */
 static NETXMS_SUBAGENT_INFO m_info =
 {
    NETXMS_SUBAGENT_INFO_MAGIC,
index b92bc8d..d36d3ef 100644 (file)
 #include <nms_agent.h>
 #include <nxdbapi.h>
 
+#define MAX_DBID_LEN       64
+#define MAX_QUERY_NAME_LEN 64
+
+/**
+ * Query status codes
+ */
+enum QueryStatusCode
+{
+   QUERY_STATUS_UNKNOWN = -1,
+   QUERY_STATUS_OK = 0,
+   QUERY_STATUS_ERROR = 1
+};
 
 /**
  * database connection
@@ -63,6 +75,7 @@ public:
 LONG H_DirectQuery(const TCHAR *param, const TCHAR *arg, TCHAR *value);
 LONG H_DirectQueryTable(const TCHAR *param, const TCHAR *arg, Table *value);
 LONG H_PollResult(const TCHAR *param, const TCHAR *arg, TCHAR *value);
+LONG H_PollResultTable(const TCHAR *param, const TCHAR *arg, Table *value);
 
 /**
  * Functions
@@ -71,5 +84,13 @@ bool AddDatabaseFromConfig(const TCHAR *db);
 bool AddQueryFromConfig(const TCHAR *query);
 void ShutdownConnections();
 DB_HANDLE GetConnectionHandle(const TCHAR *dbid);
+void StartPollingThreads();
+void StopPollingThreads();
+void DBResultToTable(DB_RESULT hResult, Table *table);
+
+/**
+ * Shutdown condition
+ */
+extern CONDITION g_condShutdown;
 
 #endif
index 7f6d192..9c198e1 100644 (file)
 #include "dbquery.h"
 
 /**
+ * Convert DB_RESULT to table object
+ */
+void DBResultToTable(DB_RESULT hResult, Table *table)
+{
+   int numColumns = DBGetColumnCount(hResult);
+   for(int c = 0; c < numColumns; c++)
+   {
+      TCHAR name[64];
+      if (!DBGetColumnName(hResult, c, name, 64))
+         _sntprintf(name, 64, _T("COL_%d"), c + 1);
+      table->addColumn(name);
+   }
+
+   int numRows = DBGetNumRows(hResult);
+   for(int r = 0; r < numRows; r++)
+   {
+      table->addRow();
+      for(int c = 0; c < numColumns; c++)
+      {
+         table->setPreallocated(c, DBGetField(hResult, r, c, NULL, 0));
+      }
+   }
+}
+
+/**
  * Direct query - single value
  */
 LONG H_DirectQuery(const TCHAR *param, const TCHAR *arg, TCHAR *value)
 {
-   TCHAR dbid[64], query[256];
-   AgentGetParameterArg(param, 1, dbid, 64);
-   AgentGetParameterArg(param, 2, query, 64);
+   TCHAR dbid[MAX_DBID_LEN], query[256];
+   AgentGetParameterArg(param, 1, dbid, MAX_DBID_LEN);
+   AgentGetParameterArg(param, 2, query, 256);
 
    DB_HANDLE hdb = GetConnectionHandle(dbid);
    if (hdb == NULL)
@@ -55,9 +80,9 @@ LONG H_DirectQuery(const TCHAR *param, const TCHAR *arg, TCHAR *value)
  */
 LONG H_DirectQueryTable(const TCHAR *param, const TCHAR *arg, Table *value)
 {
-   TCHAR dbid[64], query[256];
-   AgentGetParameterArg(param, 1, dbid, 64);
-   AgentGetParameterArg(param, 2, query, 64);
+   TCHAR dbid[MAX_DBID_LEN], query[256];
+   AgentGetParameterArg(param, 1, dbid, MAX_DBID_LEN);
+   AgentGetParameterArg(param, 2, query, 256);
 
    DB_HANDLE hdb = GetConnectionHandle(dbid);
    if (hdb == NULL)
@@ -70,25 +95,7 @@ LONG H_DirectQueryTable(const TCHAR *param, const TCHAR *arg, Table *value)
    DB_RESULT hResult = DBSelect(hdb, query);
    if (hResult != NULL)
    {
-      int numColumns = DBGetColumnCount(hResult);
-      for(int c = 0; c < numColumns; c++)
-      {
-         TCHAR name[64];
-         if (!DBGetColumnName(hResult, c, name, 64))
-            _sntprintf(name, 64, _T("COL_%d"), c + 1);
-         value->addColumn(name);
-      }
-
-      int numRows = DBGetNumRows(hResult);
-      for(int r = 0; r < numRows; r++)
-      {
-         value->addRow();
-         for(int c = 0; c < numColumns; c++)
-         {
-            value->setPreallocated(c, DBGetField(hResult, r, c, NULL, 0));
-         }
-      }
-
+      DBResultToTable(hResult, value);
       DBFreeResult(hResult);
       rc = SYSINFO_RC_SUCCESS;
    }
index 745c4a9..b36ae8b 100644 (file)
 #include "dbquery.h"
 
 /**
+ * Query definition
+ */
+class Query
+{
+private:
+   MUTEX m_mutex;
+   THREAD m_pollingThread;
+   TCHAR *m_name;
+   TCHAR *m_dbid;
+   TCHAR *m_query;
+   int m_interval;
+   time_t m_lastPoll;
+   int m_status;
+   TCHAR m_statusText[MAX_RESULT_LENGTH];
+   DB_RESULT m_result;
+
+   Query();
+
+   void setError(const TCHAR *msg);
+
+public:
+   static Query *createFromConfig(const TCHAR *src);
+
+   ~Query();
+
+   void lock() { MutexLock(m_mutex); }
+   void unlock() { MutexUnlock(m_mutex); }
+
+   time_t getNextPoll() { return m_lastPoll + m_interval; }
+   void poll();
+   void joinPollingThread() { ThreadJoin(m_pollingThread); }
+
+   LONG getResult(TCHAR *buffer);
+   LONG fillResultTable(Table *table);
+
+   const TCHAR *getName() { return m_name; }
+   int getStatus() { return m_status; }
+   const TCHAR *getStatusText() { return m_statusText; }
+};
+
+/**
+ * Query object constructor
+ */
+Query::Query()
+{
+   m_name = NULL;
+   m_dbid = NULL;
+   m_query = NULL;
+   m_lastPoll = 0;
+   m_status = QUERY_STATUS_UNKNOWN;
+   _tcscpy(m_statusText, _T("UNKNOWN"));
+   m_result = NULL;
+   m_pollingThread = INVALID_THREAD_HANDLE;
+   m_mutex = MutexCreate();
+}
+
+/**
+ * Query object destructor
+ */
+Query::~Query()
+{
+   safe_free(m_name);
+   safe_free(m_dbid);
+   safe_free(m_query);
+   if (m_result != NULL)
+      DBFreeResult(m_result);
+   MutexDestroy(m_mutex);
+}
+
+/**
+ * Get result from cell 0,0
+ */
+LONG Query::getResult(TCHAR *buffer)
+{
+   if (m_result == NULL)
+      return SYSINFO_RC_ERROR;
+   if (DBGetNumRows(m_result) == 0)
+      return SYSINFO_RC_ERROR;
+   DBGetField(m_result, 0, 0, buffer, MAX_RESULT_LENGTH);
+   return SYSINFO_RC_SUCCESS;
+}
+
+/**
+ * Fill result table
+ */
+LONG Query::fillResultTable(Table *table)
+{
+   if (m_result == NULL)
+      return SYSINFO_RC_ERROR;
+   DBResultToTable(m_result, table);
+   return SYSINFO_RC_SUCCESS;
+}
+
+/**
+ * Set error status
+ */
+void Query::setError(const TCHAR *msg)
+{
+   lock();
+   m_status = QUERY_STATUS_ERROR;
+   nx_strncpy(m_statusText, msg, MAX_RESULT_LENGTH);
+   if (m_result != NULL)
+   {
+      DBFreeResult(m_result);
+      m_result = NULL;
+   }
+   unlock();
+}
+
+/**
+ * Poll
+ */
+void Query::poll()
+{
+   m_lastPoll = time(NULL);
+
+   DB_HANDLE hdb = GetConnectionHandle(m_dbid);
+   if (hdb == NULL)
+   {
+      AgentWriteDebugLog(4, _T("DBQUERY: Query::poll(%s): no connection handle for database %s"), m_name, m_dbid);
+      setError(_T("DB connection not available"));
+      return;
+   }
+
+   TCHAR errorText[DBDRV_MAX_ERROR_TEXT];
+   DB_RESULT hResult = DBSelectEx(hdb, m_query, errorText);
+   if (hResult == NULL)
+   {
+      AgentWriteDebugLog(4, _T("DBQUERY: Query::poll(%s): query failed (%s)"), m_name, errorText);
+      setError(errorText);
+      return;
+   }
+
+   lock();
+   m_status = QUERY_STATUS_OK;
+   _tcscpy(m_statusText, _T("OK"));
+   if (m_result != NULL)
+      DBFreeResult(m_result);
+   m_result = hResult;
+   unlock();
+}
+
+/**
+ * Create new query object from config
+ * Format is following:
+ *    name:dbid:interval:query
+ */
+Query *Query::createFromConfig(const TCHAR *src)
+{
+   TCHAR *config = _tcsdup(src);
+   TCHAR *curr = config;
+   Query *query = new Query;
+
+   // Name
+   TCHAR *s = _tcschr(config, _T(':'));
+   if (s == NULL)
+      goto fail;
+   *s = 0;
+   query->m_name = _tcsdup(config);
+   curr = s + 1;
+
+   // DB ID
+   s = _tcschr(curr, _T(':'));
+   if (s == NULL)
+      goto fail;
+   *s = 0;
+   query->m_dbid = _tcsdup(curr);
+   curr = s + 1;
+
+   // interval
+   s = _tcschr(curr, _T(':'));
+   if (s == NULL)
+      goto fail;
+   *s = 0;
+   query->m_interval = _tcstol(curr, NULL, 0);
+   if ((query->m_interval < 1) || (query->m_interval > 86400))
+   {
+      AgentWriteDebugLog(1, _T("DBQuery: invalid interval %s for query %s"), curr, query->m_name);
+      goto fail;
+   }
+   curr = s + 1;
+
+   // Rest is SQL query
+   query->m_query = _tcsdup(curr);
+   free(config);
+   return query;
+
+fail:
+   free(config);
+   delete query;
+   return NULL;
+}
+
+/**
+ * Queries
+ */
+static ObjectArray<Query> s_queries;
+
+/**
+ * Acquire query object. Caller must call Query::unlock() to release query object.
+ */
+static Query *AcquireQueryObject(const TCHAR *name)
+{
+   // It is safe to scan query list without locks because
+   // list itself and query names not changing after subagent initialization
+   for(int i = 0; i < s_queries.size(); i++)
+   {
+      Query *q = s_queries.get(i);
+      if (!_tcsicmp(q->getName(), name))
+      {
+         q->lock();
+         return q;
+      }
+   }
+   return NULL;
+}
+
+/**
+ * Polling thread
+ */
+static THREAD_RESULT THREAD_CALL PollingThread(void *arg)
+{
+   Query *query = (Query *)arg;
+   AgentWriteDebugLog(3, _T("DBQuery: Polling thread for query %s started"), query->getName());
+
+   int sleepTime = (int)(query->getNextPoll() - time(NULL));
+   if (sleepTime <= 0)
+      sleepTime = 1;
+   while(!ConditionWait(g_condShutdown, sleepTime * 1000))
+   {
+      query->poll();
+      sleepTime = (int)(query->getNextPoll() - time(NULL));
+      if (sleepTime <= 0)
+         sleepTime = 1;
+   }
+
+   AgentWriteDebugLog(3, _T("DBQuery: Polling thread for query %s stopped"), query->getName());
+   return THREAD_OK;
+}
+
+/**
+ * Start polling threads
+ */
+void StartPollingThreads()
+{
+   for(int i = 0; i < s_queries.size(); i++)
+      ThreadCreate(PollingThread, 0, s_queries.get(i));
+}
+
+/**
+ * Stop polling threads
+ */
+void StopPollingThreads()
+{
+   for(int i = 0; i < s_queries.size(); i++)
+      s_queries.get(i)->joinPollingThread();
+}
+
+/**
  * Add query to the list from config
+ * Format is following:
+ *    name:dbid:interval:query
  */
-bool AddQueryFromConfig(const TCHAR *query)
+bool AddQueryFromConfig(const TCHAR *config)
 {
+   Query *query = Query::createFromConfig(config);
+   if (query != NULL)
+   {
+      s_queries.add(query);
+      AgentWriteDebugLog(1, _T("DBQuery: query %s added for polling"), query->getName());
+      return true;
+   }
    return false;
 }
 
@@ -35,5 +303,44 @@ bool AddQueryFromConfig(const TCHAR *query)
  */
 LONG H_PollResult(const TCHAR *param, const TCHAR *arg, TCHAR *value)
 {
-   return SYSINFO_RC_ERROR;
+   TCHAR name[MAX_QUERY_NAME_LEN];
+   AgentGetParameterArg(param, 1, name, MAX_QUERY_NAME_LEN);
+   Query *query = AcquireQueryObject(name);
+   if (query == NULL)
+      return SYSINFO_RC_UNSUPPORTED;
+
+   LONG rc = SYSINFO_RC_ERROR;
+   switch(*arg)
+   {
+      case _T('R'):  // Result
+         rc = query->getResult(value);
+         break;
+      case _T('S'):  // Result
+         ret_int(value, query->getStatus());
+         rc = SYSINFO_RC_SUCCESS;
+         break;
+      case _T('T'):  // Result
+         ret_string(value, query->getStatusText());
+         rc = SYSINFO_RC_SUCCESS;
+         break;
+   }
+
+   query->unlock();
+   return rc;
+}
+
+/**
+ * Get poll results - table
+ */
+LONG H_PollResultTable(const TCHAR *param, const TCHAR *arg, Table *value)
+{
+   TCHAR name[MAX_QUERY_NAME_LEN];
+   AgentGetParameterArg(param, 1, name, MAX_QUERY_NAME_LEN);
+   Query *query = AcquireQueryObject(name);
+   if (query == NULL)
+      return SYSINFO_RC_UNSUPPORTED;
+
+   LONG rc = query->fillResultTable(value);
+   query->unlock();
+   return rc;
 }
index a12af4d..3d59036 100644 (file)
@@ -67,6 +67,9 @@ LONG H_NetIpForwarding(const TCHAR *pszParam, const TCHAR *pArg, TCHAR *pValue)
    return nRet;
 }
 
+/**
+ * Handler for Net.ArpCache list
+ */
 LONG H_NetArpCache(const TCHAR *pszParam, const TCHAR *pArg, StringList *pValue)
 {
    int nRet = SYSINFO_RC_ERROR;
@@ -76,67 +79,63 @@ LONG H_NetArpCache(const TCHAR *pszParam, const TCHAR *pArg, StringList *pValue)
    if (hFile != NULL)
    {
       char szBuff[256];
-      int nFd;
-
-      nFd = socket(AF_INET, SOCK_DGRAM, 0);
-      if (nFd > 0)
+      if (fgets(szBuff, sizeof(szBuff), hFile) != NULL) // skip first line
       {
-         nRet = SYSINFO_RC_SUCCESS;
-
-         char *__unused = fgets(szBuff, sizeof(szBuff), hFile); // skip first line
-
-         while(fgets(szBuff, sizeof(szBuff), hFile) != NULL)
+         int nFd = socket(AF_INET, SOCK_DGRAM, 0);
+         if (nFd > 0)
          {
-            int nIP1, nIP2, nIP3, nIP4;
-            int nMAC1, nMAC2, nMAC3, nMAC4, nMAC5, nMAC6;
-            char szTmp1[256];
-            char szTmp2[256];
-            char szTmp3[256];
-            char szIf[256];
-
-            if (sscanf(szBuff,
-               "%d.%d.%d.%d %s %s %02X:%02X:%02X:%02X:%02X:%02X %s %s",
-               &nIP1, &nIP2, &nIP3, &nIP4,
-               szTmp1, szTmp2,
-               &nMAC1, &nMAC2, &nMAC3, &nMAC4, &nMAC5, &nMAC6,
-               szTmp3, szIf) == 14)
-            {
-               int nIndex;
-               struct ifreq irq;
-
-               if (nMAC1 == 0 && nMAC2 == 0 &&
-                  nMAC3 == 0 && nMAC4 == 0 &&
-                  nMAC5 == 0 && nMAC6 == 0)
-               {
-                  // incomplete
-                  continue;
-               }
+            nRet = SYSINFO_RC_SUCCESS;
 
-               strncpy(irq.ifr_name, szIf, IFNAMSIZ);
-               if (ioctl(nFd, SIOCGIFINDEX, &irq) != 0)
-               {
-                  perror("ioctl()");
-                  nIndex = 0;
-               }
-               else
+            while(fgets(szBuff, sizeof(szBuff), hFile) != NULL)
+            {
+               int nIP1, nIP2, nIP3, nIP4;
+               int nMAC1, nMAC2, nMAC3, nMAC4, nMAC5, nMAC6;
+               char szTmp1[256];
+               char szTmp2[256];
+               char szTmp3[256];
+               char szIf[256];
+
+               if (sscanf(szBuff,
+                          "%d.%d.%d.%d %s %s %02X:%02X:%02X:%02X:%02X:%02X %s %s",
+                          &nIP1, &nIP2, &nIP3, &nIP4,
+                          szTmp1, szTmp2,
+                          &nMAC1, &nMAC2, &nMAC3, &nMAC4, &nMAC5, &nMAC6,
+                          szTmp3, szIf) == 14)
                {
-                  nIndex = irq.ifr_ifindex;
+                  int nIndex;
+                  struct ifreq irq;
+
+                  if (nMAC1 == 0 && nMAC2 == 0 &&
+                      nMAC3 == 0 && nMAC4 == 0 &&
+                      nMAC5 == 0 && nMAC6 == 0)
+                  {
+                     // incomplete
+                     continue;
+                  }
+
+                  strncpy(irq.ifr_name, szIf, IFNAMSIZ);
+                  if (ioctl(nFd, SIOCGIFINDEX, &irq) != 0)
+                  {
+                     nIndex = 0;
+                  }
+                  else
+                  {
+                     nIndex = irq.ifr_ifindex;
+                  }
+
+                  TCHAR output[256];
+                  _sntprintf(output, 256,
+                     _T("%02X%02X%02X%02X%02X%02X %d.%d.%d.%d %d"),
+                     nMAC1, nMAC2, nMAC3, nMAC4, nMAC5, nMAC6,
+                     nIP1, nIP2, nIP3, nIP4,
+                     nIndex);
+
+                  pValue->add(output);
                }
-
-               TCHAR output[256];
-               _sntprintf(output, 256,
-                  _T("%02X%02X%02X%02X%02X%02X %d.%d.%d.%d %d"),
-                  nMAC1, nMAC2, nMAC3, nMAC4, nMAC5, nMAC6,
-                  nIP1, nIP2, nIP3, nIP4,
-                  nIndex);
-
-               pValue->add(output);
             }
+            close(nFd);
          }
-
-         close(nFd);
       }
-
       fclose(hFile);
    }
 
@@ -248,7 +247,6 @@ static int SendMessage(int socket)
 static int ReceiveMessage(int socket, char* replyBuffer)
 {
    iovec io;
-   iovec io_reply = {};
    msghdr reply = {};
    sockaddr_nl kernel;
 
@@ -321,7 +319,6 @@ static IFINFO *GetInterfaceInfo(int socket)
       return NULL;
    }
 
-   msghdr reply = {};
    nlmsghdr* msg_ptr;
    int msgLen;
    int done = 0;
index 977f951..21e510e 100644 (file)
@@ -115,7 +115,6 @@ int ProcRead(PROC_ENT **pEnt, char *szProcName, char *szCmdLine)
                        char szFileName[512];
                        FILE *hFile;
                        char szProcStat[1024] = {0}; 
-                       char szBuff[1024] = {0}; 
                        char *pProcName = NULL, *pProcStat = NULL;
                        unsigned long nPid;
 
@@ -166,18 +165,13 @@ int ProcRead(PROC_ENT **pEnt, char *szProcName, char *szCmdLine)
                                        memset(processCmdLine, 0, sizeof(processCmdLine));
 
                                        int len = fread(processCmdLine, 1, sizeof(processCmdLine) - 1, hFile);
-                                       if (len > 0) // got a valid record in format: argv[0]\x00argv[1]\x00...
+                                       if (len > 0)
                                        {
-                                               int j;
-                                               //char *pArgs;
-
-                                               /* Commented out by victor: to behave identicaly on different platforms,
-                                                  argv[0] should be matched as well
-                                               j = strlen(szBuff) + 1;
-                                               pArgs = szBuff + j; // skip first (argv[0])
-                                               len -= j;*/
+                                               // got a valid record in format: argv[0]\x00argv[1]\x00...
+                                               // Note: to behave identicaly on different platforms,
+                                               // full command line including argv[0] should be matched
                                                // replace 0x00 with spaces
-                                               for(j = 0; j < len - 1; j++)
+                                               for(int j = 0; j < len - 1; j++)
                                                {
                                                        if (processCmdLine[j] == 0)
                                                        {
index 43bb8d6..8f9f153 100644 (file)
@@ -161,12 +161,8 @@ LONG H_CpuLoad(const TCHAR *pszParam, const TCHAR *pArg, TCHAR *pValue)
 {
        int nRet = SYSINFO_RC_ERROR;
        struct statvfs s;
-       char szArg[128] = {0};
        FILE *hFile;
 
-       // get processor
-       //AgentGetParameterArg(pszParam, 1, szArg, sizeof(szArg));
-
        hFile = fopen("/proc/loadavg", "r");
        if (hFile != NULL)
        {
index 2b7cb87..fcf6a56 100644 (file)
@@ -156,9 +156,9 @@ int CheckHTTP(char *szAddr, UINT32 dwAddr, short nPort, char *szURI,
             {
                SaveResponse(szAddr, dwAddr, buff);
             }
-
-                               safe_free(buff);
                        }
+
+         safe_free(buff);
                }
                NetClose(nSd);
        }
index 9e24b11..561e6bb 100644 (file)
@@ -1,24 +1,24 @@
 /*
- ** NetXMS subagent for SunOS/Solaris
- ** Copyright (C) 2004-2013 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
- ** 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: cpu.cpp
- **
- **/
+** NetXMS subagent for SunOS/Solaris
+** Copyright (C) 2004-2013 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
+** 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: cpu.cpp
+**
+**/
 
 #include "sunos_subagent.h"
 #include <sys/sysinfo.h>
@@ -48,27 +48,27 @@ static DWORD m_dwUsage15[MAX_CPU_COUNT + 1];
 
 static void ReadCPUTimes(kstat_ctl_t *kc, uint_t *pValues)
 {
-       kstat_t *kp;
-       int i;
-       uint_t *pData;
-
-       kstat_lock();
-       for(i = 0, pData = pValues; i < m_nCPUCount; i++, pData += CPU_STATES)
-       {
-               kp = kstat_lookup(kc, (char *)"cpu_stat", m_nInstanceMap[i], NULL);
-               if (kp != NULL)
-               {
-                       if (kstat_read(kc, kp, NULL) != -1)
-                       {
-                               memcpy(pData, ((cpu_stat_t *)kp->ks_data)->cpu_sysinfo.cpu, sizeof(uint_t) * CPU_STATES);
-                       }
-                       else 
-                       {
-                               AgentWriteDebugLog(6, _T("SunOS: kstat_read failed in ReadCPUTimes"));
-                       }
-               }
-       }
-       kstat_unlock();
+   kstat_t *kp;
+   int i;
+   uint_t *pData;
+
+   kstat_lock();
+   for(i = 0, pData = pValues; i < m_nCPUCount; i++, pData += CPU_STATES)
+   {
+      kp = kstat_lookup(kc, (char *)"cpu_stat", m_nInstanceMap[i], NULL);
+      if (kp != NULL)
+      {
+         if (kstat_read(kc, kp, NULL) != -1)
+         {
+            memcpy(pData, ((cpu_stat_t *)kp->ks_data)->cpu_sysinfo.cpu, sizeof(uint_t) * CPU_STATES);
+         }
+         else
+         {
+            AgentWriteDebugLog(6, _T("SunOS: kstat_read failed in ReadCPUTimes"));
+         }
+      }
+   }
+   kstat_unlock();
 }
 
 /**
@@ -76,150 +76,150 @@ static void ReadCPUTimes(kstat_ctl_t *kc, uint_t *pValues)
  */
 THREAD_RESULT THREAD_CALL CPUStatCollector(void *arg)
 {
-       kstat_ctl_t *kc;
-       kstat_t *kp;
-       kstat_named_t *kn;
-       int i, j, iIdleTime, iLimit;
-       DWORD *pdwHistory, dwHistoryPos, dwCurrPos, dwIndex;
-       DWORD dwSum[MAX_CPU_COUNT + 1];
-       uint_t *pnLastTimes, *pnCurrTimes, *pnTemp;
-       uint_t nSum, nSysSum, nSysCurrIdle, nSysLastIdle;
-
-       // Open kstat
-       kstat_lock();
-       kc = kstat_open();
-       if (kc == NULL)
-       {
-               kstat_unlock();
-               AgentWriteLog(EVENTLOG_ERROR_TYPE,
-                               _T("SunOS: Unable to open kstat() context (%s), CPU statistics will not be collected"), 
-                               _tcserror(errno));
-               return THREAD_OK;
-       }
-
-       // Read number of CPUs
-       kp = kstat_lookup(kc, (char *)"unix", 0, (char *)"system_misc");
-       if (kp != NULL)
-       {
-               if(kstat_read(kc, kp, 0) != -1)
-               {
-                       kn = (kstat_named_t *)kstat_data_lookup(kp, (char *)"ncpus");
-                       if (kn != NULL)
-                       {
-                               m_nCPUCount = kn->value.ui32;
-                       }
-               }
-       }
-
-       // Read CPU instance numbers
-       memset(m_nInstanceMap, 0xFF, sizeof(int) * MAX_CPU_COUNT);
-       for(i = 0, j = 0; i < m_nCPUCount; i++)
-       {
-               while(kstat_lookup(kc, (char *)"cpu_stat", j, NULL) == NULL)
-                       j++;
-               m_nInstanceMap[i] = j++;
-       }
-
-       kstat_unlock();
-
-       // Initialize data
-       memset(m_dwUsage, 0, sizeof(DWORD) * (MAX_CPU_COUNT + 1));
-       memset(m_dwUsage5, 0, sizeof(DWORD) * (MAX_CPU_COUNT + 1));
-       memset(m_dwUsage15, 0, sizeof(DWORD) * (MAX_CPU_COUNT + 1));
-       pdwHistory = (DWORD *)malloc(sizeof(DWORD) * (m_nCPUCount + 1) * 900);
-       memset(pdwHistory, 0, sizeof(DWORD) * (m_nCPUCount + 1) * 900);
-       pnLastTimes = (uint_t *)malloc(sizeof(uint_t) * m_nCPUCount * CPU_STATES);
-       pnCurrTimes = (uint_t *)malloc(sizeof(uint_t) * m_nCPUCount * CPU_STATES);
-       dwHistoryPos = 0;
-       AgentWriteDebugLog(1, _T("CPU stat collector thread started"));
-
-       // Do first read
-       ReadCPUTimes(kc, pnLastTimes);
-       ThreadSleepMs(1000);
-
-       // Collection loop
-       while(!g_bShutdown)
-       {
-               ReadCPUTimes(kc, pnCurrTimes);
-
-               // Calculate utilization for last second for each CPU
-               dwIndex = dwHistoryPos * (m_nCPUCount + 1);
-               for(i = 0, j = 0, nSysSum = 0, nSysCurrIdle = 0, nSysLastIdle = 0;
-                               i < m_nCPUCount; i++)
-               {
-                       iIdleTime = j + CPU_IDLE;
-                       iLimit = j + CPU_STATES;
-                       for(nSum = 0; j < iLimit; j++)
-                               nSum += pnCurrTimes[j] - pnLastTimes[j];
-                       nSysSum += nSum;
-                       nSysCurrIdle += pnCurrTimes[iIdleTime];
-                       nSysLastIdle += pnLastTimes[iIdleTime];
-                       pdwHistory[dwIndex++] = 
-                               1000 - ((pnCurrTimes[iIdleTime] - pnLastTimes[iIdleTime]) * 1000 / nSum);
-               }
-
-               // Average utilization for last second for all CPUs
-               pdwHistory[dwIndex] = 
-                       1000 - ((nSysCurrIdle - nSysLastIdle) * 1000 / nSysSum);
-
-               // Copy current times to last
-               pnTemp = pnLastTimes;
-               pnLastTimes = pnCurrTimes;
-               pnCurrTimes = pnTemp;
-
-               // Calculate averages
-               memset(dwSum, 0, sizeof(dwSum));
-               for(i = 0, dwCurrPos = dwHistoryPos; i < 900; i++)
-               {
-                       dwIndex = dwCurrPos * (m_nCPUCount + 1);
-                       for(j = 0; j < m_nCPUCount; j++, dwIndex++)
-                               dwSum[j] += pdwHistory[dwIndex];
-                       dwSum[MAX_CPU_COUNT] += pdwHistory[dwIndex];
-
-                       switch(i)
-                       {
-                               case 59:
-                                       for(j = 0; j < m_nCPUCount; j++)
-                                               m_dwUsage[j] = dwSum[j] / 60;
-                                       m_dwUsage[MAX_CPU_COUNT] = dwSum[MAX_CPU_COUNT] / 60;
-                                       break;
-                               case 299:
-                                       for(j = 0; j < m_nCPUCount; j++)
-                                               m_dwUsage5[j] = dwSum[j] / 300;
-                                       m_dwUsage5[MAX_CPU_COUNT] = dwSum[MAX_CPU_COUNT] / 300;
-                                       break;
-                               case 899:
-                                       for(j = 0; j < m_nCPUCount; j++)
-                                               m_dwUsage15[j] = dwSum[j] / 900;
-                                       m_dwUsage15[MAX_CPU_COUNT] = dwSum[MAX_CPU_COUNT] / 900;
-                                       break;
-                               default:
-                                       break;
-                       }
-
-                       if (dwCurrPos > 0)
-                               dwCurrPos--;
-                       else
-                               dwCurrPos = 899;
-               }
-
-               // Increment history buffer position
-               dwHistoryPos++;
-               if (dwHistoryPos == 900)
-                       dwHistoryPos = 0;
-
-               ThreadSleepMs(1000);
-       }
-
-       // Cleanup
-       free(pnLastTimes);
-       free(pnCurrTimes);
-       free(pdwHistory);
-       kstat_lock();
-       kstat_close(kc);
-       kstat_unlock();
-       AgentWriteDebugLog(1, _T("CPU stat collector thread stopped"));
-       return THREAD_OK;
+   kstat_ctl_t *kc;
+   kstat_t *kp;
+   kstat_named_t *kn;
+   int i, j, iIdleTime, iLimit;
+   DWORD *pdwHistory, dwHistoryPos, dwCurrPos, dwIndex;
+   DWORD dwSum[MAX_CPU_COUNT + 1];
+   uint_t *pnLastTimes, *pnCurrTimes, *pnTemp;
+   uint_t nSum, nSysSum, nSysCurrIdle, nSysLastIdle;
+
+   // Open kstat
+   kstat_lock();
+   kc = kstat_open();
+   if (kc == NULL)
+   {
+      kstat_unlock();
+      AgentWriteLog(EVENTLOG_ERROR_TYPE,
+            _T("SunOS: Unable to open kstat() context (%s), CPU statistics will not be collected"), 
+            _tcserror(errno));
+      return THREAD_OK;
+   }
+
+   // Read number of CPUs
+   kp = kstat_lookup(kc, (char *)"unix", 0, (char *)"system_misc");
+   if (kp != NULL)
+   {
+      if(kstat_read(kc, kp, 0) != -1)
+      {
+         kn = (kstat_named_t *)kstat_data_lookup(kp, (char *)"ncpus");
+         if (kn != NULL)
+         {
+            m_nCPUCount = kn->value.ui32;
+         }
+      }
+   }
+
+   // Read CPU instance numbers
+   memset(m_nInstanceMap, 0xFF, sizeof(int) * MAX_CPU_COUNT);
+   for(i = 0, j = 0; i < m_nCPUCount; i++)
+   {
+      while(kstat_lookup(kc, (char *)"cpu_stat", j, NULL) == NULL)
+         j++;
+      m_nInstanceMap[i] = j++;
+   }
+
+   kstat_unlock();
+
+   // Initialize data
+   memset(m_dwUsage, 0, sizeof(DWORD) * (MAX_CPU_COUNT + 1));
+   memset(m_dwUsage5, 0, sizeof(DWORD) * (MAX_CPU_COUNT + 1));
+   memset(m_dwUsage15, 0, sizeof(DWORD) * (MAX_CPU_COUNT + 1));
+   pdwHistory = (DWORD *)malloc(sizeof(DWORD) * (m_nCPUCount + 1) * 900);
+   memset(pdwHistory, 0, sizeof(DWORD) * (m_nCPUCount + 1) * 900);
+   pnLastTimes = (uint_t *)malloc(sizeof(uint_t) * m_nCPUCount * CPU_STATES);
+   pnCurrTimes = (uint_t *)malloc(sizeof(uint_t) * m_nCPUCount * CPU_STATES);
+   dwHistoryPos = 0;
+   AgentWriteDebugLog(1, _T("CPU stat collector thread started"));
+
+   // Do first read
+   ReadCPUTimes(kc, pnLastTimes);
+   ThreadSleepMs(1000);
+
+   // Collection loop
+   while(!g_bShutdown)
+   {
+      ReadCPUTimes(kc, pnCurrTimes);
+
+      // Calculate utilization for last second for each CPU
+      dwIndex = dwHistoryPos * (m_nCPUCount + 1);
+      for(i = 0, j = 0, nSysSum = 0, nSysCurrIdle = 0, nSysLastIdle = 0;
+            i < m_nCPUCount; i++)
+      {
+         iIdleTime = j + CPU_IDLE;
+         iLimit = j + CPU_STATES;
+         for(nSum = 0; j < iLimit; j++)
+            nSum += pnCurrTimes[j] - pnLastTimes[j];
+         nSysSum += nSum;
+         nSysCurrIdle += pnCurrTimes[iIdleTime];
+         nSysLastIdle += pnLastTimes[iIdleTime];
+         pdwHistory[dwIndex++] = 
+            1000 - ((pnCurrTimes[iIdleTime] - pnLastTimes[iIdleTime]) * 1000 / nSum);
+      }
+
+      // Average utilization for last second for all CPUs
+      pdwHistory[dwIndex] = 
+         1000 - ((nSysCurrIdle - nSysLastIdle) * 1000 / nSysSum);
+
+      // Copy current times to last
+      pnTemp = pnLastTimes;
+      pnLastTimes = pnCurrTimes;
+      pnCurrTimes = pnTemp;
+
+      // Calculate averages
+      memset(dwSum, 0, sizeof(dwSum));
+      for(i = 0, dwCurrPos = dwHistoryPos; i < 900; i++)
+      {
+         dwIndex = dwCurrPos * (m_nCPUCount + 1);
+         for(j = 0; j < m_nCPUCount; j++, dwIndex++)
+            dwSum[j] += pdwHistory[dwIndex];
+         dwSum[MAX_CPU_COUNT] += pdwHistory[dwIndex];
+
+         switch(i)
+         {
+            case 59:
+               for(j = 0; j < m_nCPUCount; j++)
+                  m_dwUsage[j] = dwSum[j] / 60;
+               m_dwUsage[MAX_CPU_COUNT] = dwSum[MAX_CPU_COUNT] / 60;
+               break;
+            case 299:
+               for(j = 0; j < m_nCPUCount; j++)
+                  m_dwUsage5[j] = dwSum[j] / 300;
+               m_dwUsage5[MAX_CPU_COUNT] = dwSum[MAX_CPU_COUNT] / 300;
+               break;
+            case 899:
+               for(j = 0; j < m_nCPUCount; j++)
+                  m_dwUsage15[j] = dwSum[j] / 900;
+               m_dwUsage15[MAX_CPU_COUNT] = dwSum[MAX_CPU_COUNT] / 900;
+               break;
+            default:
+               break;
+         }
+
+         if (dwCurrPos > 0)
+            dwCurrPos--;
+         else
+            dwCurrPos = 899;
+      }
+
+      // Increment history buffer position
+      dwHistoryPos++;
+      if (dwHistoryPos == 900)
+         dwHistoryPos = 0;
+
+      ThreadSleepMs(1000);
+   }
+
+   // Cleanup
+   free(pnLastTimes);
+   free(pnCurrTimes);
+   free(pdwHistory);
+   kstat_lock();
+   kstat_close(kc);
+   kstat_unlock();
+   AgentWriteDebugLog(1, _T("CPU stat collector thread stopped"));
+   return THREAD_OK;
 }
 
 /**
@@ -227,75 +227,75 @@ THREAD_RESULT THREAD_CALL CPUStatCollector(void *arg)
  */
 LONG H_CPUUsage(const TCHAR *pszParam, const TCHAR *pArg, TCHAR *pValue)
 {
-       LONG nRet = SYSINFO_RC_SUCCESS;
-
-       if (pArg[0] == 'T')
-       {
-               switch(pArg[1])
-               {
-                       case '0':
-                               _sntprintf(pValue, MAX_RESULT_LENGTH, _T("%d.%d00000"),
-                                               m_dwUsage[MAX_CPU_COUNT] / 10,
-                                               m_dwUsage[MAX_CPU_COUNT] % 10);
-                               break;
-                       case '1':
-                               _sntprintf(pValue, MAX_RESULT_LENGTH, _T("%d.%d00000"),
-                                               m_dwUsage5[MAX_CPU_COUNT] / 10,
-                                               m_dwUsage5[MAX_CPU_COUNT] % 10);
-                               break;
-                       case '2':
-                               _sntprintf(pValue, MAX_RESULT_LENGTH, _T("%d.%d00000"),
-                                               m_dwUsage15[MAX_CPU_COUNT] / 10,
-                                               m_dwUsage15[MAX_CPU_COUNT] % 10);
-                               break;
-                       default:
-                               nRet = SYSINFO_RC_UNSUPPORTED;
-                               break;
-               }
-       }
-       else
-       {
-               LONG nCPU = -1, nInstance;
-               TCHAR *eptr, szBuffer[32] = _T("error");
-
-               // Get CPU number
-               AgentGetParameterArg(pszParam, 1, szBuffer, 32);
-               nInstance = _tcstol(szBuffer, &eptr, 0);
-               if (nInstance != -1)
-               {
-                       for(nCPU = 0; nCPU < MAX_CPU_COUNT; nCPU++)
-                               if (m_nInstanceMap[nCPU] == nInstance)
-                                       break;
-               }
-               if ((*eptr == 0) && (nCPU >= 0) && (nCPU < m_nCPUCount))
-               {
-                       switch(pArg[1])
-                       {
-                               case '0':
-                                       _sntprintf(pValue, MAX_RESULT_LENGTH, _T("%d.%d00000"),
-                                                       m_dwUsage[nCPU] / 10,
-                                                       m_dwUsage[nCPU] % 10);
-                                       break;
-                               case '1':
-                                       _sntprintf(pValue, MAX_RESULT_LENGTH, _T("%d.%d00000"),
-                                                       m_dwUsage5[nCPU] / 10,
-                                                       m_dwUsage5[nCPU] % 10);
-                                       break;
-                               case '2':
-                                       _sntprintf(pValue, MAX_RESULT_LENGTH, _T("%d.%d00000"),
-                                                       m_dwUsage15[nCPU] / 10,
-                                                       m_dwUsage15[nCPU] % 10);
-                                       break;
-                               default:
-                                       nRet = SYSINFO_RC_UNSUPPORTED;
-                                       break;
-                       }
-               }
-               else
-               {
-                       nRet = SYSINFO_RC_UNSUPPORTED;
-               }
-       }
-
-       return nRet;
+   LONG nRet = SYSINFO_RC_SUCCESS;
+
+   if (pArg[0] == 'T')
+   {
+      switch(pArg[1])
+      {
+         case '0':
+            _sntprintf(pValue, MAX_RESULT_LENGTH, _T("%d.%d00000"),
+                  m_dwUsage[MAX_CPU_COUNT] / 10,
+                  m_dwUsage[MAX_CPU_COUNT] % 10);
+            break;
+         case '1':
+            _sntprintf(pValue, MAX_RESULT_LENGTH, _T("%d.%d00000"),
+                  m_dwUsage5[MAX_CPU_COUNT] / 10,
+                  m_dwUsage5[MAX_CPU_COUNT] % 10);
+            break;
+         case '2':
+            _sntprintf(pValue, MAX_RESULT_LENGTH, _T("%d.%d00000"),
+                  m_dwUsage15[MAX_CPU_COUNT] / 10,
+                  m_dwUsage15[MAX_CPU_COUNT] % 10);
+            break;
+         default:
+            nRet = SYSINFO_RC_UNSUPPORTED;
+            break;
+      }
+   }
+   else
+   {
+      LONG nCPU = -1, nInstance;
+      TCHAR *eptr, szBuffer[32] = _T("error");
+
+      // Get CPU number
+      AgentGetParameterArg(pszParam, 1, szBuffer, 32);
+      nInstance = _tcstol(szBuffer, &eptr, 0);
+      if (nInstance != -1)
+      {
+         for(nCPU = 0; nCPU < MAX_CPU_COUNT; nCPU++)
+            if (m_nInstanceMap[nCPU] == nInstance)
+               break;
+      }
+      if ((*eptr == 0) && (nCPU >= 0) && (nCPU < m_nCPUCount))
+      {
+         switch(pArg[1])
+         {
+            case '0':
+               _sntprintf(pValue, MAX_RESULT_LENGTH, _T("%d.%d00000"),
+                     m_dwUsage[nCPU] / 10,
+                     m_dwUsage[nCPU] % 10);
+               break;
+            case '1':
+               _sntprintf(pValue, MAX_RESULT_LENGTH, _T("%d.%d00000"),
+                     m_dwUsage5[nCPU] / 10,
+                     m_dwUsage5[nCPU] % 10);
+               break;
+            case '2':
+               _sntprintf(pValue, MAX_RESULT_LENGTH, _T("%d.%d00000"),
+                     m_dwUsage15[nCPU] / 10,
+                     m_dwUsage15[nCPU] % 10);
+               break;
+            default:
+               nRet = SYSINFO_RC_UNSUPPORTED;
+               break;
+         }
+      }
+      else
+      {
+         nRet = SYSINFO_RC_UNSUPPORTED;
+      }
+   }
+
+   return nRet;
 }
index 637d6ae..ebe7f64 100644 (file)
@@ -1,24 +1,24 @@
 /*
- ** NetXMS subagent for SunOS/Solaris
- ** Copyright (C) 2004-2013 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
- ** 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: disk.cpp
- **
- **/
+** NetXMS subagent for SunOS/Solaris
+** Copyright (C) 2004-2013 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
+** 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: disk.cpp
+**
+**/
 
 #include "sunos_subagent.h"
 #include <sys/statvfs.h>
  */
 LONG H_DiskInfo(const TCHAR *pszParam, const TCHAR *pArg, TCHAR *pValue)
 {
-       int nRet = SYSINFO_RC_ERROR;
-       struct statvfs sv;
-       char szPath[512] = "";
-
-       AgentGetParameterArgA(pszParam, 1, szPath, sizeof(szPath));
-
-       if ((szPath[0] != 0) && (statvfs(szPath, &sv) == 0))
-       {
-               nRet = SYSINFO_RC_SUCCESS;
-               
-               QWORD usedBlocks = (QWORD)(sv.f_blocks - sv.f_bfree);
-               QWORD totalBlocks = (QWORD)sv.f_blocks;
-               QWORD blockSize = (QWORD)sv.f_bsize;
-               QWORD freeBlocks = (QWORD)sv.f_bfree;
-               QWORD availableBlocks = (QWORD)sv.f_bavail;
-               
-               switch((long)pArg)
-               {
-                       case DISK_TOTAL:
-                               ret_uint64(pValue, totalBlocks * blockSize);
-                               break;
-                       case DISK_USED:
-                               ret_uint64(pValue, usedBlocks * blockSize);
-                               break;
-                       case DISK_FREE:
-                               ret_uint64(pValue, freeBlocks * blockSize);
-                               break;
-                       case DISK_AVAIL:
-                               ret_uint64(pValue, availableBlocks * blockSize);
-                               break;
-                       case DISK_USED_PERC:
-                               ret_double(pValue, (totalBlocks > 0) ? (usedBlocks * 100) / totalBlocks : 0);
-                               break;
-                       case DISK_AVAIL_PERC:
-                               ret_double(pValue, (totalBlocks > 0) ? (availableBlocks * 100) / totalBlocks : 0);
-                               break;
-                       case DISK_FREE_PERC:
-                               ret_double(pValue, (totalBlocks > 0) ? (freeBlocks * 100) / totalBlocks : 0);
-                               break;
-                       default:
-                               nRet = SYSINFO_RC_ERROR;
-                               break;
-               }
-       }
-
-       return nRet;
+   int nRet = SYSINFO_RC_ERROR;
+   struct statvfs sv;
+   char szPath[512] = "";
+
+   AgentGetParameterArgA(pszParam, 1, szPath, sizeof(szPath));
+
+   if ((szPath[0] != 0) && (statvfs(szPath, &sv) == 0))
+   {
+      nRet = SYSINFO_RC_SUCCESS;
+
+      QWORD usedBlocks = (QWORD)(sv.f_blocks - sv.f_bfree);
+      QWORD totalBlocks = (QWORD)sv.f_blocks;
+      QWORD blockSize = (QWORD)sv.f_bsize;
+      QWORD freeBlocks = (QWORD)sv.f_bfree;
+      QWORD availableBlocks = (QWORD)sv.f_bavail;
+
+      switch((long)pArg)
+      {
+         case DISK_TOTAL:
+            ret_uint64(pValue, totalBlocks * blockSize);
+            break;
+         case DISK_USED:
+            ret_uint64(pValue, usedBlocks * blockSize);
+            break;
+         case DISK_FREE:
+            ret_uint64(pValue, freeBlocks * blockSize);
+            break;
+         case DISK_AVAIL:
+            ret_uint64(pValue, availableBlocks * blockSize);
+            break;
+         case DISK_USED_PERC:
+            ret_double(pValue, (totalBlocks > 0) ? (usedBlocks * 100) / totalBlocks : 0);
+            break;
+         case DISK_AVAIL_PERC:
+            ret_double(pValue, (totalBlocks > 0) ? (availableBlocks * 100) / totalBlocks : 0);
+            break;
+         case DISK_FREE_PERC:
+            ret_double(pValue, (totalBlocks > 0) ? (freeBlocks * 100) / totalBlocks : 0);
+            break;
+         default:
+            nRet = SYSINFO_RC_ERROR;
+            break;
+      }
+   }
+
+   return nRet;
 }
 
 /**
@@ -104,8 +104,8 @@ LONG H_FileSystems(const TCHAR *cmd, const TCHAR *arg, Table *table)
          if (fgets(line, 256, in) == NULL)
             break;
          for(char *c = line; *c != 0; c++)
-             if (*c == '\t')
-                 *c = ' ';
+            if (*c == '\t')
+               *c = ' ';
 
          table->addRow();
 
@@ -181,8 +181,8 @@ LONG H_MountPoints(const TCHAR *cmd, const TCHAR *arg, StringList *value)
          if (fgets(line, 256, in) == NULL)
             break;
          for(char *c = line; *c != 0; c++)
-             if (*c == '\t')
-                 *c = ' ';
+            if (*c == '\t')
+               *c = ' ';
          char *ptr = strchr(line, ' ');
          if (ptr != NULL)
          {
index 6288ace..99779e8 100644 (file)
@@ -1,24 +1,24 @@
 /*
- ** NetXMS subagent for SunOS/Solaris
- ** Copyright (C) 2004-2011 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
- ** 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: iostat.cpp
- **
- **/
+** NetXMS subagent for SunOS/Solaris
+** Copyright (C) 2004-2011 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
+** 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: iostat.cpp
+**
+**/
 
 #include "sunos_subagent.h"
 
 
 struct IO_STATS
 {
-       // device name
-       char dev[KSTAT_STRLEN];
-
-       // current values
-       QWORD currBytesRead;
-       QWORD currBytesWritten;
-       DWORD currReadOps;
-       DWORD currWriteOps;
-       DWORD currQueue;
-       
-       // history - totals for queue, deltas for others
-       QWORD histBytesRead[HISTORY_SIZE];
-       QWORD histBytesWritten[HISTORY_SIZE];
-       DWORD histReadOps[HISTORY_SIZE];
-       DWORD histWriteOps[HISTORY_SIZE];
-       DWORD histQueue[HISTORY_SIZE];
+   // device name
+   char dev[KSTAT_STRLEN];
+
+   // current values
+   QWORD currBytesRead;
+   QWORD currBytesWritten;
+   DWORD currReadOps;
+   DWORD currWriteOps;
+   DWORD currQueue;
+
+   // history - totals for queue, deltas for others
+   QWORD histBytesRead[HISTORY_SIZE];
+   QWORD histBytesWritten[HISTORY_SIZE];
+   DWORD histReadOps[HISTORY_SIZE];
+   DWORD histWriteOps[HISTORY_SIZE];
+   DWORD histQueue[HISTORY_SIZE];
 };
 
 /**
@@ -66,37 +66,37 @@ static int s_currSlot = 0;  // current history slot
  */
 static void ProcessDeviceStats(const char *dev, kstat_io_t *kio)
 {
-       int i;
-
-       // find device
-       for(i = 1; i <= MAX_DEVICES; i++)
-               if (!strcmp(dev, s_data[i].dev) || (s_data[i].dev[0] == 0))
-                       break;
-       if (i > MAX_DEVICES)
-               return;         // No more free slots
-
-       if (s_data[i].dev[0] == 0)
-       {
-               // new device
-               AgentWriteDebugLog(5, _T("SunOS: device %hs added to I/O stat collection"), dev);
-               strcpy(s_data[i].dev, dev);
-       }
-       else
-       {
-               // existing device - update history
-               s_data[i].histBytesRead[s_currSlot] = kio->nread - s_data[i].currBytesRead;
-               s_data[i].histBytesWritten[s_currSlot] = kio->nwritten - s_data[i].currBytesWritten;
-               s_data[i].histReadOps[s_currSlot] = kio->reads - s_data[i].currReadOps;
-               s_data[i].histWriteOps[s_currSlot] = kio->writes - s_data[i].currWriteOps;
-               s_data[i].histQueue[s_currSlot] = kio->wcnt + kio->rcnt;
-       }
-
-       // update current values
-       s_data[i].currBytesRead = kio->nread;
-       s_data[i].currBytesWritten = kio->nwritten;
-       s_data[i].currReadOps = kio->reads;
-       s_data[i].currWriteOps = kio->writes;
-       s_data[i].currQueue = kio->wcnt + kio->rcnt;
+   int i;
+
+   // find device
+   for(i = 1; i <= MAX_DEVICES; i++)
+      if (!strcmp(dev, s_data[i].dev) || (s_data[i].dev[0] == 0))
+         break;
+   if (i > MAX_DEVICES)
+      return;          // No more free slots
+
+   if (s_data[i].dev[0] == 0)
+   {
+      // new device
+      AgentWriteDebugLog(5, _T("SunOS: device %hs added to I/O stat collection"), dev);
+      strcpy(s_data[i].dev, dev);
+   }
+   else
+   {
+      // existing device - update history
+      s_data[i].histBytesRead[s_currSlot] = kio->nread - s_data[i].currBytesRead;
+      s_data[i].histBytesWritten[s_currSlot] = kio->nwritten - s_data[i].currBytesWritten;
+      s_data[i].histReadOps[s_currSlot] = kio->reads - s_data[i].currReadOps;
+      s_data[i].histWriteOps[s_currSlot] = kio->writes - s_data[i].currWriteOps;
+      s_data[i].histQueue[s_currSlot] = kio->wcnt + kio->rcnt;
+   }
+
+   // update current values
+   s_data[i].currBytesRead = kio->nread;
+   s_data[i].currBytesWritten = kio->nwritten;
+   s_data[i].currReadOps = kio->reads;
+   s_data[i].currWriteOps = kio->writes;
+   s_data[i].currQueue = kio->wcnt + kio->rcnt;
 }
 
 /**
@@ -104,23 +104,23 @@ static void ProcessDeviceStats(const char *dev, kstat_io_t *kio)
  */
 static void CalculateTotals()
 {
-       QWORD br = 0, bw = 0;
-       DWORD r = 0, w = 0, q = 0;
-
-       for(int i = 1; (i <= MAX_DEVICES) && (s_data[i].dev[0] != 0); i++)
-       {
-               br += s_data[i].histBytesRead[s_currSlot];
-               bw += s_data[i].histBytesWritten[s_currSlot];
-               r += s_data[i].histReadOps[s_currSlot];
-               w += s_data[i].histWriteOps[s_currSlot];
-               q += s_data[i].histQueue[s_currSlot];
-       }
-
-       s_data[0].histBytesRead[s_currSlot] = br;
-       s_data[0].histBytesWritten[s_currSlot] = bw;
-       s_data[0].histReadOps[s_currSlot] = r;
-       s_data[0].histWriteOps[s_currSlot] = w;
-       s_data[0].histQueue[s_currSlot] = q;
+   QWORD br = 0, bw = 0;
+   DWORD r = 0, w = 0, q = 0;
+
+   for(int i = 1; (i <= MAX_DEVICES) && (s_data[i].dev[0] != 0); i++)
+   {
+      br += s_data[i].histBytesRead[s_currSlot];
+      bw += s_data[i].histBytesWritten[s_currSlot];
+      r += s_data[i].histReadOps[s_currSlot];
+      w += s_data[i].histWriteOps[s_currSlot];
+      q += s_data[i].histQueue[s_currSlot];
+   }
+
+   s_data[0].histBytesRead[s_currSlot] = br;
+   s_data[0].histBytesWritten[s_currSlot] = bw;
+   s_data[0].histReadOps[s_currSlot] = r;
+   s_data[0].histWriteOps[s_currSlot] = w;
+   s_data[0].histQueue[s_currSlot] = q;
 }
 
 /**
@@ -128,47 +128,47 @@ static void CalculateTotals()
  */
 THREAD_RESULT THREAD_CALL IOStatCollector(void *arg)
 {
-       kstat_ctl_t *kc;
-       kstat_t *kp;
-       kstat_io_t kio;
-
-       kstat_lock();
-       kc = kstat_open();
-       kstat_unlock();
-       if (kc == NULL)
-       {
-               AgentWriteLog(EVENTLOG_ERROR_TYPE, _T("SunOS::IOStatCollector: call to kstat_open failed (%s), I/O statistic will not be collected"), _tcserror(errno));
-               return THREAD_OK;
-       }
-
-       memset(s_data, 0, sizeof(IO_STATS) * (MAX_DEVICES + 1));
-       AgentWriteDebugLog(1, _T("SunOS: I/O stat collector thread started"));
-
-       while(!g_bShutdown)
-       {
-               kstat_lock();
-               kstat_chain_update(kc);
-               for(kp = kc->kc_chain; kp != NULL; kp = kp->ks_next)
-               {
-                       if (kp->ks_type == KSTAT_TYPE_IO)
-                       {
-                               kstat_read(kc, kp, &kio);
-                               ProcessDeviceStats(kp->ks_name, &kio);
-                       }
-               }
-               kstat_unlock();
-               CalculateTotals();
-               s_currSlot++;
-               if (s_currSlot == HISTORY_SIZE)
-                       s_currSlot = 0;
-               ThreadSleepMs(1000);
-       }
-
-       AgentWriteDebugLog(1, _T("SunOS: I/O stat collector thread stopped"));
-       kstat_lock();
-       kstat_close(kc);
-       kstat_unlock();
-       return THREAD_OK;
+   kstat_ctl_t *kc;
+   kstat_t *kp;
+   kstat_io_t kio;
+
+   kstat_lock();
+   kc = kstat_open();
+   kstat_unlock();
+   if (kc == NULL)
+   {
+      AgentWriteLog(EVENTLOG_ERROR_TYPE, _T("SunOS::IOStatCollector: call to kstat_open failed (%s), I/O statistic will not be collected"), _tcserror(errno));
+      return THREAD_OK;
+   }
+
+   memset(s_data, 0, sizeof(IO_STATS) * (MAX_DEVICES + 1));
+   AgentWriteDebugLog(1, _T("SunOS: I/O stat collector thread started"));
+
+   while(!g_bShutdown)
+   {
+      kstat_lock();
+      kstat_chain_update(kc);
+      for(kp = kc->kc_chain; kp != NULL; kp = kp->ks_next)
+      {
+         if (kp->ks_type == KSTAT_TYPE_IO)
+         {
+            kstat_read(kc, kp, &kio);
+            ProcessDeviceStats(kp->ks_name, &kio);
+         }
+      }
+      kstat_unlock();
+      CalculateTotals();
+      s_currSlot++;
+      if (s_currSlot == HISTORY_SIZE)
+         s_currSlot = 0;
+      ThreadSleepMs(1000);
+   }
+
+   AgentWriteDebugLog(1, _T("SunOS: I/O stat collector thread stopped"));
+   kstat_lock();
+   kstat_close(kc);
+   kstat_unlock();
+   return THREAD_OK;
 }
 
 /**
@@ -176,10 +176,10 @@ THREAD_RESULT THREAD_CALL IOStatCollector(void *arg)
  */
 static double CalculateAverage32(DWORD *series)
 {
-       double sum = 0;
-       for(int i = 0; i < HISTORY_SIZE; i++)
-               sum += series[i];
-       return sum / (double)HISTORY_SIZE;
+   double sum = 0;
+   for(int i = 0; i < HISTORY_SIZE; i++)
+      sum += series[i];
+   return sum / (double)HISTORY_SIZE;
 }
 
 /**
@@ -187,11 +187,11 @@ static double CalculateAverage32(DWORD *series)
  */
 static DWORD CalculateMin32(DWORD *series)
 {
-       DWORD val = series[0];
-       for(int i = 1; i < HISTORY_SIZE; i++)
-               if (series[i] < val)
-                       val = series[i];
-       return val;
+   DWORD val = series[0];
+   for(int i = 1; i < HISTORY_SIZE; i++)
+      if (series[i] < val)
+         val = series[i];
+   return val;
 }
 
 /**
@@ -199,11 +199,11 @@ static DWORD CalculateMin32(DWORD *series)
  */
 static DWORD CalculateMax32(DWORD *series)
 {
-       DWORD val = series[0];
-       for(int i = 1; i < HISTORY_SIZE; i++)
-               if (series[i] > val)
-                       val = series[i];
-       return val;
+   DWORD val = series[0];
+   for(int i = 1; i < HISTORY_SIZE; i++)
+      if (series[i] > val)
+         val = series[i];
+   return val;
 }
 
 /**
@@ -211,10 +211,10 @@ static DWORD CalculateMax32(DWORD *series)
  */
 static QWORD CalculateAverage64(QWORD *series)
 {
-       QWORD sum = 0;
-       for(int i = 0; i < HISTORY_SIZE; i++)
-               sum += series[i];
-       return sum / HISTORY_SIZE;
+   QWORD sum = 0;
+   for(int i = 0; i < HISTORY_SIZ