added persistent storage in agent; added agent policy registration in persistent...
authorVictor Kirhenshtein <victor@netxms.org>
Tue, 9 Nov 2010 23:54:03 +0000 (23:54 +0000)
committerVictor Kirhenshtein <victor@netxms.org>
Tue, 9 Nov 2010 23:54:03 +0000 (23:54 +0000)
22 files changed:
include/nms_common.h
include/nxconfig.h
include/uuid.h
src/agent/core/config.cpp
src/agent/core/messages.mc
src/agent/core/nxagentd.cpp
src/agent/core/nxagentd.h
src/agent/core/policy.cpp
src/agent/core/session.cpp
src/java/netxms-base/src/main/java/org/netxms/base/NXCPCodes.java
src/java/netxms-client/src/main/java/org/netxms/client/NXCObjectModificationData.java
src/java/netxms-client/src/main/java/org/netxms/client/NXCSession.java
src/java/netxms-client/src/main/java/org/netxms/client/objects/AgentPolicy.java
src/java/netxms-client/src/main/java/org/netxms/client/objects/AgentPolicyConfig.java
src/java/netxms-client/src/main/java/org/netxms/client/objects/GenericObject.java
src/java/netxms-eclipse/ObjectTools/plugin.xml
src/java/netxms-eclipse/PolicyManager/src/org/netxms/ui/eclipse/policymanager/Activator.java
src/java/netxms-eclipse/PolicyManager/src/org/netxms/ui/eclipse/policymanager/propertypages/ConfigFile.java
src/java/netxms-eclipse/PolicyManager/src/org/netxms/ui/eclipse/policymanager/propertypages/Policy.java
src/libnetxms/config.cpp
src/libnetxms/uuid.c
src/server/core/id.cpp

index 993aa9d..69962ee 100644 (file)
@@ -673,7 +673,7 @@ typedef struct tagPOINT
 
 
 //
-// Event log severity codes (UNIX only)
+// Event log severity codes
 //
 
 #ifndef _WIN32
@@ -685,6 +685,11 @@ typedef struct tagPOINT
 #define EVENTLOG_AUDIT_FAILURE          0x0010
 #endif   /* _WIN32 */
 
+#define NXLOG_DEBUG     EVENTLOG_DEBUG_TYPE
+#define NXLOG_INFO      EVENTLOG_INFORMATION_TYPE
+#define NXLOG_WARNING   EVENTLOG_WARNING_TYPE
+#define NXLOG_ERROR     EVENTLOG_ERROR_TYPE
+
 
 //
 // Interface types
index c2d9a64..ff321e1 100644 (file)
@@ -46,14 +46,15 @@ private:
        int m_line;
        int m_id;
 
-       void linkEntry(ConfigEntry *entry) { entry->m_next = m_next; m_next = entry; }
        void addEntry(ConfigEntry *entry) { entry->m_parent = this; entry->m_next = m_childs; m_childs = entry; }
+       void linkEntry(ConfigEntry *entry) { entry->m_next = m_next; m_next = entry; }
 
 public:
        ConfigEntry(const TCHAR *name, ConfigEntry *parent, const TCHAR *file, int line, int id);
        ~ConfigEntry();
 
        ConfigEntry *getNext() { return m_next; }
+       ConfigEntry *getParent() { return m_parent; }
 
        const TCHAR *getName() { return m_name; }
        int getId() { return m_id; }
@@ -66,6 +67,7 @@ public:
        INT64 getValueInt64(int index = 0, INT64 defaultValue = 0);
        QWORD getValueUInt64(int index = 0, QWORD defaultValue = 0);
        bool getValueBoolean(int index = 0, bool defaultValue = false);
+       bool getValueUUID(int index, uuid_t uuid);
 
        const TCHAR *getSubEntryValue(const TCHAR *name, int index = 0, const TCHAR *defaultValue = NULL);
        LONG getSubEntryValueInt(const TCHAR *name, int index = 0, LONG defaultValue = 0);
@@ -73,6 +75,7 @@ public:
        INT64 getSubEntryValueInt64(const TCHAR *name, int index = 0, INT64 defaultValue = 0);
        QWORD getSubEntryValueUInt64(const TCHAR *name, int index = 0, QWORD defaultValue = 0);
        bool getSubEntryValueBoolean(const TCHAR *name, int index = 0, bool defaultValue = false);
+       bool getSubEntryValueUUID(const TCHAR *name, uuid_t uuid, int index = 0);
 
        const TCHAR *getFile() { return m_file; }
        int getLine() { return m_line; }
@@ -82,9 +85,11 @@ public:
        void addValue(const TCHAR *value);
        void setValue(const TCHAR*value);
 
+       ConfigEntry *createEntry(const TCHAR *name);
        ConfigEntry *findEntry(const TCHAR *name);
        ConfigEntryList *getSubEntries(const TCHAR *mask);
        ConfigEntryList *getOrderedSubEntries(const TCHAR *mask);
+       void unlinkEntry(ConfigEntry *entry);
 
        void print(FILE *file, int level);
        void createXml(String &xml, int level = 0);
@@ -121,6 +126,7 @@ class LIBNETXMS_EXPORTABLE Config
 private:
        ConfigEntry *m_root;
        int m_errorCount;
+       MUTEX m_mutex;
 
 protected:
        virtual void onError(const TCHAR *errorMessage);
@@ -132,6 +138,9 @@ public:
        Config();
        ~Config();
 
+       void lock() { MutexLock(m_mutex, INFINITE); }
+       void unlock() { MutexUnlock(m_mutex); }
+
        void setTopLevelTag(const TCHAR *topLevelTag) { m_root->setName(topLevelTag); }
 
        bool loadXmlConfig(const TCHAR *file, const char *topLevelTag = NULL);
@@ -141,6 +150,8 @@ public:
 
        bool loadConfigDirectory(const TCHAR *path, const TCHAR *defaultIniSection);
 
+       void deleteEntry(const TCHAR *path);
+
        ConfigEntry *getEntry(const TCHAR *path);
        const TCHAR *getValue(const TCHAR *path, const TCHAR *defaultValue = NULL);
        LONG getValueInt(const TCHAR *path, LONG defaultValue);
