Initial commit of libnetxms
authorVictor Kirhenshtein <victor@netxms.org>
Mon, 26 Apr 2004 12:31:21 +0000 (12:31 +0000)
committerVictor Kirhenshtein <victor@netxms.org>
Mon, 26 Apr 2004 12:31:21 +0000 (12:31 +0000)
.gitattributes
src/libnetxms/Makefile [new file with mode: 0644]
src/libnetxms/cscp.cpp [new file with mode: 0644]
src/libnetxms/inline.cpp [new file with mode: 0644]
src/libnetxms/libnetxms.dsp [new file with mode: 0644]
src/libnetxms/libnetxms.dsw [new file with mode: 0644]
src/libnetxms/libnetxms.h [new file with mode: 0644]
src/libnetxms/main.cpp [new file with mode: 0644]
src/libnetxms/queue.cpp [new file with mode: 0644]
src/libnetxms/tools.cpp [new file with mode: 0644]

index 7ee8571..6d22cae 100644 (file)
@@ -71,6 +71,15 @@ src/console/win32/res/login.bmp -text
 src/console/win32/res/nxcon.ico -text
 src/console/win32/res/nxcon.rc2 -text
 src/console/win32/resource.h -text
+src/libnetxms/Makefile -text
+src/libnetxms/cscp.cpp -text
+src/libnetxms/inline.cpp -text
+src/libnetxms/libnetxms.dsp -text
+src/libnetxms/libnetxms.dsw -text
+src/libnetxms/libnetxms.h -text
+src/libnetxms/main.cpp -text
+src/libnetxms/queue.cpp -text
+src/libnetxms/tools.cpp -text
 src/libnxcl/comm.cpp -text
 src/libnxcl/eventdb.cpp -text
 src/libnxcl/events.cpp -text