@@ -148,6 +159,7 @@ public:
        INT64 getValueInt64(const TCHAR *path, INT64 defaultValue);
        QWORD getValueUInt64(const TCHAR *path, QWORD defaultValue);
        bool getValueBoolean(const TCHAR *path, bool defaultValue);
+       bool getValueUUID(const TCHAR *path, uuid_t uuid);
        ConfigEntryList *getSubEntries(const TCHAR *path, const TCHAR *mask);
        ConfigEntryList *getOrderedSubEntries(const TCHAR *path, const TCHAR *mask);
 
@@ -157,6 +169,7 @@ public:
        bool setValue(const TCHAR *path, INT64 value);
        bool setValue(const TCHAR *path, QWORD value);
        bool setValue(const TCHAR *path, double value);
+       bool setValue(const TCHAR *path, uuid_t value);
 
        bool parseTemplate(const TCHAR *section, NX_CFG_TEMPLATE *cfgTemplate);
 
index 87d9171..c439788 100644 (file)
@@ -32,7 +32,7 @@ int LIBNETXMS_EXPORTABLE uuid_compare(uuid_t uu1, uuid_t uu2);
 void LIBNETXMS_EXPORTABLE uuid_copy(uuid_t uu1, uuid_t uu2);
 void LIBNETXMS_EXPORTABLE uuid_generate(uuid_t out);
 int LIBNETXMS_EXPORTABLE uuid_is_null(uuid_t uu);
-int LIBNETXMS_EXPORTABLE uuid_parse(TCHAR *in, uuid_t uu);
+int LIBNETXMS_EXPORTABLE uuid_parse(const TCHAR *in, uuid_t uu);
 TCHAR LIBNETXMS_EXPORTABLE *uuid_to_string(uuid_t uu, TCHAR *out);
 
 #ifdef __cplusplus
index 084c5a1..015e3a4 100644 (file)
@@ -1,6 +1,6 @@
 /* 
 ** NetXMS multiplatform core agent
-** Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Victor Kirhenshtein
+** Copyright (C) 2003-2010 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
index cd62bfa..bd86dee 100644 (file)
@@ -284,4 +284,16 @@ Language=English
 Debug level set to %1
 .
 
+MessageId=
+SymbolicName=MSG_REGISTRY_LOAD_FAILED
+Language=English
+Failed to load agent's registry from file %1
+.
+
+MessageId=
+SymbolicName=MSG_REGISTRY_SAVE_FAILED
+Language=English
+Failed to save agent's registry to file %1: %2
+.
+
 ;#endif
index 8e05530..75de9ad 100644 (file)
@@ -1,6 +1,6 @@
 /* 
 ** NetXMS multiplatform core agent
-** Copyright (C) 2003-2009 Victor Kirhenshtein
+** Copyright (C) 2003-2010 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
@@ -62,7 +62,7 @@ void InitSessionList();
 BOOL PushData(const TCHAR *parameter, const TCHAR *value);
 
 #if !defined(_WIN32) && !defined(_NETWARE)
-void InitStaticSubagents(void);
+void InitStaticSubagents();
 #endif
 
 #ifdef _WIN32
@@ -121,6 +121,7 @@ char g_szLogFile[MAX_PATH] = AGENT_DEFAULT_LOG;
 char g_szSharedSecret[MAX_SECRET_LENGTH] = "admin";
 char g_szConfigFile[MAX_PATH] = AGENT_DEFAULT_CONFIG;
 char g_szFileStore[MAX_PATH] = AGENT_DEFAULT_FILE_STORE;
+char g_szDataDirectory[MAX_PATH] = AGENT_DEFAULT_DATA_DIR;
 char g_szPlatformSuffix[MAX_PSUFFIX_LENGTH] = "";
 char g_szConfigServer[MAX_DB_STRING] = "not_set";
 char g_szRegistrar[MAX_DB_STRING] = "not_set";
@@ -176,6 +177,7 @@ static char m_szProcessToWait[MAX_PATH] = "";
 static char m_szDumpDir[MAX_PATH] = "C:\\";
 static DWORD m_dwMaxLogSize = 16384 * 1024;
 static DWORD m_dwLogHistorySize = 4;
+static Config *s_registry = NULL;
 
 #if defined(_WIN32) || defined(_NETWARE)
 static CONDITION m_hCondShutdown = INVALID_CONDITION_HANDLE;
@@ -196,6 +198,7 @@ static NX_CFG_TEMPLATE m_cfgTemplate[] =
    { "ActionShellExec", CT_STRING_LIST, '\n', 0, 0, 0, &m_pszShellActionList },
    { "ControlServers", CT_STRING_LIST, ',', 0, 0, 0, &m_pszControlServerList },
    { "CreateCrashDumps", CT_BOOLEAN, 0, 0, AF_CATCH_EXCEPTIONS, 0, &g_dwFlags },
+       { "DataDirectory", CT_STRING, 0, 0, MAX_PATH, 0, g_szDataDirectory },
        { "DebugLevel", CT_LONG, 0, 0, 0, 0, &g_debugLevel },
    { "DumpDirectory", CT_STRING, 0, 0, MAX_PATH, 0, m_szDumpDir },
    { "EnableActions", CT_BOOLEAN, 0, 0, AF_ENABLE_ACTIONS, 0, &g_dwFlags },
@@ -273,13 +276,62 @@ static char m_szHelpText[] =
    "\n";
 
 
+//
+// Save registry
+//
+
+static void SaveRegistry()
+{
+       TCHAR regPath[MAX_PATH];
+       nx_strncpy(regPath, g_szDataDirectory, MAX_PATH - _tcslen(REGISTRY_FILE_NAME) - 1);
+       if (regPath[_tcslen(regPath) - 1] != FS_PATH_SEPARATOR_CHAR)
+               _tcscat(regPath, FS_PATH_SEPARATOR);
+       _tcscat(regPath, REGISTRY_FILE_NAME);
+
+       String xml = s_registry->createXml();
+       FILE *f = _tfopen(regPath, _T("w"));
+       if (f != NULL)
+       {
+               _fputts((const TCHAR *)xml, f);
+               fclose(f);
+       }
+       else
+       {
+               nxlog_write(MSG_REGISTRY_SAVE_FAILED, NXLOG_ERROR, "ss", regPath, strerror(errno));
+       }
+}
+
+
+//
+// Open registry
+//
+
+Config *OpenRegistry()
+{
+       s_registry->lock();
+       return s_registry;
+}
+
+
+//
+// Close registry
+//
+
+void CloseRegistry(bool modified)
+{
+       if (modified)
+               SaveRegistry();
+       s_registry->unlock();
+}
+
+
 #ifdef _WIN32
 
 //
 // Get our own console window handle (an alternative to Microsoft's GetConsoleWindow)
 //
 
-static HWND GetConsoleHWND(void)
+static HWND GetConsoleHWND()
 {
        HWND hWnd;
        DWORD wpid, cpid;
@@ -319,7 +371,7 @@ static FARPROC GetProcAddressAndLog(HMODULE hModule, LPCSTR procName)
 // Import symbols
 //
 
-static void ImportSymbols(void)
+static void ImportSymbols()
 {
    HMODULE hModule;
 
@@ -530,7 +582,7 @@ stop_handler:
 
 #ifdef _WIN32
 
-void LoadWindowsSubagent(void)
+void LoadWindowsSubagent()
 {
    OSVERSIONINFO ver;
 
@@ -557,7 +609,7 @@ void LoadWindowsSubagent(void)
 
 #else
 
-void LoadPlatformSubagent(void)
+void LoadPlatformSubagent()
 {
 #if defined(_NETWARE)
    LoadSubAgent("NETWARE.NSM");
@@ -618,6 +670,7 @@ static void DBLibraryDebugCallback(int level, const TCHAR *format, va_list args)
 BOOL Initialize()
 {
    char *pItem, *pEnd;
+       char regPath[MAX_PATH];
 #ifdef _NETWARE
    char szLoadPath[1024], szSearchPath[1024];
 #endif
@@ -642,8 +695,21 @@ BOOL Initialize()
                fprintf(stderr, "FATAL ERROR: Cannot open log file\n");
                return FALSE;
        }
-       nxlog_write(MSG_USE_CONFIG_D, EVENTLOG_INFORMATION_TYPE, "s", g_szConfigIncludeDir);
-       nxlog_write(MSG_DEBUG_LEVEL, EVENTLOG_INFORMATION_TYPE, "d", g_debugLevel);
+       nxlog_write(MSG_USE_CONFIG_D, NXLOG_INFO, "s", g_szConfigIncludeDir);
+       nxlog_write(MSG_DEBUG_LEVEL, NXLOG_INFO, "d", g_debugLevel);
+
+       // Initialize persistent storage
+       s_registry = new Config;
+       s_registry->setTopLevelTag(_T("registry"));
+       nx_strncpy(regPath, g_szDataDirectory, MAX_PATH - _tcslen(REGISTRY_FILE_NAME) - 1);
+       if (regPath[_tcslen(regPath) - 1] != FS_PATH_SEPARATOR_CHAR)
+               _tcscat(regPath, FS_PATH_SEPARATOR);
+       _tcscat(regPath, REGISTRY_FILE_NAME);
+       if (!s_registry->loadXmlConfig(regPath, "registry"))
+       {
+               nxlog_write(MSG_REGISTRY_LOAD_FAILED, NXLOG_ERROR, "s", regPath);
+               SaveRegistry();
+       }
 
 #ifdef _WIN32
    WSADATA wsaData;
@@ -651,7 +717,7 @@ BOOL Initialize()
 
    if (WSAStartup(2, &wsaData) != 0)
    {
-      nxlog_write(MSG_WSASTARTUP_FAILED, EVENTLOG_ERROR_TYPE, "e", WSAGetLastError());
+      nxlog_write(MSG_WSASTARTUP_FAILED, NXLOG_ERROR, "e", WSAGetLastError());
       return FALSE;
    }
 
index d1485c4..3c0859b 100644 (file)
 #define AGENT_DEFAULT_CONFIG_D   "C:\\nxagentd.conf.d"
 #define AGENT_DEFAULT_LOG        "C:\\nxagentd.log"
 #define AGENT_DEFAULT_FILE_STORE "C:\\"
+#define AGENT_DEFAULT_DATA_DIR   "C:\\"
 #elif defined(_NETWARE)
 #define AGENT_DEFAULT_CONFIG     "SYS:ETC/nxagentd.conf"
 #define AGENT_DEFAULT_CONFIG_D   "SYS:ETC/nxagentd.conf.d"
 #define AGENT_DEFAULT_LOG        "SYS:ETC/nxagentd.log"
 #define AGENT_DEFAULT_FILE_STORE "SYS:\\"
+#define AGENT_DEFAULT_DATA_DIR   "SYS:ETC"
 #elif defined(_IPSO)
 #define AGENT_DEFAULT_CONFIG     "/opt/netxms/etc/nxagentd.conf"
 #define AGENT_DEFAULT_CONFIG_D   "/opt/netxms/etc/nxagentd.conf.d"
 #define AGENT_DEFAULT_LOG        "/opt/netxms/log/nxagentd.log"
 #define AGENT_DEFAULT_FILE_STORE "/opt/netxms/store"
+#define AGENT_DEFAULT_DATA_DIR   "/opt/netxms/data"
 #else
 #define AGENT_DEFAULT_CONFIG     "{search}"
 #define AGENT_DEFAULT_CONFIG_D   "{search}"
 #define AGENT_DEFAULT_LOG        "/var/log/nxagentd"
 #define AGENT_DEFAULT_FILE_STORE "/tmp"
+#define AGENT_DEFAULT_DATA_DIR   "/var/opt/netxms/agent"
 #endif
 
+#define REGISTRY_FILE_NAME       "registry.dat"
+
 
 //
 // Constants
@@ -301,6 +307,8 @@ public:
    void sendRawMessage(CSCP_MESSAGE *pMsg) { m_pSendQueue->Put(nx_memdup(pMsg, ntohl(pMsg->dwSize))); }
        bool sendFile(DWORD requestId, const TCHAR *file, long offset);
 
+       DWORD getServerAddress() { return m_dwHostAddr; }
+
    DWORD getIndex() { return m_dwIndex; }
    void setIndex(DWORD dwIndex) { if (m_dwIndex == INVALID_INDEX) m_dwIndex = dwIndex; }
 
@@ -315,9 +323,9 @@ public:
 // Functions
 //
 
-BOOL Initialize(void);
-void Shutdown(void);
-void Main(void);
+BOOL Initialize();
+void Shutdown();
+void Main();
 
 void ConsolePrintf(const char *pszFormat, ...);
 void DebugPrintf(DWORD dwSessionId, int level, const char *pszFormat, ...);
@@ -326,7 +334,7 @@ void BuildFullPath(TCHAR *pszFileName, TCHAR *pszFullPath);
 
 BOOL DownloadConfig(TCHAR *pszServer);
 
-BOOL InitParameterList(void);
+BOOL InitParameterList();
 void AddParameter(const char *szName, LONG (* fpHandler)(const char *, const char *, char *), const char *pArg,
                   int iDataType, const char *pszDescription);
 void AddPushParameter(const TCHAR *name, int dataType, const TCHAR *description);
@@ -337,7 +345,7 @@ DWORD GetEnumValue(DWORD dwSessionId, char *pszParam, StringList *pValue);
 void GetParameterList(CSCPMessage *pMsg);
 
 BOOL LoadSubAgent(char *szModuleName);
-void UnloadAllSubAgents(void);
+void UnloadAllSubAgents();
 BOOL InitSubAgent(HMODULE hModule, TCHAR *pszModuleName,
                   BOOL (* SubAgentInit)(NETXMS_SUBAGENT_INFO **, TCHAR *),
                   TCHAR *pszEntryPoint);
@@ -360,16 +368,19 @@ void SendTrap(DWORD dwEventCode, int iNumArgs, TCHAR **ppArgList);
 void SendTrap(DWORD dwEventCode, const char *pszFormat, ...);
 void SendTrap(DWORD dwEventCode, const char *pszFormat, va_list args);
 
+Config *OpenRegistry();
+void CloseRegistry(bool modified);
+
 #ifdef _WIN32
 
-void InitService(void);
+void InitService();
 void InstallService(char *execName, char *confFile);
-void RemoveService(void);
-void StartAgentService(void);
-void StopAgentService(void);
+void RemoveService();
+void StartAgentService();
+void StopAgentService();
 BOOL WaitForService(DWORD dwDesiredState);
 void InstallEventSource(char *path);
-void RemoveEventSource(void);
+void RemoveEventSource();
 
 char *GetPdhErrorText(DWORD dwError, char *pszBuffer, int iBufSize);
 
index 972034e..39b3872 100644 (file)
@@ -1,6 +1,6 @@
 /* 
 ** NetXMS multiplatform core agent
-** Copyright (C) 2003-2009 Victor Kirhenshtein
+** Copyright (C) 2003-2010 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
 #define close _close
 #endif
 
+#define POLICY_REGISTRY_PATH _T("/policyRegistry")
+
+
+//
+// Register policy in persistent storage
+//
+
+static void RegisterPolicy(CommSession *session, DWORD type, uuid_t guid)
+{
+       TCHAR path[256], buffer[64];
+       int tail;
+
+       _sntprintf(path, 256, _T("/policyRegistry/%s/"), uuid_to_string(guid, buffer));
+       tail = _tcslen(path);
+
+       Config *registry = OpenRegistry();
+
+       _tcscpy(&path[tail], _T("type"));
+       registry->setValue(path, type);
+
+       _tcscpy(&path[tail], _T("server"));
+       registry->setValue(path, IpToStr(session->getServerAddress(), buffer));
+
+       CloseRegistry(true);
+}
+
+
+//
+// Register policy in persistent storage
+//
+
+static void UnregisterPolicy(DWORD type, uuid_t guid)
+{
+       TCHAR path[256], buffer[64];
+
+       _sntprintf(path, 256, _T("/policyRegistry/%s"), uuid_to_string(guid, buffer));
+       Config *registry = OpenRegistry();
+       registry->deleteEntry(path);
+       CloseRegistry(true);
+}
+
 
 //
 // Deploy configuration file
 //
 
-static DWORD DeployConfig(DWORD session, CSCPMessage *msg)
+static DWORD DeployConfig(DWORD session, uuid_t guid, CSCPMessage *msg)
 {
-       TCHAR path[MAX_PATH], name[MAX_PATH], *fname, tail;
-       int i, fh;
+       TCHAR path[MAX_PATH], name[64], tail;
+       int fh;
        DWORD rcc;
 
-       msg->GetVariableStr(VID_CONFIG_FILE_NAME, name, MAX_PATH);
-       DebugPrintf(session, 3, _T("DeployConfig(): original file name is %s"), name);
-       for(i = (int)_tcslen(name) - 1; i >= 0; i--)
-               if ((name[i] == '/') || (name[i] == '\\'))
-               {
-                       break;
-               }
-       fname = &name[i + 1];
        tail = g_szConfigIncludeDir[_tcslen(g_szConfigIncludeDir) - 1];
-       _sntprintf(path, MAX_PATH, _T("%s%s%s"), g_szConfigIncludeDir, ((tail != '\\') && (tail != '/')) ? FS_PATH_SEPARATOR : _T(""), fname);
+       _sntprintf(path, MAX_PATH, _T("%s%s%s.conf"), g_szConfigIncludeDir,
+                  ((tail != '\\') && (tail != '/')) ? FS_PATH_SEPARATOR : _T(""),
+                                 uuid_to_string(guid, name));
 
        fh = _topen(path, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, S_IRUSR | S_IWUSR);
        if (fh != -1)
@@ -88,21 +123,28 @@ static DWORD DeployConfig(DWORD session, CSCPMessage *msg)
 // Deploy policy on agent
 //
 
-DWORD DeployPolicy(DWORD session, CSCPMessage *request)
+DWORD DeployPolicy(CommSession *session, CSCPMessage *request)
 {
        DWORD type, rcc;
+       uuid_t guid;
 
        type = request->GetVariableShort(VID_POLICY_TYPE);
+       request->GetVariableBinary(VID_GUID, guid, UUID_LENGTH);
+
        switch(type)
        {
                case AGENT_POLICY_CONFIG:
-                       rcc = DeployConfig(session, request);
+                       rcc = DeployConfig(session->getIndex(), guid, request);
                        break;
                default:
                        rcc = ERR_BAD_ARGUMENTS;
                        break;
        }
-       DebugPrintf(session, 3, _T("Policy deployment: TYPE=%d RCC=%d"), type, rcc);
+
+       if (rcc == RCC_SUCCESS)
+               RegisterPolicy(session, type, guid);
+
+       DebugPrintf(session->getIndex(), 3, _T("Policy deployment: TYPE=%d RCC=%d"), type, rcc);
        return rcc;
 }
 
@@ -111,22 +153,16 @@ DWORD DeployPolicy(DWORD session, CSCPMessage *request)
 // Remove configuration file
 //
 
-static DWORD RemoveConfig(DWORD session, CSCPMessage *msg)
+static DWORD RemoveConfig(DWORD session, uuid_t guid,  CSCPMessage *msg)
 {
-       TCHAR path[MAX_PATH], name[MAX_PATH], *fname, tail;
-       int i;
+       TCHAR path[MAX_PATH], name[64], tail;
        DWORD rcc;
 
-       msg->GetVariableStr(VID_CONFIG_FILE_NAME, name, MAX_PATH);
-       DebugPrintf(session, 3, _T("RemoveConfig(): original file name is %s"), name);
-       for(i = (int)_tcslen(name) - 1; i >= 0; i--)
-               if ((name[i] == '/') || (name[i] == '\\'))
-               {
-                       break;
-               }
-       fname = &name[i + 1];
        tail = g_szConfigIncludeDir[_tcslen(g_szConfigIncludeDir) - 1];
-       _sntprintf(path, MAX_PATH, _T("%s%s%s"), g_szConfigIncludeDir, ((tail != '\\') && (tail != '/')) ? FS_PATH_SEPARATOR : _T(""), fname);
+       _sntprintf(path, MAX_PATH, _T("%s%s%s.conf"), g_szConfigIncludeDir,
+                  ((tail != '\\') && (tail != '/')) ? FS_PATH_SEPARATOR : _T(""),
+                                 uuid_to_string(guid, name));
+
        if (_tremove(path) != 0)
        {
                rcc = (errno == ENOENT) ? ERR_SUCCESS : ERR_IO_FAILURE;
@@ -143,20 +179,27 @@ static DWORD RemoveConfig(DWORD session, CSCPMessage *msg)
 // Uninstall policy from agent
 //
 
-DWORD UninstallPolicy(DWORD session, CSCPMessage *request)
+DWORD UninstallPolicy(CommSession *session, CSCPMessage *request)
 {
        DWORD type, rcc;
+       uuid_t guid;
 
        type = request->GetVariableShort(VID_POLICY_TYPE);
+       request->GetVariableBinary(VID_GUID, guid, UUID_LENGTH);
+
        switch(type)
        {
                case AGENT_POLICY_CONFIG:
-                       rcc = RemoveConfig(session, request);
+                       rcc = RemoveConfig(session->getIndex(), guid, request);
                        break;
                default:
                        rcc = ERR_BAD_ARGUMENTS;
                        break;
        }
-       DebugPrintf(session, 3, _T("Policy uninstall: TYPE=%d RCC=%d"), type, rcc);
+
+       if (rcc == RCC_SUCCESS)
+               UnregisterPolicy(type, guid);
+
+       DebugPrintf(session->getIndex(), 3, _T("Policy uninstall: TYPE=%d RCC=%d"), type, rcc);
        return rcc;
 }
index 902f794..5ef5d3d 100644 (file)
@@ -34,8 +34,8 @@
 
 void UnregisterSession(DWORD dwIndex);
 void ProxySNMPRequest(CSCPMessage *pRequest, CSCPMessage *pResponse);
-DWORD DeployPolicy(DWORD session, CSCPMessage *request);
-DWORD UninstallPolicy(DWORD session, CSCPMessage *request);
+DWORD DeployPolicy(CommSession *session, CSCPMessage *request);
+DWORD UninstallPolicy(CommSession *session, CSCPMessage *request);
 
 
 //
@@ -494,7 +494,7 @@ void CommSession::processingThread()
                                case CMD_DEPLOY_AGENT_POLICY:
                                        if (m_bMasterServer)
                                        {
-                                               msg.SetVariable(VID_RCC, DeployPolicy(m_dwIndex, pMsg));
+                                               msg.SetVariable(VID_RCC, DeployPolicy(this, pMsg));
                                        }
                                        else
                                        {
@@ -504,7 +504,7 @@ void CommSession::processingThread()
                                case CMD_UNINSTALL_AGENT_POLICY:
                                        if (m_bMasterServer)
                                        {
-                                               msg.SetVariable(VID_RCC, UninstallPolicy(m_dwIndex, pMsg));
+                                               msg.SetVariable(VID_RCC, UninstallPolicy(this, pMsg));
                                        }
                                        else
                                        {
index fcafeb0..946b7cd 100644 (file)
@@ -347,7 +347,7 @@ public final class NXCPCodes
        public static final long VID_EVENT_NAME_TABLE        = 77;\r
        public static final long VID_PARENT_ID               = 78;\r
        public static final long VID_CHILD_ID                = 79;\r
-       public static final long VID_CONFIG_FILE_NAME        = 80;\r
+       //public static final long VID_CONFIG_FILE_NAME        = 80;\r
        public static final long VID_CONFIG_FILE_DATA        = 81;\r
        public static final long VID_COMMENTS                = 82;\r
        public static final long VID_POLICY_ID               = 83;\r
index f66ce65..7e1a674 100644 (file)
@@ -58,7 +58,6 @@ public class NXCObjectModificationData
        private String autoApplyFilter;\r
        private boolean autoBindEnabled;\r
        private String autoBindFilter;\r
-       private String configFileName;\r
        private String configFileContent;\r
        private int version;\r
        private String description;\r
@@ -247,23 +246,6 @@ public class NXCObjectModificationData
        }\r
 \r
        /**\r
-        * @return the configFileName\r
-        */\r
-       public String getConfigFileName()\r
-       {\r
-               return configFileName;\r
-       }\r
-\r
-       /**\r
-        * @param configFileName the configFileName to set\r
-        */\r
-       public void setConfigFileName(String configFileName)\r
-       {\r
-               this.configFileName = configFileName;\r
-               flags |= MODIFY_POLICY_CONFIG;\r
-       }\r
-\r
-       /**\r
         * @return the configFileContent\r
         */\r
        public String getConfigFileContent()\r