diff --git a/src/libnetxms/Makefile b/src/libnetxms/Makefile
new file mode 100644 (file)
index 0000000..3d31854
--- /dev/null
@@ -0,0 +1,18 @@
+SRC=cscp.cpp main.cpp queue.cpp tools.cpp
+OBJ=$(SRC:C/.cpp/.o/)
+DST=libnmsutil.a
+
+CFLAGS=-I../../include -Wall
+
+all: $(DST)
+
+$(DST): $(OBJ)
+       @rm -f $(DST)
+       @$(AR) q $(DST) $(OBJ)
+
+.SUFFIXES: .cpp .o
+.cpp.o: $(SRC)
+       $(CC) -c -o $@ $(CFLAGS) $<
+
+clean:
+       @rm -f $(OBJ) $(DST)
diff --git a/src/libnetxms/cscp.cpp b/src/libnetxms/cscp.cpp
new file mode 100644 (file)
index 0000000..bc03d05
--- /dev/null
@@ -0,0 +1,524 @@
+/* 
+** NetXMS - Network Management System
+** Utility Library
+** Copyright (C) 2003 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.
+**
+** $module: cscp.cpp
+**
+**/
+
+#include "libnetxms.h"
+
+
+//
+// Default constructor for CSCPMessage class
+//
+
+CSCPMessage::CSCPMessage()
+{
+   m_wCode = 0;
+   m_dwId = 0;
+   m_dwNumVar = 0;
+   m_ppVarList = NULL;
+}
+
+
+//
+// Create CSCPMessage object from received message
+//
+
+CSCPMessage::CSCPMessage(CSCP_MESSAGE *pMsg)
+{
+   WORD wPos, wSize;
+   CSCP_DF *pVar;
+   int iVarSize;
+
+   m_dwNumVar = 0;
+   m_ppVarList = NULL;
+
+   m_wCode = ntohs(pMsg->wCode);
+   m_dwId = ntohl(pMsg->dwId);
+   wSize = ntohs(pMsg->wSize);
+   
+   // Parse data fields
+   for(wPos = 8; wPos < wSize; wPos += iVarSize)
+   {
+      pVar = (CSCP_DF *)(((char *)pMsg) + wPos);
+
+      // Calculate variable size
+      switch(pVar->bType)
+      {
+         case DT_INTEGER:
+            iVarSize = 12;
+            break;
+         case DT_INT64:
+            iVarSize = 16;
+            break;
+         case DT_INT16:
+            iVarSize = 8;
+            break;
+         case DT_STRING:
+         case DT_BINARY:
+            iVarSize = ntohs(pVar->data.string.wLen) + 8;
+            break;
+      }
+
+      // Create new entry
+      m_ppVarList = (CSCP_DF **)MemReAlloc(m_ppVarList, sizeof(CSCP_DF *) * (m_dwNumVar + 1));
+      m_ppVarList[m_dwNumVar] = (CSCP_DF *)MemAlloc(iVarSize);
+      memcpy(m_ppVarList[m_dwNumVar], pVar, iVarSize);
+
+      // Convert numeric values to host format
+      m_ppVarList[m_dwNumVar]->dwVarId = ntohl(m_ppVarList[m_dwNumVar]->dwVarId);
+      switch(pVar->bType)
+      {
+         case DT_INTEGER:
+            m_ppVarList[m_dwNumVar]->data.integer.dwInteger = ntohl(m_ppVarList[m_dwNumVar]->data.integer.dwInteger);
+            break;
+         case DT_INT64:
+            m_ppVarList[m_dwNumVar]->data.int64.qwInt64 = ntohq(m_ppVarList[m_dwNumVar]->data.int64.qwInt64);
+            break;
+         case DT_INT16:
+            m_ppVarList[m_dwNumVar]->data.wInt16 = ntohs(m_ppVarList[m_dwNumVar]->data.wInt16);
+            break;
+         case DT_STRING:
+         case DT_BINARY:
+            m_ppVarList[m_dwNumVar]->data.string.wLen = ntohs(m_ppVarList[m_dwNumVar]->data.string.wLen);
+            break;
+      }
+      
+      m_dwNumVar++;
+   }
+}
+
+
+//
+// Destructor for CSCPMessage
+//
+
+CSCPMessage::~CSCPMessage()
+{
+   DeleteAllVariables();
+}
+
+
+//
+// Find variable by name
+//
+
+DWORD CSCPMessage::FindVariable(DWORD dwVarId)
+{
+   DWORD i;
+
+   for(i = 0; i < m_dwNumVar; i++)
+      if (m_ppVarList[i]->dwVarId == dwVarId)
+         return i;
+   return INVALID_INDEX;
+}
+
+
+//
+// Set variable
+// Argument dwSize (data size) is used only for DT_BINARY type
+//
+
+void CSCPMessage::Set(DWORD dwVarId, BYTE bType, void *pValue, DWORD dwSize)
+{
+   DWORD dwIndex;
+   CSCP_DF *pVar;
+
+   // Create CSCP_DF structure
+   switch(bType)
+   {
+      case DT_INTEGER:
+         pVar = (CSCP_DF *)MemAlloc(12);
+         pVar->data.integer.dwInteger = *((DWORD *)pValue);
+         break;
+      case DT_INT16:
+         pVar = (CSCP_DF *)MemAlloc(8);
+         pVar->data.wInt16 = *((WORD *)pValue);
+         break;
+      case DT_INT64:
+         pVar = (CSCP_DF *)MemAlloc(16);
+         pVar->data.int64.qwInt64 = *((QWORD *)pValue);
+         break;
+      case DT_STRING:
+         pVar = (CSCP_DF *)MemAlloc(8 + strlen((char *)pValue));
+         pVar->data.string.wLen = (WORD)strlen((char *)pValue);
+         memcpy(pVar->data.string.szValue, pValue, pVar->data.string.wLen);
+         break;
+      case DT_BINARY:
+         pVar = (CSCP_DF *)MemAlloc(8 + dwSize);
+         pVar->data.string.wLen = (WORD)dwSize;
+         memcpy(pVar->data.string.szValue, pValue, pVar->data.string.wLen);
+         break;
+      default:
+         return;  // Invalid data type, unable to handle
+   }
+   pVar->dwVarId = dwVarId;
+   pVar->bType = bType;
+
+   // Check if variable exists
+   dwIndex = FindVariable(pVar->dwVarId);
+   if (dwIndex == INVALID_INDEX) // Add new variable to list
+   {
+      m_ppVarList = (CSCP_DF **)MemReAlloc(m_ppVarList, sizeof(CSCP_DF *) * (m_dwNumVar + 1));
+      m_ppVarList[m_dwNumVar] = pVar;
+      m_dwNumVar++;
+   }
+   else  // Replace existing variable
+   {
+      MemFree(m_ppVarList[dwIndex]);
+      m_ppVarList[dwIndex] = pVar;
+   }
+}
+
+
+//
+// Get variable value
+//
+
+void *CSCPMessage::Get(DWORD dwVarId, BYTE bType)
+{
+   DWORD dwIndex;
+   void *pData;
+
+   // Find variable
+   dwIndex = FindVariable(dwVarId);
+   if (dwIndex == INVALID_INDEX)
+      return NULL;      // No such variable
+
+   // Check data type
+   if (m_ppVarList[dwIndex]->bType != bType)
+      return NULL;
+
+   if ((bType == DT_INTEGER) || (bType == DT_INT64))
+      pData = (void *)((char *)(&m_ppVarList[dwIndex]->data) + 2);
+   else
+      pData = &m_ppVarList[dwIndex]->data;
+
+   return pData;
+}
+
+
+//
+// Get integer variable
+//
+
+DWORD CSCPMessage::GetVariableLong(DWORD dwVarId)
+{
+   char *pValue;
+
+   pValue = (char *)Get(dwVarId, DT_INTEGER);
+   return pValue ? *((DWORD *)pValue) : 0;
+}
+
+
+//
+// Get 16-bit integer variable
+//
+
+WORD CSCPMessage::GetVariableShort(DWORD dwVarId)
+{
+   void *pValue;
+
+   pValue = Get(dwVarId, DT_INT16);
+   return pValue ? *((WORD *)pValue) : 0;
+}
+
+
+//
+// Get 64-bit integer variable
+//
+
+QWORD CSCPMessage::GetVariableInt64(DWORD dwVarId)
+{
+   char *pValue;
+
+   pValue = (char *)Get(dwVarId, DT_INT64);
+   return pValue ? *((QWORD *)pValue) : 0;
+}
+
+
+//
+// Get string variable
+// If szBuffer is NULL, memory block of required size will be allocated
+// for result; if szBuffer is not NULL, entire result or part of it will
+// be placed to szBuffer and pointer to szBuffer will be returned.
+//
+
+char *CSCPMessage::GetVariableStr(DWORD dwVarId, char *szBuffer, DWORD dwBufSize)
+{
+   void *pValue;
+   char *pStr = NULL;
+   int iLen;
+
+   if ((szBuffer != NULL) && (dwBufSize == 0))
+      return NULL;   // non-sense combination
+
+   pValue = Get(dwVarId, DT_STRING);
+   if (pValue != NULL)
+   {
+      if (szBuffer == NULL)
+         pStr = (char *)MemAlloc(*((WORD *)pValue) + 1);
+      else
+         pStr = szBuffer;
+      iLen = (szBuffer == NULL) ? *((WORD *)pValue) : min(*((WORD *)pValue), dwBufSize - 1);
+      memcpy(pStr, (char *)pValue + 2, iLen);
+      pStr[iLen] = 0;
+   }
+   else
+   {
+      if (szBuffer != NULL)
+      {
+         pStr = szBuffer;
+         pStr[0] = 0;
+      }
+   }
+   return pStr;
+}
+
+
+//
+// Get binary (byte array) variable
+// Result will be placed to the buffer provided (no more than dwBufSize bytes,
+// and actual size of data will be returned
+// If pBuffer is NULL, just actual data length is returned
+//
+
+DWORD CSCPMessage::GetVariableBinary(DWORD dwVarId, BYTE *pBuffer, DWORD dwBufSize)
+{
+   void *pValue;
+   DWORD dwSize;
+
+   pValue = Get(dwVarId, DT_BINARY);
+   if (pValue != NULL)
+   {
+      dwSize = *((WORD *)pValue);
+      if (pBuffer != NULL)
+         memcpy(pBuffer, (BYTE *)pValue + 2, min(dwBufSize, dwSize));
+   }
+   else
+   {
+      dwSize = 0;
+   }
+   return dwSize;
+}
+
+
+//
+// Build protocol message ready to be send over the wire
+//
+
+CSCP_MESSAGE *CSCPMessage::CreateMessage(void)
+{
+   WORD wSize;
+   int iVarSize;
+   DWORD i;
+   CSCP_MESSAGE *pMsg;
+   CSCP_DF *pVar;
+
+   // Calculate message size
+   for(i = 0, wSize = 8; i < m_dwNumVar; i++)
+      switch(m_ppVarList[i]->bType)
+      {
+         case DT_INTEGER:
+            wSize += 12;
+            break;
+         case DT_INT64:
+            wSize += 16;
+            break;
+         case DT_INT16:
+            wSize += 8;
+            break;
+         case DT_STRING:
+         case DT_BINARY:
+            wSize += m_ppVarList[i]->data.string.wLen + 8;
+            break;
+      }
+
+   // Create message
+   pMsg = (CSCP_MESSAGE *)MemAlloc(wSize);
+   pMsg->wCode = htons(m_wCode);
+   pMsg->wSize = htons(wSize);
+   pMsg->dwId = htonl(m_dwId);
+
+   // Fill data fields
+   for(i = 0, pVar = (CSCP_DF *)((char *)pMsg + 8); i < m_dwNumVar; i++)
+   {
+      // Calculate variable size
+      switch(m_ppVarList[i]->bType)
+      {
+         case DT_INTEGER:
+            iVarSize = 12;
+            break;
+         case DT_INT64:
+            iVarSize = 16;
+            break;
+         case DT_INT16:
+            iVarSize = 8;
+            break;
+         case DT_STRING:
+         case DT_BINARY:
+            iVarSize = m_ppVarList[i]->data.string.wLen + 8;
+            break;
+      }
+
+      memcpy(pVar, m_ppVarList[i], iVarSize);
+
+      // Convert numeric values to network format
+      pVar->dwVarId = htonl(pVar->dwVarId);
+      switch(pVar->bType)
+      {
+         case DT_INTEGER:
+            pVar->data.integer.dwInteger = htonl(pVar->data.integer.dwInteger);
+            break;
+         case DT_INT64:
+            pVar->data.int64.qwInt64 = htonq(pVar->data.int64.qwInt64);
+            break;
+         case DT_INT16:
+            pVar->data.wInt16 = htons(pVar->data.wInt16);
+            break;
+         case DT_STRING:
+         case DT_BINARY:
+            pVar->data.string.wLen = htons(pVar->data.string.wLen);
+            break;
+      }
+
+      pVar = (CSCP_DF *)((char *)pVar + iVarSize);
+   }
+
+   return pMsg;
+}
+
+
+//
+// Delete all variables
+//
+
+void CSCPMessage::DeleteAllVariables(void)
+{
+   if (m_ppVarList != NULL)
+   {
+      DWORD i;
+
+      for(i = 0; i < m_dwNumVar; i++)
+         MemFree(m_ppVarList[i]);
+      MemFree(m_ppVarList);
+
+      m_ppVarList = NULL;
+      m_dwNumVar = 0;
+   }
+}
+
+
+//
+// Receive raw CSCP message from network
+// If pMsg is NULL, temporary buffer will be re-initialized
+//
+
+int LIBNETXMS_EXPORTABLE RecvCSCPMessage(SOCKET hSocket, CSCP_MESSAGE *pMsg, CSCP_BUFFER *pBuffer)
+{
+   DWORD dwMsgSize = 0, dwBytesRead = 0, dwBytesToCopy;
+   int iErr;
+
+   // Initialize buffer if requested
+   if (pMsg == NULL)
+   {
+      pBuffer->dwBufSize = 0;
+      pBuffer->dwBufPos = 0;
+      return 0;
+   }
+
+   // Check if we have something in buffer
+   if (pBuffer->dwBufSize > 0)
+   {
+      // Handle the case when entire message header have not been read into the buffer
+      if (pBuffer->dwBufSize < 8)
+      {
+         // Most likely we are at the buffer end, so move content
+         // to the beginning
+         memmove(pBuffer->szBuffer, &pBuffer->szBuffer[pBuffer->dwBufPos], pBuffer->dwBufSize);
+         pBuffer->dwBufPos = 0;
+
+         // Receive new portion of data from the network 
+         // and append it to existing data in buffer
+         iErr = recv(hSocket, &pBuffer->szBuffer[pBuffer->dwBufSize], CSCP_TEMP_BUF_SIZE - pBuffer->dwBufSize, 0);
+         if (iErr <= 0)
+            return iErr;
+         pBuffer->dwBufSize += (DWORD)iErr;
+      }
+
+      // Get message size from message header and copy available 
+      // message bytes from buffer
+      dwMsgSize = (DWORD)ntohs(((CSCP_MESSAGE *)(&pBuffer->szBuffer[pBuffer->dwBufPos]))->wSize);
+      dwBytesRead = min(dwMsgSize, pBuffer->dwBufSize);
+      memcpy(pMsg, &pBuffer->szBuffer[pBuffer->dwBufPos], dwBytesRead);
+      pBuffer->dwBufSize -= dwBytesRead;
+      pBuffer->dwBufPos = (pBuffer->dwBufSize > 0) ? (pBuffer->dwBufPos + dwBytesRead) : 0;
+      if (dwBytesRead == dwMsgSize)
+         return (int)dwBytesRead;   // We have read entire message
+   }
+
+   // Receive rest of message from the network
+   do
+   {
+      iErr = recv(hSocket, pBuffer->szBuffer, CSCP_TEMP_BUF_SIZE, 0);
+      if (iErr <= 0)
+         return iErr;
+
+      if (dwBytesRead == 0)   // New message?
+         dwMsgSize = (DWORD)ntohs(((CSCP_MESSAGE *)(pBuffer->szBuffer))->wSize);
+      dwBytesToCopy = min((DWORD)iErr, dwMsgSize - dwBytesRead);
+      memcpy(((char *)pMsg) + dwBytesRead, pBuffer->szBuffer, dwBytesToCopy);
+      dwBytesRead += dwBytesToCopy;
+   }
+   while(dwBytesRead < dwMsgSize);
+   
+   // Check if we have something left in buffer
+   if (dwBytesToCopy < (DWORD)iErr)
+   {
+      pBuffer->dwBufPos = dwBytesToCopy;
+      pBuffer->dwBufSize = (DWORD)iErr - dwBytesToCopy;
+   }
+
+   return (int)dwMsgSize;
+}
+
+
+//
+// Create CSCP message with raw data (MF_BINARY flag)
+// If pBuffer is NULL, new buffer is allocated with MemAlloc()
+// Buffer should be of dwDataSize + 16 bytes.
+//
+
+CSCP_MESSAGE LIBNETXMS_EXPORTABLE *CreateRawCSCPMessage(WORD wCode, DWORD dwId, DWORD dwDataSize, void *pData, CSCP_MESSAGE *pBuffer)
+{
+   CSCP_MESSAGE *pMsg;
+
+   if (pBuffer == NULL)
+      pMsg = (CSCP_MESSAGE *)MemAlloc(dwDataSize + 16);
+   else
+      pMsg = pBuffer;
+
+   pMsg->wCode = htons(wCode | MF_BINARY);
+   pMsg->dwId = htonl(dwId);
+   pMsg->wSize = htons((WORD)dwDataSize + 8);
+   memcpy(pMsg->df, pData, dwDataSize);
+
+   return pMsg;
+}
diff --git a/src/libnetxms/inline.cpp b/src/libnetxms/inline.cpp
new file mode 100644 (file)
index 0000000..714d444
--- /dev/null
@@ -0,0 +1,69 @@
+/* 
+** libnetxms - Common NetXMS utility library
+** Copyright (C) 2003, 2004 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.
+**
+** $module: inline.cpp
+**
+**/
+
+#define LIBNETXMS_INLINE
+#include "libnetxms.h"
+
+
+//
+// Functions defined as inline for C++ programs
+//
+
+extern "C" void LIBNETXMS_EXPORTABLE ret_string(char *rbuf, char *value)
+{
+   memset(rbuf, 0, MAX_RESULT_LENGTH);
+   strncpy(rbuf, value, MAX_RESULT_LENGTH - 3);
+   strcat(rbuf, "\r\n");
+}
+
+extern "C" void LIBNETXMS_EXPORTABLE ret_int(char *rbuf, long value)
+{
+   sprintf(rbuf, "%ld\r\n", value);
+}
+
+extern "C" void LIBNETXMS_EXPORTABLE ret_uint(char *rbuf, unsigned long value)
+{
+   sprintf(rbuf, "%lu\r\n", value);
+}
+
+extern "C" void LIBNETXMS_EXPORTABLE ret_double(char *rbuf, double value)
+{
+   sprintf(rbuf, "%f\r\n", value);
+}
+
+extern "C" void LIBNETXMS_EXPORTABLE ret_int64(char *rbuf, INT64 value)
+{
+#ifdef _WIN32
+   sprintf(rbuf, "%I64d\r\n", value);
+#else    /* _WIN32 */
+   sprintf(rbuf, "%lld\r\n", value);
+#endif   /* _WIN32 */
+}
+
+extern "C" void LIBNETXMS_EXPORTABLE ret_uint64(char *rbuf, QWORD value)
+{
+#ifdef _WIN32
+   sprintf(rbuf, "%I64u\r\n", value);
+#else    /* _WIN32 */
+   sprintf(rbuf, "%llu\r\n", value);
+#endif   /* _WIN32 */
+}
diff --git a/src/libnetxms/libnetxms.dsp b/src/libnetxms/libnetxms.dsp
new file mode 100644 (file)
index 0000000..5dddbc0
--- /dev/null
@@ -0,0 +1,144 @@
+# Microsoft Developer Studio Project File - Name="libnetxms" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=libnetxms - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "libnetxms.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "libnetxms.mak" CFG="libnetxms - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "libnetxms - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "libnetxms - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "libnetxms - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBNETXMS_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBNETXMS_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x809 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib /nologo /dll /machine:I386
+
+!ELSEIF  "$(CFG)" == "libnetxms - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBNETXMS_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBNETXMS_EXPORTS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# Begin Special Build Tool
+SOURCE="$(InputPath)"
+PostBuild_Desc=Copy files
+PostBuild_Cmds=copy Debug\libnetxms.dll ..\..\bin
+# End Special Build Tool
+
+!ENDIF 
+
+# Begin Target
+
+# Name "libnetxms - Win32 Release"
+# Name "libnetxms - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\cscp.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\inline.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\main.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\queue.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\tools.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\libnetxms.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\nms_agent.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\nms_common.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\nms_util.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/src/libnetxms/libnetxms.dsw b/src/libnetxms/libnetxms.dsw
new file mode 100644 (file)
index 0000000..bdcf8cb
--- /dev/null
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "libnetxms"=.\libnetxms.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/src/libnetxms/libnetxms.h b/src/libnetxms/libnetxms.h
new file mode 100644 (file)
index 0000000..2b92633
--- /dev/null
@@ -0,0 +1,42 @@
+/* 
+** NetXMS - Network Management System
+** Utility Library
+** Copyright (C) 2003, 2004 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.
+**
+** $module: libnetxms.h
+**
+**/
+
+#ifndef _libnetxms_h_
+#define _libnetxms_h_
+
+#include <stdio.h>
+#include <openssl/ssl.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#else    /* _WIN32 */
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#endif   /* _WIN32 */
+
+#include <nms_common.h>
+#include <nms_util.h>
+#include <nms_agent.h>
+
+#endif   /* _libnetxms_h_ */
diff --git a/src/libnetxms/main.cpp b/src/libnetxms/main.cpp
new file mode 100644 (file)
index 0000000..6e0a4c6
--- /dev/null
@@ -0,0 +1,85 @@
+/* 
+** NetXMS - Network Management System
+** Utility Library
+** Copyright (C) 2003 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.
+**
+** $module: main.cpp
+**
+**/
+
+#include "libnetxms.h"
+
+
+//
+// Swap byte order in 64-bit integer
+//
+
+#ifdef _WIN32
+
+QWORD LIBNETXMS_EXPORTABLE __bswap_64(QWORD qwVal)
+{
+   QWORD qwResult;
+   BYTE *sptr = (BYTE *)&qwVal;
+   BYTE *dptr = (BYTE *)&qwResult + 7;
+   int i;
+
+   for(i = 0; i < 8; i++, sptr++, dptr--)
+      *dptr = *sptr;
+
+   return qwResult;
+}
+
+#endif
+
+
+//
+// strupr() implementation for non-windows platforms
+//
+
+#ifndef _WIN32
+
+void LIBNETXMS_EXPORTABLE strupr(char *in)
+{
+       char *p = in;
+
+       if (in == NULL) 
+   { 
+               return;
+       }
+       
+       for (; *p != 0; p++) 
+   {
+               // TODO: check/set locale
+               *p = toupper(*p);
+       }
+}
+
+#endif
+
+
+//
+// DLL entry point
+//
+
+#ifdef _WIN32
+
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
+{
+   return TRUE;
+}
+
+#endif   /* _WIN32 */
diff --git a/src/libnetxms/queue.cpp b/src/libnetxms/queue.cpp
new file mode 100644 (file)
index 0000000..e18efe8
--- /dev/null
@@ -0,0 +1,120 @@
+/* 
+** Project X - Network Management System
+** Copyright (C) 2003 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.
+**
+** $module: queue.cpp
+**
+**/
+
+#include "libnetxms.h"
+
+
+//
+// Queue constructor
+//
+
+Queue::Queue(DWORD dwInitialSize, DWORD dwBufferIncrement)
+{
+   m_hQueueAccess = MutexCreate();
+   m_hConditionNotEmpty = ConditionCreate();
+   m_dwNumElements = 0;
+   m_dwFirst = 0;
+   m_dwLast = 0;
+   m_dwBufferSize = dwInitialSize;
+   m_dwBufferIncrement = dwBufferIncrement;
+   m_pElements = (void **)MemAlloc(sizeof(void *) * m_dwBufferSize);
+}
+
+
+//
+// Destructor
+//
+
+Queue::~Queue()
+{
+   MutexDestroy(m_hQueueAccess);
+   ConditionDestroy(m_hConditionNotEmpty);
+   MemFree(m_pElements);
+}
+
+
+//
+// Put new element into queue
+//
+
+void Queue::Put(void *pElement)
+{
+   Lock();
+   if (m_dwNumElements == m_dwBufferSize)
+   {
+      // Extend buffer
+      m_dwBufferSize += m_dwBufferIncrement;
+      m_pElements = (void **)MemReAlloc(m_pElements, sizeof(void *) * m_dwBufferSize);
+      
+      // Move free space
+      memmove(&m_pElements[m_dwFirst + m_dwBufferIncrement], &m_pElements[m_dwFirst],
+              sizeof(void *) * (m_dwBufferSize - m_dwFirst - m_dwBufferIncrement));
+      m_dwFirst += m_dwBufferIncrement;
+   }
+   m_pElements[m_dwLast++] = pElement;
+   if (m_dwLast == m_dwBufferSize)
+      m_dwLast = 0;
+   m_dwNumElements++;
+   ConditionSet(m_hConditionNotEmpty);
+   Unlock();
+}
+
+
+//
+// Get object from queue. Return NULL if queue is empty
+//
+
+void *Queue::Get(void)
+{
+   void *pElement = NULL;
+
+   Lock();
+   if (m_dwNumElements != 0)
+   {
+      pElement = m_pElements[m_dwFirst++];
+      if (m_dwFirst == m_dwBufferSize)
+         m_dwFirst = 0;
+      m_dwNumElements--;
+   }
+   Unlock();
+   return pElement;
+}
+
+
+//
+// Get object from queue or block if queue if empty
+//
+
+void *Queue::GetOrBlock(void)
+{
+   void *pElement;
+
+   pElement = Get();
+   if (pElement != NULL)
+      return pElement;
+   do
+   {
+      ConditionWait(m_hConditionNotEmpty, INFINITE);
+      pElement = Get();
+   } while(pElement == NULL);
+   return pElement;
+}
diff --git a/src/libnetxms/tools.cpp b/src/libnetxms/tools.cpp
new file mode 100644 (file)
index 0000000..cb2646b
--- /dev/null
@@ -0,0 +1,322 @@
+/* 
+** Project X - Network Management System
+** Copyright (C) 2003 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.
+**
+** $module: tools.cpp
+**
+**/
+
+#include "libnetxms.h"
+
+
+//
+// Calculate number of bits in netmask
+//
+
+int LIBNETXMS_EXPORTABLE BitsInMask(DWORD dwMask)
+{
+   int bits;
+   DWORD dwTemp;
+
+   for(bits = 0, dwTemp = ntohl(dwMask); dwTemp != 0; bits++, dwTemp <<= 1);
+   return bits;
+}
+
+
+//
+// Convert IP address from binary form (network bytes order) to string
+//
+
+char LIBNETXMS_EXPORTABLE *IpToStr(DWORD dwAddr, char *szBuffer)
+{
+   static char szInternalBuffer[32];
+   char *szBufPtr;
+
+   szBufPtr = szBuffer == NULL ? szInternalBuffer : szBuffer;
+   sprintf(szBufPtr, "%ld.%ld.%ld.%ld", dwAddr & 255, (dwAddr >> 8) & 255,
+           (dwAddr >> 16) & 255, dwAddr >> 24);
+   return szBufPtr;
+}
+
+
+//
+// Our memory allocation wrappers
+// We need them primary because of Windows CLIB behavior:
+// every module has it's own memory block list, so if memory block
+// was allocated in DLL by malloc(), call to free() for this block in
+// main program will cause crash.
+//
+
+void LIBNETXMS_EXPORTABLE *MemAlloc(DWORD dwSize)
+{
+   return malloc(dwSize);
+}
+
+void LIBNETXMS_EXPORTABLE *MemReAlloc(void *pBlock, DWORD dwNewSize)
+{
+   return realloc(pBlock, dwNewSize);
+}
+
+void LIBNETXMS_EXPORTABLE MemFree(void *pBlock)
+{
+   if (pBlock != NULL)
+      free(pBlock);
+}
+
+
+//
+// Duplicate memory block
+//
+
+void LIBNETXMS_EXPORTABLE *nx_memdup(const void *pData, DWORD dwSize)
+{
+   void *pNewData;
+
+   pNewData = MemAlloc(dwSize);
+   memcpy(pNewData, pData, dwSize);
+   return pNewData;
+}
+
+
+//
+// Duplicate string using MemAlloc()
+//
+
+char LIBNETXMS_EXPORTABLE *nx_strdup(const char *pSrc)
+{
+   char *pDest;
+
+   pDest = (char *)MemAlloc(strlen(pSrc) + 1);
+   strcpy(pDest, pSrc);
+   return pDest;
+}
+
+
+//
+// Match string against pattern with * and ? metasymbols
+//
+
+static BOOL MatchStringEngine(const char *pattern, const char *string)
+{
+   const char *SPtr,*MPtr,*BPtr;
+
+   SPtr = string;
+   MPtr = pattern;
+
+   while(*MPtr!=0)
+   {
+      switch(*MPtr)
+      {
+         case '?':
+            if (*SPtr!=0)
+            {
+               SPtr++;
+               MPtr++;
+            }
+            else
+               return FALSE;
+            break;
+         case '*':
+            while(*MPtr=='*')
+               MPtr++;
+            if (*MPtr==0)
+                   return TRUE;
+            if (*MPtr=='?')      // Handle "*?" case
+            {
+               if (*SPtr!=0)
+                  SPtr++;
+               else
+                  return FALSE;
+               break;
+            }
+            BPtr=MPtr;           // Text block begins here
+            while((*MPtr!=0)&&(*MPtr!='?')&&(*MPtr!='*'))
+               MPtr++;     // Find the end of text block
+            while(1)
+            {
+               while((*SPtr!=0)&&(*SPtr!=*BPtr))
+                  SPtr++;
+               if (strlen(SPtr)<(size_t)(MPtr-BPtr))
+                  return FALSE;  // Length of remained text less than remaining pattern
+               if (!memcmp(BPtr,SPtr,MPtr-BPtr))
+                  break;
+               SPtr++;
+            }
+            SPtr+=(MPtr-BPtr);   // Increment SPtr because we alredy match current fragment
+            break;
+         default:
+            if (*MPtr==*SPtr)
+            {
+               SPtr++;
+               MPtr++;
+            }
+            else
+               return FALSE;
+            break;
+      }
+   }
+
+   return *SPtr==0 ? TRUE : FALSE;
+}
+
+BOOL LIBNETXMS_EXPORTABLE NxMatchString(const char *pattern, const char *string, BOOL matchCase)
+{
+   if (matchCase)
+      return MatchStringEngine(pattern, string);
+   else
+   {
+      char *tp, *ts;
+      BOOL bResult;
+
+      tp = strdup(pattern);
+      ts = strdup(string);
+      strupr(tp);
+      strupr(ts);
+      bResult = MatchStringEngine(tp, ts);
+      free(tp);
+      free(ts);
+      return bResult;
+   }
+}
+
+
+//
+// Strip whitespaces and tabs off the string
+//
+
+void LIBNETXMS_EXPORTABLE NxStrStrip(char *str)
+{
+   int i;
+
+   for(i=0;(str[i]!=0)&&((str[i]==' ')||(str[i]=='\t'));i++);
+   if (i>0)
+      memmove(str,&str[i],strlen(&str[i])+1);
+   for(i=strlen(str)-1;(i>=0)&&((str[i]==' ')||(str[i]=='\t'));i--);
+   str[i+1]=0;
+}
+
+
+//
+// Get arguments for parameters like name(arg1,...)
+// Returns FALSE on processing error
+//
+
+BOOL LIBNETXMS_EXPORTABLE NxGetParameterArg(char *param, int index, char *arg, int maxSize)
+{
+   char *ptr1, *ptr2;
+   int state, currIndex, pos;
+   BOOL bResult = TRUE;
+
+   arg[0] = 0;    // Default is empty string
+   ptr1 = strchr(param,'(');
+   if (ptr1 == NULL)
+      return TRUE;  // No arguments at all
+   for(ptr2 = ptr1 + 1, currIndex = 1, state = 0, pos = 0; state != -1; ptr2++)
+   {
+      switch(state)
+      {
+         case 0:  // Normal
+            switch(*ptr2)
+            {
+               case ')':
+                  if (currIndex == index)
+                     arg[pos] = 0;
+                  state = -1;    // Finish processing
+                  break;
+               case '"':
+                  state = 1;     // String
+                  break;
+               case '\'':        // String, type 2
+                  state = 2;
+                  break;
+               case ',':
+                  if (currIndex == index)
+                  {
+                     arg[pos] = 0;
+                     state = -1;
+                  }
+                  else
+                  {
+                     currIndex++;
+                  }
+                  break;
+               case 0:
+                  state = -1;       // Finish processing
+                  bResult = FALSE;  // Set error flag
+                  break;
+               default:
+                  if ((currIndex == index) && (pos < maxSize - 1))
+                     arg[pos++] = *ptr2;
+            }
+            break;
+         case 1:  // String in ""
+            switch(*ptr2)
+            {
+               case '"':
+                  state = 0;     // Normal
+                  break;
+               case '\\':        // Escape
+                  ptr2++;
+                  if ((currIndex == index) && (pos < maxSize - 1))
+                     arg[pos++] = *ptr2;
+                  if (ptr2 == 0)    // Unexpected EOL
+                  {
+                     bResult = FALSE;
+                     state = -1;
+                  }
+                  break;
+               case 0:
+                  state = -1;    // Finish processing
+                  bResult = FALSE;  // Set error flag
+                  break;
+               default:
+                  if ((currIndex == index) && (pos < maxSize - 1))
+                     arg[pos++] = *ptr2;
+            }
+            break;
+         case 2:  // String in ''
+            switch(*ptr2)
+            {
+               case '\'':
+                  state = 0;     // Normal
+                  break;
+               case '\\':        // Escape
+                  ptr2++;
+                  if ((currIndex == index) && (pos < maxSize - 1))
+                     arg[pos++] = *ptr2;
+                  if (ptr2 == 0)    // Unexpected EOL
+                  {
+                     bResult = FALSE;
+                     state = -1;
+                  }
+                  break;
+               case 0:
+                  state = -1;    // Finish processing
+                  bResult = FALSE;  // Set error flag
+                  break;
+               default:
+                  if ((currIndex == index) && (pos < maxSize - 1))
+                     arg[pos++] = *ptr2;
+            }
+            break;
+      }
+   }
+
+   if (bResult)
+      NxStrStrip(arg);
+   return bResult;
+}