index 2fb9edd..6674dfe 100644 (file)
@@ -1991,7 +1991,6 @@ public class NXCSession implements Session, ScriptLibraryManager, UserManager, S
                // Configuration file\r
                if ((flags & NXCObjectModificationData.MODIFY_POLICY_CONFIG) != 0)\r
                {\r
-                       msg.setVariable(NXCPCodes.VID_CONFIG_FILE_NAME, data.getConfigFileName());\r
                        msg.setVariable(NXCPCodes.VID_CONFIG_FILE_DATA, data.getConfigFileContent());\r
                }\r
 \r
index 9fd76b5..dc01ec9 100644 (file)
@@ -23,7 +23,7 @@ import org.netxms.base.NXCPMessage;
 import org.netxms.client.NXCSession;\r
 \r
 /**\r
- * @author Victor\r
+ * Generic agent policy object\r
  *\r
  */\r
 public class AgentPolicy extends GenericObject\r
index 5f7d3d1..cef460c 100644 (file)
@@ -1,5 +1,20 @@
 /**\r
- * \r
+ * NetXMS - open source network management system\r
+ * Copyright (C) 2003-2010 Victor Kirhenshtein\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
  */\r
 package org.netxms.client.objects;\r
 \r
@@ -8,12 +23,11 @@ import org.netxms.base.NXCPMessage;
 import org.netxms.client.NXCSession;\r
 \r
 /**\r
- * @author Victor\r
+ * Agent policy for deploying configuration files\r
  *\r
  */\r
 public class AgentPolicyConfig extends AgentPolicy\r
 {\r
-       private String fileName;\r
        private String fileContent;\r
 \r
        /**\r
@@ -23,19 +37,10 @@ public class AgentPolicyConfig extends AgentPolicy
        public AgentPolicyConfig(NXCPMessage msg, NXCSession session)\r
        {\r
                super(msg, session);\r
-               fileName = msg.getVariableAsString(NXCPCodes.VID_CONFIG_FILE_NAME);\r
                fileContent = msg.getVariableAsString(NXCPCodes.VID_CONFIG_FILE_DATA);\r
        }\r
 \r
        /**\r
-        * @return the fileName\r
-        */\r
-       public String getFileName()\r
-       {\r
-               return fileName;\r
-       }\r
-\r
-       /**\r
         * @return the fileContent\r
         */\r
        public String getFileContent()\r
index 9dbc942..ec24e9f 100644 (file)
@@ -10,6 +10,7 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;
+import java.util.UUID;
 import java.net.InetAddress;
 import org.netxms.base.*;
 import org.netxms.client.GeoLocation;
@@ -55,6 +56,7 @@ public class GenericObject
        
        // Generic object attributes
        private long objectId = 0;
+       private UUID guid;
        private String objectName;
        private int objectClass;        // NetXMS object class
        private int status = STATUS_UNKNOWN;
@@ -85,6 +87,7 @@ public class GenericObject
                this.session = session;
                
                objectId = msg.getVariableAsInteger(NXCPCodes.VID_OBJECT_ID);
+               guid = msg.getVariableAsUUID(NXCPCodes.VID_GUID);
                objectName = msg.getVariableAsString(NXCPCodes.VID_OBJECT_NAME);
                objectClass = msg.getVariableAsInteger(NXCPCodes.VID_OBJECT_CLASS);
                primaryIP = msg.getVariableAsInetAddress(NXCPCodes.VID_IP_ADDRESS);
@@ -414,4 +417,13 @@ public class GenericObject
        {
                return (int)objectId;
        }
+
+
+       /**
+        * @return the guid
+        */
+       public UUID getGuid()
+       {
+               return guid;
+       }
 }
index 9ed972b..091e919 100644 (file)
@@ -12,7 +12,7 @@
                   checkEnabled="false">\r
                <iterate\r
                      ifEmpty="false"\r
-                     operator="or">\r
+                     operator="and">\r
                   <instanceof\r
                         value="org.netxms.client.objects.Node">\r
                   </instanceof>\r
index 206534f..5c7d3d5 100644 (file)
@@ -1,3 +1,21 @@
+/**\r
+ * NetXMS - open source network management system\r
+ * Copyright (C) 2003-2010 Victor Kirhenshtein\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
+ */\r
 package org.netxms.ui.eclipse.policymanager;\r
 \r
 import org.eclipse.ui.plugin.AbstractUIPlugin;\r
@@ -6,44 +24,55 @@ import org.osgi.framework.BundleContext;
 /**\r
  * The activator class controls the plug-in life cycle\r
  */\r
-public class Activator extends AbstractUIPlugin {\r
+public class Activator extends AbstractUIPlugin\r
+{\r
 \r
        // The plug-in ID\r
        public static final String PLUGIN_ID = "org.netxms.ui.eclipse.policymanager";\r
 \r
        // The shared instance\r
        private static Activator plugin;\r
-       \r
+\r
        /**\r
         * The constructor\r
         */\r
-       public Activator() {\r
+       public Activator()\r
+       {\r
        }\r
 \r
        /*\r
         * (non-Javadoc)\r
-        * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)\r
+        * \r
+        * @see\r
+        * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext\r
+        * )\r
         */\r
-       public void start(BundleContext context) throws Exception {\r
+       public void start(BundleContext context) throws Exception\r
+       {\r
                super.start(context);\r
                plugin = this;\r
        }\r
 \r
        /*\r
         * (non-Javadoc)\r
-        * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)\r
+        * \r
+        * @see\r
+        * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext\r
+        * )\r
         */\r
-       public void stop(BundleContext context) throws Exception {\r
+       public void stop(BundleContext context) throws Exception\r
+       {\r
                plugin = null;\r
                super.stop(context);\r
        }\r
 \r
        /**\r
         * Returns the shared instance\r
-        *\r
+        * \r
         * @return the shared instance\r
         */\r
-       public static Activator getDefault() {\r
+       public static Activator getDefault()\r
+       {\r
                return plugin;\r
        }\r
 \r
index 70c40da..b5a5672 100644 (file)
@@ -1,12 +1,26 @@
 /**\r
- * \r
+ * NetXMS - open source network management system\r
+ * Copyright (C) 2003-2010 Victor Kirhenshtein\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
  */\r
 package org.netxms.ui.eclipse.policymanager.propertypages;\r
 \r
 import org.eclipse.core.runtime.IProgressMonitor;\r
 import org.eclipse.core.runtime.IStatus;\r
 import org.eclipse.core.runtime.Status;\r
-import org.eclipse.core.runtime.jobs.Job;\r
 import org.eclipse.swt.SWT;\r
 import org.eclipse.swt.layout.GridData;\r
 import org.eclipse.swt.layout.GridLayout;\r
@@ -16,23 +30,21 @@ import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Text;\r
 import org.eclipse.ui.dialogs.PropertyPage;\r
 import org.eclipse.ui.progress.UIJob;\r
-import org.netxms.client.NXCException;\r
 import org.netxms.client.NXCObjectModificationData;\r
 import org.netxms.client.NXCSession;\r
 import org.netxms.client.objects.AgentPolicyConfig;\r
+import org.netxms.ui.eclipse.jobs.ConsoleJob;\r
 import org.netxms.ui.eclipse.policymanager.Activator;\r
 import org.netxms.ui.eclipse.shared.ConsoleSharedData;\r
 import org.netxms.ui.eclipse.tools.WidgetHelper;\r
 \r
 /**\r
- * @author Victor\r
+ * Property page for agent configuration policy\r
  *\r
  */\r
 public class ConfigFile extends PropertyPage\r
 {\r
-       private Text textName;\r
        private Text textContent;\r
-       private String initialName;\r
        private String initialContent;\r
        private AgentPolicyConfig object;\r
        \r
@@ -56,11 +68,6 @@ public class ConfigFile extends PropertyPage
                //FormLayout layout = new FormLayout();\r
       dialogArea.setLayout(layout);\r
       \r
-               // File name\r
-      initialName = new String(object.getFileName());\r
-      textName = WidgetHelper.createLabeledText(dialogArea, SWT.SINGLE | SWT.BORDER, SWT.DEFAULT, "File name",\r
-                                                   initialName, WidgetHelper.DEFAULT_LAYOUT_DATA);\r
-               \r
                // File content\r
       Label label = new Label(dialogArea, SWT.NONE);\r
       label.setText("File");\r
@@ -87,41 +94,29 @@ public class ConfigFile extends PropertyPage
         */\r
        protected void applyChanges(final boolean isApply)\r
        {\r
-               if (textName.getText().equals(initialName) &&\r
-                   textContent.getText().equals(initialContent))\r
+               if (textContent.getText().equals(initialContent))\r
                        return;         // Nothing to apply\r
                \r
                if (isApply)\r
                        setValid(false);\r
                \r
-               final String newName = new String(textName.getText());\r
                final String newContent = new String(textContent.getText());\r
-               new Job("Change policy") {\r
+               new ConsoleJob("Change policy", null, Activator.PLUGIN_ID, null) {\r
                        @Override\r
-                       protected IStatus run(IProgressMonitor monitor)\r
+                       protected void runInternal(IProgressMonitor monitor) throws Exception\r
                        {\r
-                               IStatus status;\r
-                               \r
-                               try\r
-                               {\r
-                                       if (object != null)\r
-                                       {\r
-                                               NXCObjectModificationData md = new NXCObjectModificationData(object.getObjectId());\r
-                                               md.setConfigFileName(newName);\r
-                                               md.setConfigFileContent(newContent);\r
-                                               ((NXCSession)ConsoleSharedData.getSession()).modifyObject(md);\r
-                                       }\r
-                                       initialName = newName;\r
-                                       initialContent = newContent;\r
-                                       status = Status.OK_STATUS;\r
-                               }\r
-                               catch(Exception e)\r
+                               if (object != null)\r
                                {\r
-                                       status = new Status(Status.ERROR, Activator.PLUGIN_ID, \r
-                                                           (e instanceof NXCException) ? ((NXCException)e).getErrorCode() : 0,\r
-                                                           "Cannot change agent policy: " + e.getMessage(), e);\r
+                                       NXCObjectModificationData md = new NXCObjectModificationData(object.getObjectId());\r
+                                       md.setConfigFileContent(newContent);\r
+                                       ((NXCSession)ConsoleSharedData.getSession()).modifyObject(md);\r
                                }\r
+                               initialContent = newContent;\r
+                       }\r
 \r
+                       @Override\r
+                       protected void jobFinalize()\r
+                       {\r
                                if (isApply)\r
                                {\r
                                        new UIJob("Update \"Configuration File\" property page") {\r
@@ -133,10 +128,14 @@ public class ConfigFile extends PropertyPage
                                                }\r
                                        }.schedule();\r
                                }\r
+                       }\r
 \r
-                               return status;\r
+                       @Override\r
+                       protected String getErrorMessage()\r
+                       {\r
+                               return "Cannot update agent policy";\r
                        }\r
-               }.schedule();\r
+               }.start();\r
        }\r
        \r
        /* (non-Javadoc)\r
index b1541a6..9efeff2 100644 (file)
@@ -1,5 +1,20 @@
 /**\r
- * \r
+ * NetXMS - open source network management system\r
+ * Copyright (C) 2003-2010 Victor Kirhenshtein\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
  */\r
 package org.netxms.ui.eclipse.policymanager.propertypages;\r
 \r
@@ -23,7 +38,7 @@ import org.netxms.ui.eclipse.shared.ConsoleSharedData;
 import org.netxms.ui.eclipse.tools.WidgetHelper;\r
 \r
 /**\r
- * @author Victor\r
+ * Generic agent policy properties\r
  *\r
  */\r
 public class Policy extends PropertyPage\r
@@ -32,7 +47,6 @@ public class Policy extends PropertyPage
        private String initialDescription;\r
        private AgentPolicy object;\r
        \r
-       \r
        /* (non-Javadoc)\r
         * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)\r
         */\r
index c57290c..95d0519 100644 (file)
@@ -94,6 +94,49 @@ ConfigEntry *ConfigEntry::findEntry(const TCHAR *name)
 
 
 //
+// Create (or find existing) subentry
+//
+
+ConfigEntry *ConfigEntry::createEntry(const TCHAR *name)
+{
+       ConfigEntry *e;
+
+       for(e = m_childs; e != NULL; e = e->getNext())
+               if (!_tcsicmp(e->getName(), name))
+                       return e;
+
+       return new ConfigEntry(name, this, _T("<memory>"), 0, 0);
+}
+
+
+//
+// Unlink subentry
+//
+
+void ConfigEntry::unlinkEntry(ConfigEntry *entry)
+{
+       ConfigEntry *curr, *prev;
+
+       for(curr = m_childs, prev = NULL; curr != NULL; curr = curr->m_next)
+       {
+               if (curr == entry)
+               {
+                       if (prev != NULL)
+                       {
+                               prev->m_next = curr->m_next;
+                       }
+                       else
+                       {
+                               m_childs = curr->m_next;
+                       }
+                       break;
+               }
+               prev = curr;
+       }
+}
+
+
+//
 // Get all subentries with names matched to mask
 //
 
@@ -177,6 +220,16 @@ bool ConfigEntry::getValueBoolean(int index, bool defaultValue)
        }
 }
 
+bool ConfigEntry::getValueUUID(int index, uuid_t uuid)
+{
+       const TCHAR *value = getValue(index);
+       if (value != NULL)
+       {
+               return uuid_parse(value, uuid) == 0;
+       }
+       return false;
+}
+
 
 //
 // Set value
@@ -272,6 +325,19 @@ bool ConfigEntry::getSubEntryValueBoolean(const TCHAR *name, int index, bool def
        }
 }
 
+bool ConfigEntry::getSubEntryValueUUID(const TCHAR *name, uuid_t uuid, int index)
+{
+       const TCHAR *value = getSubEntryValue(name, index);
+       if (value != NULL)
+       {
+               return uuid_parse(value, uuid) == 0;
+       }
+       else
+       {
+               return false;
+       }
+}
+
 
 //
 // Print config entry
@@ -355,6 +421,7 @@ Config::Config()
 {
        m_root = new ConfigEntry(_T("[root]"), NULL, NULL, 0, 0);
        m_errorCount = 0;
+       m_mutex = MutexCreate();
 }
 
 
@@ -365,6 +432,7 @@ Config::Config()
 Config::~Config()
 {
        delete m_root;
+       MutexDestroy(m_mutex);
 }
 
 
@@ -529,6 +597,19 @@ bool Config::getValueBoolean(const TCHAR *path, bool defaultValue)
        }
 }
 
+bool Config::getValueUUID(const TCHAR *path, uuid_t uuid)
+{
+       const TCHAR *value = getValue(path);
+       if (value != NULL)
+       {
+               return uuid_parse(value, uuid) == 0;
+       }
+       else
+       {
+               return false;
+       }
+}
+
 
 //
 // Get subentries
@@ -635,6 +716,25 @@ ConfigEntry *Config::createEntry(const TCHAR *path)
 
 
 //
+// Delete entry
+//
+
+void Config::deleteEntry(const TCHAR *path)
+{
+       ConfigEntry *entry = getEntry(path);
+       if (entry == NULL)
+               return;
+
+       ConfigEntry *parent = entry->getParent();
+       if (parent == NULL)     // root entry
+               return;
+
+       parent->unlinkEntry(entry);
+       delete entry;
+}
+
+
+//
 // Set value
 // Returns false on error (usually caused by incorrect path)
 //
@@ -683,6 +783,13 @@ bool Config::setValue(const TCHAR *path, double value)
        return setValue(path, buffer);
 }
 
+bool Config::setValue(const TCHAR *path, uuid_t value)
+{
+       TCHAR buffer[64];
+       uuid_to_string(value, buffer);
+       return setValue(path, buffer);
+}
+
 
 //
 // Find comment start in INI style config line
index cced669..4a2f15e 100644 (file)
@@ -147,11 +147,12 @@ void uuid_unpack(uuid_t in, struct uuid *uu)
 // Parse UUID
 //
 
-int LIBNETXMS_EXPORTABLE uuid_parse(TCHAR *in, uuid_t uu)
+int LIBNETXMS_EXPORTABLE uuid_parse(const TCHAR *in, uuid_t uu)
 {
        struct uuid uuid;
        int i;
-       TCHAR *cp, buf[3];
+       const TCHAR *cp;
+       TCHAR buf[3];
 
        if (_tcslen(in) != 36)
                return -1;
index 9ab4d41..a390cb9 100644 (file)
@@ -1,7 +1,6 @@
-/* $Id$ */
 /* 
 ** NetXMS - Network Management System
-** Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Victor Kirhenshtein
+** Copyright (C) 2003-2010 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
@@ -151,6 +150,22 @@ BOOL InitIdTable(void)
                                                    DBGetFieldULong(hResult, 0, 0) + 1);
       DBFreeResult(hResult);
    }
+   hResult = DBSelect(g_hCoreDB, "SELECT max(id) FROM ap_common");
+   if (hResult != NULL)
+   {
+      if (DBGetNumRows(hResult) > 0)
+         m_dwFreeIdTable[IDG_NETWORK_OBJECT] = max(m_dwFreeIdTable[IDG_NETWORK_OBJECT],
+                                                   DBGetFieldULong(hResult, 0, 0) + 1);
+      DBFreeResult(hResult);
+   }
+   hResult = DBSelect(g_hCoreDB, "SELECT max(id) FROM network_maps");
+   if (hResult != NULL)
+   {
+      if (DBGetNumRows(hResult) > 0)
+         m_dwFreeIdTable[IDG_NETWORK_OBJECT] = max(m_dwFreeIdTable[IDG_NETWORK_OBJECT],
+                                                   DBGetFieldULong(hResult, 0, 0) + 1);
+      DBFreeResult(hResult);
+   }
    hResult = DBSelect(g_hCoreDB, "SELECT max(object_id) FROM deleted_objects");
    if (hResult != NULL)
    {