- Improved sending of logs from server to client
authorVictor Kirhenshtein <victor@netxms.org>
Sun, 5 Mar 2006 15:42:04 +0000 (15:42 +0000)
committerVictor Kirhenshtein <victor@netxms.org>
Sun, 5 Mar 2006 15:42:04 +0000 (15:42 +0000)
- Trap logs almost implemented
- Console wait view improved
- Many small fixes and improvements

39 files changed:
.gitattributes
doc/internal/db_format_change.txt
include/netxmsdb.h
include/nms_cscp.h
include/nxclapi.h
include/nxcscpapi.h
sql/schema.in
src/console/win32/EventBrowser.cpp
src/console/win32/EventBrowser.h
src/console/win32/Makefile.am
src/console/win32/SyslogBrowser.cpp
src/console/win32/SyslogBrowser.h
src/console/win32/TableView.cpp
src/console/win32/ToolBox.cpp
src/console/win32/TrapLogBrowser.cpp [new file with mode: 0644]
src/console/win32/TrapLogBrowser.h [copied from src/console/win32/EventBrowser.h with 55% similarity]
src/console/win32/WaitView.cpp
src/console/win32/WaitView.h
src/console/win32/globals.h
src/console/win32/nxcon.clw
src/console/win32/nxcon.cpp
src/console/win32/nxcon.dsp
src/console/win32/nxcon.h
src/console/win32/nxcon.rc
src/console/win32/resource.h
src/libnxcl/comm.cpp
src/libnxcl/eventdb.cpp
src/libnxcl/events.cpp
src/libnxcl/libnxcl.h
src/libnxcl/objects.cpp
src/libnxcl/session.cpp
src/libnxcl/snmptrap.cpp
src/server/core/debug.cpp
src/server/core/main.cpp
src/server/core/poll.cpp
src/server/core/session.cpp
src/server/core/snmptrap.cpp
src/server/include/nms_core.h
src/server/tools/nxdbmgr/upgrade.cpp

index 964666c..ee3d613 100644 (file)
@@ -701,6 +701,8 @@ src/console/win32/TrapEditDlg.cpp -text
 src/console/win32/TrapEditDlg.h -text
 src/console/win32/TrapEditor.cpp -text
 src/console/win32/TrapEditor.h -text
+src/console/win32/TrapLogBrowser.cpp -text
+src/console/win32/TrapLogBrowser.h -text
 src/console/win32/TrapParamDlg.cpp -text
 src/console/win32/TrapParamDlg.h -text
 src/console/win32/UserEditor.cpp -text
index 5160898..97ef445 100644 (file)
@@ -1,4 +1,26 @@
 *************
+* 37 ==> 38 *
+*************
+
+- Added table "snmp_trap_log":
+       CREATE TABLE snmp_trap_log
+       (
+               trap_id SQL_INT64 not null,
+               trap_timestamp integer not null,
+               ip_addr varchar(15) not null,
+               object_id integer not null,
+               trap_oid varchar(255) not null,
+               trap_varlist SQL_TEXT not null,
+               PRIMARY KEY(trap_id)
+       ) TABLE_TYPE;
+        CREATE INDEX idx_snmp_trap_log_trap_timestamp ON snmp_trap_log(trap_timestamp);
+- Indexes added to existing log tables:
+       CREATE INDEX idx_event_log_event_timestamp ON event_log(event_timestamp);
+       CREATE INDEX idx_syslog_msg_timestamp ON syslog(msg_timestamp);
+- Added configuration parameter "LogAllSNMPTraps"
+
+
+*************
 * 36 ==> 37 *
 *************
 
index 1e1db7d..9013c32 100644 (file)
@@ -23,6 +23,6 @@
 #ifndef _netxms_db_h
 #define _netxms_db_h
 
-#define DB_FORMAT_VERSION      37
+#define DB_FORMAT_VERSION      38
 
 #endif
index 64a7696..9ef46e0 100644 (file)
@@ -44,6 +44,9 @@
 #define EVP_MAX_IV_LENGTH              16
 #endif
 
+#define RECORD_ORDER_NORMAL            0
+#define RECORD_ORDER_REVERSED          1
+
 
 //
 // Ciphers
@@ -225,6 +228,7 @@ typedef struct
 #define MF_END_OF_FILE     0x0002
 #define MF_DONT_ENCRYPT    0x0004
 #define MF_END_OF_SEQUENCE 0x0008
+#define MF_REVERSE_ORDER   0x0010
 
 
 //
@@ -389,6 +393,8 @@ typedef struct
 #define CMD_RENAME_SCRIPT           0x009C
 #define CMD_GET_SESSION_LIST        0x009D
 #define CMD_KILL_SESSION            0x009E
+#define CMD_GET_TRAP_LOG            0x009F
+#define CMD_TRAP_LOG_RECORDS        0x00A0
 
 
 //
@@ -604,6 +610,7 @@ typedef struct
 #define VID_SCRIPT_ID               ((DWORD)207)
 #define VID_SCRIPT_CODE             ((DWORD)208)
 #define VID_SESSION_ID              ((DWORD)209)
+#define VID_RECORDS_ORDER           ((DWORD)210)
 
 // Variable ranges for object's ACL
 #define VID_ACL_USER_BASE           ((DWORD)0x00001000)
@@ -684,6 +691,9 @@ typedef struct
 // Base value for syslog records
 #define VID_SYSLOG_MSG_BASE         ((DWORD)0x10000000)
 
+// Base value for trap log records
+#define VID_TRAP_LOG_MSG_BASE       ((DWORD)0x10000000)
+
 // Base value for script list
 #define VID_SCRIPT_LIST_BASE        ((DWORD)0x10000000)
 
index 6b949ec..bb2819b 100644 (file)
@@ -1,7 +1,7 @@
 /* 
 ** NetXMS - Network Management System
 ** Client Library API
-** Copyright (C) 2004, 2005 Victor Kirhenshtein
+** Copyright (C) 2004, 2005, 2006 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
 ** along with this program; if not, write to the Free Software
 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 **
-** $module: nxclapi.h
+** File: nxclapi.h
 **
 **/
 
-/*
-** WARNING !!!
-**
-** If structures in this file being changed, don't forget to change
-** NXSM wrapper files accordingly!
-**
-*/
-
-
 #ifndef _nxclapi_h_
 #define _nxclapi_h_
 
@@ -211,6 +202,7 @@ typedef void * NXC_SESSION;
 #define NXC_EVENT_NOTIFICATION         5
 #define NXC_EVENT_DEPLOYMENT_STATUS    6
 #define NXC_EVENT_NEW_SYSLOG_RECORD    7
+#define NXC_EVENT_NEW_SNMP_TRAP        8
 
 
 //
@@ -367,8 +359,9 @@ typedef void * NXC_SESSION;
 #define SYSTEM_ACCESS_MANAGE_LPP          0x0400
 #define SYSTEM_ACCESS_MANAGE_TOOLS        0x0800
 #define SYSTEM_ACCESS_MANAGE_SCRIPTS      0x1000
+#define SYSTEM_ACCESS_VIEW_TRAP_LOG       0x2000
 
-#define SYSTEM_ACCESS_FULL                0x1FFF
+#define SYSTEM_ACCESS_FULL                0x3FFF
 
 
 //
@@ -501,6 +494,7 @@ typedef void * NXC_SESSION;
 #define NXC_CHANNEL_SYSLOG       0x0002
 #define NXC_CHANNEL_ALARMS       0x0004
 #define NXC_CHANNEL_OBJECTS      0x0008
+#define NXC_CHANNEL_SNMP_TRAPS   0x0010
 
 
 //
@@ -1270,6 +1264,21 @@ typedef struct
 
 
 //
+// Trap log records
+//
+
+typedef struct
+{
+   QWORD qwId;
+   DWORD dwTimeStamp;
+   DWORD dwIpAddr;
+   DWORD dwObjectId;
+   TCHAR szTrapOID[MAX_DB_STRING];
+   TCHAR *pszTrapVarbinds;
+} NXC_SNMP_TRAP_LOG_RECORD;
+
+
+//
 // Functions
 //
 
index 05bf02a..c52b1b4 100644 (file)
@@ -77,6 +77,7 @@ private:
 
 public:
    CSCPMessage();
+   CSCPMessage(CSCPMessage *pMsg);
    CSCPMessage(CSCP_MESSAGE *pMsg);
    ~CSCPMessage();
 
@@ -90,6 +91,7 @@ public:
 
    BOOL IsVariableExist(DWORD dwVarId) { return (FindVariable(dwVarId) != INVALID_INDEX) ? TRUE : FALSE; }
    BOOL IsEndOfSequence(void) { return (m_wFlags & MF_END_OF_SEQUENCE) ? TRUE : FALSE; }
+   BOOL IsReverseOrder(void) { return (m_wFlags & MF_REVERSE_ORDER) ? TRUE : FALSE; }
 
    void SetVariable(DWORD dwVarId, WORD wValue) { Set(dwVarId, CSCP_DT_INT16, &wValue); }
    void SetVariable(DWORD dwVarId, DWORD dwValue) { Set(dwVarId, CSCP_DT_INTEGER, &dwValue); }
@@ -113,6 +115,7 @@ public:
 
    void DisableEncryption(void) { m_wFlags |= MF_DONT_ENCRYPT; }
    void SetEndOfSequence(void) { m_wFlags |= MF_END_OF_SEQUENCE; }
+   void SetReverseOrderFlag(void) { m_wFlags |= MF_REVERSE_ORDER; }
 };
 
 
@@ -184,7 +187,7 @@ int LIBNXCSCP_EXPORTABLE RecvCSCPMessage(SOCKET hSocket, CSCP_MESSAGE *pMsg,
                                          CSCP_BUFFER *pBuffer, DWORD dwMaxMsgSize,
                                          CSCP_ENCRYPTION_CONTEXT **ppCtx,
                                          BYTE *pDecryptionBuffer, DWORD dwTimeout);
-CSCP_MESSAGE LIBNXCSCP_EXPORTABLE *CreateRawCSCPMessage(WORD wCode, DWORD dwId,
+CSCP_MESSAGE LIBNXCSCP_EXPORTABLE *CreateRawCSCPMessage(WORD wCode, DWORD dwId, WORD wFlags,
                                                         DWORD dwDataSize, void *pData,
                                                         CSCP_MESSAGE *pBuffer);
 TCHAR LIBNXCSCP_EXPORTABLE *CSCPMessageCodeName(WORD wCode, TCHAR *pszBuffer);
index 36c4545..db587b7 100644 (file)
@@ -434,6 +434,8 @@ CREATE TABLE event_log
        PRIMARY KEY(event_id)
 ) TABLE_TYPE;
 
+CREATE INDEX idx_event_log_event_timestamp ON event_log(event_timestamp);
+
 
 /*
 ** Actions on events
@@ -741,6 +743,8 @@ CREATE TABLE syslog
        PRIMARY KEY(msg_id)
 ) TABLE_TYPE;
 
+CREATE INDEX idx_syslog_msg_timestamp ON syslog(msg_timestamp);
+
 
 /*
 ** Script library
@@ -762,7 +766,7 @@ CREATE TABLE script_library
 CREATE TABLE snmp_trap_log
 (
        trap_id SQL_INT64 not null,
-       timestamp integer not null,
+       trap_timestamp integer not null,
        ip_addr varchar(15) not null,
        object_id integer not null,
        trap_oid varchar(255) not null,
@@ -770,6 +774,8 @@ CREATE TABLE snmp_trap_log
        PRIMARY KEY(trap_id)
 ) TABLE_TYPE;
 
+CREATE INDEX idx_snmp_trap_log_trap_timestamp ON snmp_trap_log(trap_timestamp);
+
 
 /*
 ** Log processing policy
index 01dea35..0ab524a 100644 (file)
@@ -85,6 +85,7 @@ int CEventBrowser::OnCreate(LPCREATESTRUCT lpCreateStruct)
    m_wndListCtrl.InsertColumn(3, "Message", LVCFMT_LEFT, 500);
        
    // Create wait view
+   m_wndWaitView.SetText(_T("Loading event log..."));
    m_wndWaitView.Create(NULL, NULL, WS_CHILD, rect, this, ID_WAIT_VIEW);
 
    ((CConsoleApp *)AfxGetApp())->OnViewCreate(IDR_EVENTS, this);
@@ -144,7 +145,7 @@ void CEventBrowser::OnSetFocus(CWnd* pOldWnd)
 // Add new event record (normally received from the server) to the list
 //
 
-void CEventBrowser::AddEvent(NXC_EVENT *pEvent)
+void CEventBrowser::AddEvent(NXC_EVENT *pEvent, BOOL bAppend)
 {
    int iIdx;
    struct tm *ptm;
@@ -152,7 +153,7 @@ void CEventBrowser::AddEvent(NXC_EVENT *pEvent)
 
    ptm = localtime((const time_t *)&pEvent->dwTimeStamp);
    strftime(szBuffer, 32, "%d-%b-%Y %H:%M:%S", ptm);
-   iIdx = m_wndListCtrl.InsertItem(0x7FFFFFFF, szBuffer, pEvent->dwSeverity);
+   iIdx = m_wndListCtrl.InsertItem(bAppend ? 0x7FFFFFFF : 0, szBuffer, pEvent->dwSeverity);
    if (iIdx != -1)
    {
       NXC_OBJECT *pObject;
@@ -231,6 +232,6 @@ LRESULT CEventBrowser::OnGetSaveInfo(WPARAM wParam, WINDOW_SAVE_INFO *pInfo)
 
 void CEventBrowser::OnNetXMSEvent(WPARAM wParam, NXC_EVENT *pEvent)
 {
-   AddEvent(pEvent);
+   AddEvent(pEvent, wParam == RECORD_ORDER_NORMAL);
    free(pEvent);
 }
index 1affb36..f8af10a 100644 (file)
@@ -22,8 +22,6 @@ public:
 
 // Operations
 public:
-       void AddEvent(NXC_EVENT *pEvent);
-
 // Overrides
        // ClassWizard generated virtual function overrides
        //{{AFX_VIRTUAL(CEventBrowser)
@@ -39,6 +37,8 @@ protected:
        CListCtrl m_wndListCtrl;
        virtual ~CEventBrowser();
 
+       void AddEvent(NXC_EVENT *pEvent, BOOL bAppend);
+
        // Generated message map functions
        //{{AFX_MSG(CEventBrowser)
        afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
index cdf3853..499d407 100644 (file)
@@ -105,6 +105,7 @@ EXTRA_DIST = \
        tools.cpp \
        TrapEditor.cpp TrapEditor.h \
        TrapEditDlg.cpp TrapEditDlg.h \
+       TrapLogBrowser.cpp TrapLogBrowser.h \
        TrapParamDlg.cpp TrapParamDlg.h \
        UserEditor.cpp UserEditor.h \
        UserPropDlg.cpp UserPropDlg.h \
index 0a9d560..38ad609 100644 (file)
@@ -87,6 +87,7 @@ int CSyslogBrowser::OnCreate(LPCREATESTRUCT lpCreateStruct)
    m_wndListCtrl.InsertColumn(5, "Message", LVCFMT_LEFT, 500);
        
    // Create wait view
+   m_wndWaitView.SetText(_T("Loading syslog..."));
    m_wndWaitView.Create(NULL, NULL, WS_CHILD, rect, this, ID_WAIT_VIEW);
 
    ((CConsoleApp *)AfxGetApp())->OnViewCreate(IDR_SYSLOG_BROWSER, this);
@@ -206,7 +207,7 @@ LRESULT CSyslogBrowser::OnGetSaveInfo(WPARAM wParam, WINDOW_SAVE_INFO *pInfo)
 
 void CSyslogBrowser::OnSyslogRecord(WPARAM wParam, NXC_SYSLOG_RECORD *pRec)
 {
-   AddRecord(pRec);
+   AddRecord(pRec, wParam == RECORD_ORDER_NORMAL);
    safe_free(pRec->pszText);
    free(pRec);
 }
@@ -216,7 +217,7 @@ void CSyslogBrowser::OnSyslogRecord(WPARAM wParam, NXC_SYSLOG_RECORD *pRec)
 // Add new record to list
 //
 
-void CSyslogBrowser::AddRecord(NXC_SYSLOG_RECORD *pRec)
+void CSyslogBrowser::AddRecord(NXC_SYSLOG_RECORD *pRec, BOOL bAppend)
 {
    int iIdx;
    struct tm *ptm;
@@ -225,7 +226,7 @@ void CSyslogBrowser::AddRecord(NXC_SYSLOG_RECORD *pRec)
 
    ptm = localtime((const time_t *)&pRec->dwTimeStamp);
    strftime(szBuffer, 32, "%d-%b-%Y %H:%M:%S", ptm);
-   iIdx = m_wndListCtrl.InsertItem(0x7FFFFFFF, szBuffer, nImage[pRec->wSeverity]);
+   iIdx = m_wndListCtrl.InsertItem(bAppend ? 0x7FFFFFFF : 0, szBuffer, nImage[pRec->wSeverity]);
    if (iIdx != -1)
    {
       m_wndListCtrl.SetItemText(iIdx, 1, g_szSyslogSeverity[pRec->wSeverity]);
@@ -242,6 +243,7 @@ void CSyslogBrowser::AddRecord(NXC_SYSLOG_RECORD *pRec)
       m_wndListCtrl.SetItemText(iIdx, 4, pRec->szTag);
       m_wndListCtrl.SetItemText(iIdx, 5, pRec->pszText);
 
-      m_wndListCtrl.EnsureVisible(iIdx, FALSE);
+      if (bAppend)
+         m_wndListCtrl.EnsureVisible(iIdx, FALSE);
    }
 }
index f8995e7..ac75b8a 100644 (file)
@@ -32,7 +32,7 @@ public:
 
 // Implementation
 protected:
-       void AddRecord(NXC_SYSLOG_RECORD *pRec);
+       void AddRecord(NXC_SYSLOG_RECORD *pRec, BOOL bAppend);
        CImageList *m_pImageList;
        BOOL m_bIsBusy;
        CWaitView m_wndWaitView;
index 074808b..0d2a953 100644 (file)
@@ -114,6 +114,7 @@ int CTableView::OnCreate(LPCREATESTRUCT lpCreateStruct)
    m_wndListCtrl.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
 
    // Create wait view
+   m_wndWaitView.SetText(_T("Receiving data from server..."));
    m_wndWaitView.Create(NULL, NULL, WS_CHILD, rect, this, ID_WAIT_VIEW);
        
    PostMessage(WM_COMMAND, ID_VIEW_REFRESH, 0);
index 5caa225..f2cbfd6 100644 (file)
@@ -131,14 +131,17 @@ void CToolBox::OnNcPaint()
 
 int CToolBox::OnCreate(LPCREATESTRUCT lpCreateStruct) 
 {
+   CDC *pdc;
+
        if (CWnd::OnCreate(lpCreateStruct) == -1)
                return -1;
 
-   m_fontTitle.CreateFont(-MulDiv(8, GetDeviceCaps(GetDC()->m_hDC, LOGPIXELSY), 72),
+   pdc = GetDC();
+   m_fontTitle.CreateFont(-MulDiv(8, GetDeviceCaps(pdc->m_hDC, LOGPIXELSY), 72),
                           0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET,
                           OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY,
                           VARIABLE_PITCH | FF_DONTCARE, "MS Sans Serif");
-       
+       ReleaseDC(pdc);
        return 0;
 }
 
diff --git a/src/console/win32/TrapLogBrowser.cpp b/src/console/win32/TrapLogBrowser.cpp
new file mode 100644 (file)
index 0000000..6c2cd1f
--- /dev/null
@@ -0,0 +1,141 @@
+// TrapLogBrowser.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "nxcon.h"
+#include "TrapLogBrowser.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CTrapLogBrowser
+
+IMPLEMENT_DYNCREATE(CTrapLogBrowser, CMDIChildWnd)
+
+CTrapLogBrowser::CTrapLogBrowser()
+{
+   m_bIsBusy = FALSE;
+}
+
+CTrapLogBrowser::~CTrapLogBrowser()
+{
+}
+
+
+BEGIN_MESSAGE_MAP(CTrapLogBrowser, CMDIChildWnd)
+       //{{AFX_MSG_MAP(CTrapLogBrowser)
+       ON_WM_CREATE()
+       ON_WM_DESTROY()
+       ON_WM_SETFOCUS()
+       ON_WM_SIZE()
+       ON_COMMAND(ID_VIEW_REFRESH, OnViewRefresh)
+       //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CTrapLogBrowser message handlers
+
+BOOL CTrapLogBrowser::PreCreateWindow(CREATESTRUCT& cs) 
+{
+       // TODO: Add your specialized code here and/or call the base class
+       
+       return CMDIChildWnd::PreCreateWindow(cs);
+}
+
+
+//
+// WM_CREATE message handler
+//
+
+int CTrapLogBrowser::OnCreate(LPCREATESTRUCT lpCreateStruct) 
+{
+   RECT rect;
+   DWORD dwResult;
+
+       if (CMDIChildWnd::OnCreate(lpCreateStruct) == -1)
+               return -1;
+       
+   // Create list view control
+   GetClientRect(&rect);
+   m_wndListCtrl.Create(WS_CHILD | WS_VISIBLE | LVS_REPORT, rect, this, ID_LIST_VIEW);
+   m_wndListCtrl.SetExtendedStyle(LVS_EX_TRACKSELECT | LVS_EX_UNDERLINEHOT | 
+                                  LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
+   m_wndListCtrl.SetHoverTime(0x7FFFFFFF);
+
+   // Setup columns
+   m_wndListCtrl.InsertColumn(0, "Time", LVCFMT_LEFT, 135);
+   m_wndListCtrl.InsertColumn(1, "Source IP", LVCFMT_LEFT, 80);
+   m_wndListCtrl.InsertColumn(2, "Source Object", LVCFMT_LEFT, 80);
+   m_wndListCtrl.InsertColumn(3, "Trap OID", LVCFMT_LEFT, 100);
+   m_wndListCtrl.InsertColumn(4, "Varbinds", LVCFMT_LEFT, 500);
+       
+   // Create wait view
+   m_wndWaitView.SetText(_T("Loading SNMP trap log..."));
+   m_wndWaitView.Create(NULL, NULL, WS_CHILD, rect, this, ID_WAIT_VIEW);
+
+   ((CConsoleApp *)AfxGetApp())->OnViewCreate(IDR_TRAP_LOG_BROWSER, this);
+   dwResult = DoRequestArg2(NXCSubscribe, g_hSession,
+                            (void *)NXC_CHANNEL_SNMP_TRAPS,
+                            _T("Subscribing to SNMPTRAPS channel..."));
+   if (dwResult != RCC_SUCCESS)
+      theApp.ErrorBox(dwResult, _T("Cannot subscribe to SNMPTRAPS channel: %s"));
+
+   PostMessage(WM_COMMAND, ID_VIEW_REFRESH, 0);
+       return 0;
+}
+
+
+//
+// WM_DESTROY message handler
+//
+
+void CTrapLogBrowser::OnDestroy() 
+{
+   DoRequestArg2(NXCUnsubscribe, g_hSession, (void *)NXC_CHANNEL_SNMP_TRAPS,
+                 _T("Unsubscribing from SNMPTRAPS channel..."));
+   ((CConsoleApp *)AfxGetApp())->OnViewDestroy(IDR_TRAP_LOG_BROWSER, this);
+       CMDIChildWnd::OnDestroy();
+}
+
+
+//
+// WM_SETFOCUS message handler
+//
+
+void CTrapLogBrowser::OnSetFocus(CWnd* pOldWnd) 
+{
+       CMDIChildWnd::OnSetFocus(pOldWnd);
+       
+   if (m_bIsBusy)
+      m_wndWaitView.SetFocus();
+   else
+      m_wndListCtrl.SetFocus();
+}
+
+
+//
+// WM_SIZE message handler
+//
+
+void CTrapLogBrowser::OnSize(UINT nType, int cx, int cy) 
+{
+       CMDIChildWnd::OnSize(nType, cx, cy);
+       
+   m_wndListCtrl.SetWindowPos(NULL, 0, 0, cx, cy, SWP_NOZORDER);
+   m_wndWaitView.SetWindowPos(NULL, 0, 0, cx, cy, SWP_NOZORDER);
+}
+
+
+//
+// WM_COMMAND::ID_VIEW_REFRESH message handler
+//
+
+void CTrapLogBrowser::OnViewRefresh() 
+{
+       // TODO: Add your command handler code here
+       
+}
similarity index 55%
copy from src/console/win32/EventBrowser.h
copy to src/console/win32/TrapLogBrowser.h
index 1affb36..7421847 100644 (file)
@@ -1,55 +1,50 @@
-#if !defined(AFX_EVENTBROWSER_H__02BA6E09_9B47_47DF_BD7F_5D39FB02A78C__INCLUDED_)
-#define AFX_EVENTBROWSER_H__02BA6E09_9B47_47DF_BD7F_5D39FB02A78C__INCLUDED_
+#if !defined(AFX_TRAPLOGBROWSER_H__4BF65716_21B1_42CB_AAD4_37E933410142__INCLUDED_)
+#define AFX_TRAPLOGBROWSER_H__4BF65716_21B1_42CB_AAD4_37E933410142__INCLUDED_
 
 #include "WaitView.h"  // Added by ClassView
 #if _MSC_VER > 1000
 #pragma once
 #endif // _MSC_VER > 1000
-// EventBrowser.h : header file
+// TrapLogBrowser.h : header file
 //
 
 /////////////////////////////////////////////////////////////////////////////
-// CEventBrowser frame
+// CTrapLogBrowser frame
 
-class CEventBrowser : public CMDIChildWnd
+class CTrapLogBrowser : public CMDIChildWnd
 {
-       DECLARE_DYNCREATE(CEventBrowser)
+       DECLARE_DYNCREATE(CTrapLogBrowser)
 protected:
-       CEventBrowser();           // protected constructor used by dynamic creation
+       CTrapLogBrowser();           // protected constructor used by dynamic creation
 
 // Attributes
 public:
 
 // Operations
 public:
-       void AddEvent(NXC_EVENT *pEvent);
 
 // Overrides
        // ClassWizard generated virtual function overrides
-       //{{AFX_VIRTUAL(CEventBrowser)
+       //{{AFX_VIRTUAL(CTrapLogBrowser)
        protected:
        virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
        //}}AFX_VIRTUAL
 
 // Implementation
 protected:
-       BOOL m_bIsBusy;
        CWaitView m_wndWaitView;
-       CImageList *m_pImageList;
+       BOOL m_bIsBusy;
        CListCtrl m_wndListCtrl;
-       virtual ~CEventBrowser();
+       virtual ~CTrapLogBrowser();
 
        // Generated message map functions
-       //{{AFX_MSG(CEventBrowser)
+       //{{AFX_MSG(CTrapLogBrowser)
        afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
        afx_msg void OnDestroy();
-       afx_msg void OnSize(UINT nType, int cx, int cy);
        afx_msg void OnSetFocus(CWnd* pOldWnd);
+       afx_msg void OnSize(UINT nType, int cx, int cy);
        afx_msg void OnViewRefresh();
        //}}AFX_MSG
-   afx_msg LRESULT OnGetSaveInfo(WPARAM wParam, WINDOW_SAVE_INFO *pInfo);
-   afx_msg void OnRequestCompleted(void);
-   afx_msg void OnNetXMSEvent(WPARAM wParam, NXC_EVENT *pEvent);
        DECLARE_MESSAGE_MAP()
 };
 
@@ -58,4 +53,4 @@ protected:
 //{{AFX_INSERT_LOCATION}}
 // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
 
-#endif // !defined(AFX_EVENTBROWSER_H__02BA6E09_9B47_47DF_BD7F_5D39FB02A78C__INCLUDED_)
+#endif // !defined(AFX_TRAPLOGBROWSER_H__4BF65716_21B1_42CB_AAD4_37E933410142__INCLUDED_)
index e08f7a1..689aef4 100644 (file)
 static char THIS_FILE[] = __FILE__;
 #endif
 
-#define BOX_COUNT          10
-#define BOX_SIZE           10
-#define BOX_MARGIN         25
-#define MAX_STAGES         10
-
-
-//
-// Static data
-//
-
-static COLORREF m_rgbBoxColors[MAX_STAGES] =
-{
-   RGB(53, 128, 21),
-   RGB(61, 147, 23),
-   RGB(68, 165, 27),
-   RGB(75, 183, 30),
-   RGB(83, 201, 33),
-   RGB(90, 220, 35),
-   RGB(104, 222, 54),
-   RGB(118, 225, 72),
-   RGB(132, 228, 90),
-   RGB(146, 232, 108)
-};
+#define ID_PROGRESS_BAR    100
+#define ID_STATIC_TEXT     101
 
 
 /////////////////////////////////////////////////////////////////////////////
@@ -41,9 +20,7 @@ static COLORREF m_rgbBoxColors[MAX_STAGES] =
 
 CWaitView::CWaitView()
 {
-   m_iActiveBox = 0;
-   m_iStage = 0;
-   m_iStageDir = 1;
+   _tcscpy(m_szText, _T("Loading..."));
 }
 
 CWaitView::~CWaitView()
@@ -53,9 +30,11 @@ CWaitView::~CWaitView()
 
 BEGIN_MESSAGE_MAP(CWaitView, CWnd)
        //{{AFX_MSG_MAP(CWaitView)
-       ON_WM_PAINT()
        ON_WM_DESTROY()
        ON_WM_TIMER()
+       ON_WM_CREATE()
+       ON_WM_SIZE()
+       ON_WM_CTLCOLOR()
        //}}AFX_MSG_MAP
 END_MESSAGE_MAP()
 
@@ -68,13 +47,47 @@ BOOL CWaitView::PreCreateWindow(CREATESTRUCT& cs)
    if (cs.lpszClass == NULL)
       cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW, 
                                          ::LoadCursor(NULL, IDC_WAIT), 
-                                         GetSysColorBrush(COLOR_3DSHADOW), 
+                                         GetSysColorBrush(COLOR_WINDOW), 
                                          NULL);
        return CWnd::PreCreateWindow(cs);
 }
 
 
 //
+// WM_CREATE message handler
+//
+
+int CWaitView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
+{
+   RECT rect;
+   CDC *pdc;
+
+       if (CWnd::OnCreate(lpCreateStruct) == -1)
+               return -1;
+
+   pdc = GetDC();
+   m_font.CreateFont(-MulDiv(8, GetDeviceCaps(pdc->m_hDC, LOGPIXELSY), 72),
+                     0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET,
+                     OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY,
+                     VARIABLE_PITCH | FF_DONTCARE, "MS Sans Serif");
+   m_nTextHeight = pdc->GetTextExtent(_T("TEXT"), 4).cy;
+   ReleaseDC(pdc);
+
+   rect.left = 0;
+   rect.top = 0;
+   rect.right = 100;
+   rect.bottom = 20;
+   m_wndText.Create(m_szText, WS_CHILD | WS_VISIBLE | SS_LEFT | SS_NOPREFIX, rect, this, ID_STATIC_TEXT);
+   m_wndText.SetFont(&m_font);
+   m_wndProgressBar.Create(WS_CHILD | WS_VISIBLE | WS_BORDER | PBS_SMOOTH, rect, this, ID_PROGRESS_BAR);
+   m_wndProgressBar.SendMessage(PBM_SETBKCOLOR, 0, (LPARAM)GetSysColor(COLOR_WINDOW));
+   m_wndProgressBar.ModifyStyleEx(WS_EX_CLIENTEDGE | WS_EX_STATICEDGE, 0, 0);
+       
+       return 0;
+}
+
+
+//
 // WM_DESTROY message handler
 //
 
@@ -87,27 +100,18 @@ void CWaitView::OnDestroy()
 
 
 //
-// WM_PAINT message handler
+// WM_SIZE message handler
 //
 
-void CWaitView::OnPaint(
+void CWaitView::OnSize(UINT nType, int cx, int cy
 {
-       CPaintDC dc(this); // device context for painting
-   RECT rect;
-   int i, x, y;
-
-   GetClientRect(&rect);
+   int x, y;
 
-   // Draw boxes
-   y = (rect.bottom - BOX_SIZE) / 2;
-   x = (rect.right - (BOX_COUNT * BOX_SIZE + (BOX_COUNT - 1) * BOX_MARGIN)) / 2;
-   for(i = 0; i < BOX_COUNT; i++)
-   {
-      dc.Draw3dRect(x, y, BOX_SIZE, BOX_SIZE, RGB(46, 109, 18), RGB(159, 234, 128));
-      dc.FillSolidRect(x + 1, y + 1, BOX_SIZE - 2, BOX_SIZE - 2,
-                       (i == m_iActiveBox) ? m_rgbBoxColors[m_iStage] : m_rgbBoxColors[0]);
-      x += BOX_SIZE + BOX_MARGIN;
-   }
+       CWnd::OnSize(nType, cx, cy);
+   x = cx / 2 - 150;
+   y = cy / 2;
+   m_wndText.SetWindowPos(NULL, x, y - m_nTextHeight - 3, 300, m_nTextHeight + 2, SWP_NOZORDER);
+   m_wndProgressBar.SetWindowPos(NULL, x, y + 1, 300, 12, SWP_NOZORDER);
 }
 
 
@@ -117,19 +121,16 @@ void CWaitView::OnPaint()
 
 void CWaitView::OnTimer(UINT nIDEvent) 
 {
-   m_iStage += m_iStageDir;
-   if (m_iStage == MAX_STAGES - 1)
-   {
-      m_iStageDir = -1;
-   }
-   else if (m_iStage == 0)
+   m_nCurrPos++;
+   m_wndProgressBar.SetPos(m_nCurrPos);
+   if (m_nCurrPos > m_nThreshold)
    {
-      m_iStageDir = 1;
-      m_iActiveBox++;
-      if (m_iActiveBox == BOX_COUNT)
-         m_iActiveBox = 0;
+      m_nMaxPos *= 2;
+      m_nCurrPos *= 2;
+      m_wndProgressBar.SetRange32(0, m_nMaxPos);
+      m_wndProgressBar.SetPos(m_nCurrPos);
+      m_nThreshold = m_nCurrPos + (m_nMaxPos - m_nCurrPos) / 2;
    }
-   InvalidateRect(NULL, FALSE);
 }
 
 
@@ -142,12 +143,12 @@ void CWaitView::Start()
    if (m_nTimer != 0)
       KillTimer(m_nTimer);
 
-   m_iActiveBox = 0;
-   m_iStage = 0;
-   m_iStageDir = 1;
-
-   m_nTimer = SetTimer(1, 100, NULL);
-   InvalidateRect(NULL, FALSE);
+   m_nCurrPos = 0;
+   m_nMaxPos = 100;
+   m_nThreshold = 50;
+   m_wndProgressBar.SetRange32(0, m_nMaxPos);
+   m_wndProgressBar.SetPos(0);
+   m_nTimer = SetTimer(1, 1000, NULL);
 }
 
 
@@ -163,3 +164,26 @@ void CWaitView::Stop()
       m_nTimer = 0;
    }
 }
+
+
+//
+// WM_CTLCOLOR message handler
+//
+
+HBRUSH CWaitView::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
+{
+   HBRUSH hbr;
+
+   switch(pWnd->GetDlgCtrlID())
+   {
+      case ID_STATIC_TEXT:
+         pDC->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
+         pDC->SetBkColor(GetSysColor(COLOR_WINDOW));
+         hbr = GetSysColorBrush(COLOR_WINDOW);
+         break;
+      default:
+       hbr = CWnd::OnCtlColor(pDC, pWnd, nCtlColor);
+         break;
+   }
+       return hbr;
+}
index 7357722..0ac183f 100644 (file)
@@ -37,16 +37,26 @@ public:
 
        // Generated message map functions
 protected:
-       int m_iStageDir;
-       int m_iStage;
+       int m_nThreshold;
+       int m_nMaxPos;
+       int m_nCurrPos;
+       int m_nTextHeight;
+       CFont m_font;
+       TCHAR m_szText[MAX_DB_STRING];
+       CProgressCtrl m_wndProgressBar;
+       CStatic m_wndText;
        UINT m_nTimer;
-       int m_iActiveBox;
        //{{AFX_MSG(CWaitView)
-       afx_msg void OnPaint();
        afx_msg void OnDestroy();
        afx_msg void OnTimer(UINT nIDEvent);
+       afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+       afx_msg void OnSize(UINT nType, int cx, int cy);
+       afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
        //}}AFX_MSG
        DECLARE_MESSAGE_MAP()
+
+public:
+   void SetText(TCHAR *pszText) { nx_strncpy(m_szText, pszText, MAX_DB_STRING); }
 };
 
 /////////////////////////////////////////////////////////////////////////////
index aa07d98..f557569 100644 (file)
@@ -114,6 +114,7 @@ extern CConsoleApp theApp;
 #define NXCM_UPDATE_EVENT_LIST     (WM_USER + 118)
 #define NXCM_UPDATE_OBJECT_TOOLS   (WM_USER + 119)
 #define NXCM_UPDATE_GRAPH_POINT    (WM_USER + 120)
+#define NXCM_TRAP_LOG_RECORD       (WM_USER + 121)
 
 
 //
index d488f85..439e4a4 100644 (file)
@@ -2,13 +2,13 @@
 
 [General Info]
 Version=1
-LastClass=CGraphSettingsPage
-LastTemplate=generic CWnd
+LastClass=CTrapLogBrowser
+LastTemplate=CMDIChildWnd
 NewFileInclude1=#include "stdafx.h"
 NewFileInclude2=#include "nxcon.h"
 LastPage=0
 
-ClassCount=114
+ClassCount=115
 Class1=CConsoleApp
 Class3=CMainFrame
 Class4=CChildFrame
@@ -16,9 +16,9 @@ Class7=CEventBrowser
 Class9=CMapView
 
 ResourceCount=136
-Resource1=IDD_OBJTOOL_GENERAL (English (U.S.))
+Resource1=IDD_CREATE_NETSRV (English (U.S.))
 Resource2=IDD_OBJECT_NODE_GENERAL
-Resource3=IDA_EVENT_EDITOR (English (U.S.))
+Resource3=IDD_OBJECT_VPNC_GENERAL (English (U.S.))
 Resource4=IDD_SELECT_OBJECT
 Resource5=IDD_SELECT_ACTION
 Class2=CChildView
@@ -32,9 +32,9 @@ Resource7=IDD_NEW_USER
 Class12=CObjectBrowser
 Resource8=IDD_CREATE_CONTAINER
 Class13=CObjectPropDlg
-Resource9=IDD_SELECT_USER (English (U.S.))
-Resource10=IDD_DCI_TRANSFORM (English (U.S.))
-Resource11=IDD_CREATE_TEMPLATE (English (U.S.))
+Resource9=IDA_TRAP_EDITOR (English (U.S.))
+Resource10=IDD_DCI_COLLECTION (English (U.S.))
+Resource11=IDD_THRESHOLD (English (U.S.))
 Resource12=IDR_CTRLPANEL (English (U.S.))
 Resource13=IDR_EVENTS (English (U.S.))
 Resource14=IDR_MAPFRAME (English (U.S.))
@@ -42,17 +42,17 @@ Resource15=IDR_OBJECTS (English (U.S.))
 Resource16=IDD_DUMMY (English (U.S.))
 Class14=CEventEditor
 Class15=CEditEventDlg
-Resource17=IDD_EDIT_RULE_ALARM (English (U.S.))
+Resource17=IDD_OBJECT_GENERAL (English (U.S.))
 Class16=CDebugFrame
-Resource18=IDD_SELECT_AGENT_PARAM (English (U.S.))
+Resource18=IDD_OBJECT_PRESENTATION (English (U.S.))
 Resource19=IDD_OBJECT_PROPERTIES (English (U.S.))
 Resource20=IDD_SELECT_EVENT
 Class17=CObjectPreview
-Resource21=IDD_OBJTOOL_OPTIONS (English (U.S.))
+Resource21=IDD_OBJECT_NODE_POLL (English (U.S.))
 Class18=CToolBox
 Class19=CObjectInfoBox
 Class20=CObjectSearchBox
-Resource22=IDD_DESKTOP_SAVE_AS (English (U.S.))
+Resource22=IDD_SELECT_ACTION (English (U.S.))
 Class21=CEditBox
 Class22=COPGeneral
 Class23=CNodePropsGeneral
@@ -61,14 +61,14 @@ Class24=CObjectPropCaps
 Class25=CObjectPropSheet
 Resource24=IDA_MDI_DEFAULT
 Class26=CRequestProcessingDlg
-Resource25=IDD_EDIT_RULE_SEVERITY (English (U.S.))
+Resource25=IDD_REQUEST_PROCESSING (English (U.S.))
 Resource26=IDD_PROGRESS (English (U.S.))
 Resource27=IDD_EDIT_RULE_ALARM
-Resource28=IDD_LASTVAL_PROP (English (U.S.))
+Resource28=IDD_DCI_TRANSFORM (English (U.S.))
 Class27=CObjectPropsGeneral
-Resource29=IDA_SCRIPT_MANAGER (English (U.S.))
+Resource29=IDR_MAINFRAME (English (U.S.))
 Class28=CObjectPropsSecurity
-Resource30=IDD_SAVE_AGENT_CFG (English (U.S.))
+Resource30=IDD_SELECT_INTERNAL_ITEM (English (U.S.))
 Resource31=IDD_SELECT_USER
 Resource32=IDD_OBJECT_SECURITY
 Class29=CUserSelectDlg
@@ -79,36 +79,36 @@ Class31=CNewUserDlg
 Resource35=IDD_THRESHOLD
 Resource36=IDA_EPP
 Class32=CUserPropDlg
-Resource37=IDA_ALARM_BROWSER (English (U.S.))
+Resource37=IDD_EDIT_VARIABLE (English (U.S.))
 Resource38=IDD_ABOUTBOX
 Class33=CGroupPropDlg
 Resource39=IDD_CP_GENERAL
 Resource40=IDA_TRAP_EDITOR
 Resource41=IDM_VIEW_SPECIFIC
-Resource42=IDA_OBJECT_BROWSER (English (U.S.))
+Resource42=IDD_LASTVAL_PROP (English (U.S.))
 Class34=CPasswordChangeDlg
 Class35=CNodeSummary
 Class36=CNetSummaryFrame
 Class37=CDataCollectionEditor
-Resource43=IDD_CHANGE_IP (English (U.S.))
+Resource43=IDD_DESKTOP_SAVE_AS (English (U.S.))
 Class38=CDCIPropPage
-Resource44=IDD_REMOVE_TEMPLATE
+Resource44=IDD_OBJECT_RELATIONS (English (U.S.))
 Class39=CDCIDataView
-Resource45=IDD_OBJECT_CAPS (English (U.S.))
+Resource45=IDA_ALARM_BROWSER (English (U.S.))
 Class40=CGraph
 Class41=CGraphFrame
 Class42=CDCIThresholdsPage
-Resource46=IDD_DCI_COLLECTION (English (U.S.))
-Resource47=IDD_SELECT_ACTION (English (U.S.))
+Resource46=IDA_AGENT_CFG_EDITOR (English (U.S.))
+Resource47=IDD_USER_PROPERTIES (English (U.S.))
 Resource48=IDM_CONTEXT
 Class43=CThresholdDlg
-Resource49=IDD_OBJECT_RELATIONS (English (U.S.))
+Resource49=IDD_ACTION_PROPERTIES (English (U.S.))
 Resource50=IDD_EDIT_TRAP_ARG
 Class44=CMIBBrowserDlg
 Class45=CEventPolicyEditor
 Class46=CRuleList
 Class47=CRuleHeader
-Resource51=IDD_CREATE_VPNC (English (U.S.))
+Resource51=IDD_DATA_QUERY (English (U.S.))
 Resource52=IDD_CREATE_NODE
 Class48=CObjectSelDlg
 Resource53=IDD_OBJECT_CAPS
@@ -117,21 +117,21 @@ Class49=CRuleCommentDlg
 Resource55=IDD_DCI_COLLECTION
 Class50=CEventSelDlg
 Resource56=IDD_DATA_QUERY
-Resource57=IDD_ABOUTBOX (English (U.S.))
+Resource57=IDA_MDI_DEFAULT (English (U.S.))
 Resource58=IDD_CREATE_TG
-Resource59=IDA_LAST_VALUES (English (U.S.))
-Resource60=IDD_SELECT_INTERNAL_ITEM (English (U.S.))
+Resource59=IDD_OBJTOOL_GENERAL (English (U.S.))
+Resource60=IDD_SELECT_EVENT (English (U.S.))
 Class51=CObjectPropsPresentation
-Resource61=IDA_TRAP_EDITOR (English (U.S.))
+Resource61=IDD_SAVE_AGENT_CFG (English (U.S.))
 Resource62=IDD_EDIT_RULE_COMMENT
 Class52=CRuleSeverityDlg
 Resource63=IDD_ACTION_PROPERTIES
 Class53=CRuleAlarmDlg
 Class54=CAlarmBrowser
-Resource64=IDA_EPP (English (U.S.))
+Resource64=IDD_DCI_DATA_EXPORT (English (U.S.))
 Resource65=IDD_DCI_TRANSFORM
-Resource66=IDA_MDI_DEFAULT (English (U.S.))
-Resource67=IDD_EDIT_TRAP (English (U.S.))
+Resource66=IDD_GRAPH_PROP_DATA (English (U.S.))
+Resource67=IDD_SELECT_OBJECT (English (U.S.))
 Resource68=IDM_CONTEXT (English (U.S.))
 Class55=CConsolePropsGeneral
 Class56=CActionEditor
@@ -143,18 +143,18 @@ Class58=CEditActionDlg
 Resource72=IDA_NETMAP
 Class59=CActionSelDlg
 Resource73=IDD_MIB_BROWSER
-Resource74=IDD_GRAPH_PROP_SETTINGS (English (U.S.))
-Resource75=IDA_ACTION_EDITOR (English (U.S.))
+Resource74=IDD_CREATE_CONTAINER (English (U.S.))
+Resource75=IDD_EDIT_IP_SUBNET (English (U.S.))
 Resource76=IDD_USER_PROPERTIES
 Class60=CCreateObjectDlg
 Class61=CCreateContainerDlg
 Resource77=IDR_MAINFRAME
 Class62=CCreateNodeDlg
-Resource78=IDA_AGENT_CFG_EDITOR (English (U.S.))
-Resource79=IDA_NETMAP (English (U.S.))
-Resource80=IDA_SERVER_CFG_EDITOR (English (U.S.))
+Resource78=IDD_OBJTOOL_OPTIONS (English (U.S.))
+Resource79=IDD_CREATE_VPNC (English (U.S.))
+Resource80=IDD_NEW_OBJECT_TOOL (English (U.S.))
 Class63=CDCITransformPage
-Resource81=IDR_MAINFRAME (English (U.S.))
+Resource81=IDD_GRAPH_PROP_SETTINGS (English (U.S.))
 Class64=CPollNodeDlg
 Resource82=IDD_POLL_NODE (English (U.S.))
 Class65=CNodePoller
@@ -171,7 +171,7 @@ Resource89=IDA_ALARM_BROWSER
 Class69=CDataQueryDlg
 Resource90=IDD_EDIT_RULE_SEVERITY
 Class70=CTrapEditDlg
-Resource91=IDD_CP_GENERAL (English (U.S.))
+Resource91=IDD_OBJECT_SECURITY (English (U.S.))
 Class71=CTrapParamDlg
 Resource92=IDD_EDIT_EVENT
 Resource93=IDD_CREATE_TEMPLATE
@@ -179,87 +179,88 @@ Class72=CGraphPropDlg
 Class73=CColorSelector
 Class74=CPackageMgr
 Resource94=IDD_GROUP_PROPERTIES
-Resource95=IDD_DCI_THRESHOLDS (English (U.S.))
-Resource96=IDD_ACTION_PROPERTIES (English (U.S.))
-Resource97=IDD_INPUT_BOX (English (U.S.))
-Resource98=IDD_MIB_BROWSER (English (U.S.))
-Resource99=IDD_EDIT_IP_SUBNET (English (U.S.))
-Resource100=IDD_GROUP_PROPERTIES (English (U.S.))
-Resource101=IDD_DCI_SCHEDULE (English (U.S.))
-Resource102=IDD_SET_PASSWORD (English (U.S.))
-Resource103=IDD_THRESHOLD (English (U.S.))
-Resource104=IDD_SELECT_EVENT (English (U.S.))
-Resource105=IDD_CREATE_TG (English (U.S.))
-Resource106=IDD_OBJECT_VPNC_GENERAL (English (U.S.))
-Resource107=IDD_OBJECT_GENERAL (English (U.S.))
+Resource95=IDA_DC_EDITOR (English (U.S.))
+Resource96=IDD_NEW_USER (English (U.S.))
+Resource97=IDD_EDIT_RULE_SEVERITY (English (U.S.))
+Resource98=IDA_SCRIPT_MANAGER (English (U.S.))
+Resource99=IDD_EDIT_TRAP_ARG (English (U.S.))
+Resource100=IDA_LAST_VALUES (English (U.S.))
+Resource101=IDD_SELECT_AGENT_PARAM (English (U.S.))
+Resource102=IDA_SERVER_CFG_EDITOR (English (U.S.))
+Resource103=IDA_OBJECT_TOOLS_EDITOR (English (U.S.))
+Resource104=IDD_OBJECT_NODE_GENERAL (English (U.S.))
+Resource105=IDD_DCI_THRESHOLDS (English (U.S.))
+Resource106=IDD_EDIT_TRAP (English (U.S.))
+Resource107=IDA_EVENT_EDITOR (English (U.S.))
 Class75=CInternalItemSelDlg
-Resource108=IDD_SELECT_OBJECT (English (U.S.))
+Resource108=IDD_ABOUTBOX (English (U.S.))
 Class76=CAgentParamSelDlg
-Resource109=IDD_REQUEST_PROCESSING (English (U.S.))
+Resource109=IDA_NETMAP (English (U.S.))
 Class77=CInputBox
-Resource110=IDD_CREATE_NETSRV (English (U.S.))
+Resource110=IDD_EDIT_RULE_ALARM (English (U.S.))
 Class78=CCreateNetSrvDlg
-Resource111=IDD_OBJECT_NETSRV_GENERAL (English (U.S.))
+Resource111=IDD_CP_GENERAL (English (U.S.))
 Class79=CNetSrvPropsGeneral
 Resource112=IDD_LOGIN (English (U.S.))
 Class80=CNodePropsPolling
 Class81=CDeploymentView
 Class82=CLastValuesView
 Class83=CValueList
-Resource113=IDA_GRAPH (English (U.S.))
+Resource113=IDD_DCI_SCHEDULE (English (U.S.))
 Class84=CObjectPropsRelations
-Resource114=IDD_USER_PROPERTIES (English (U.S.))
+Resource114=IDA_PACKAGE_MGR (English (U.S.))
 Class85=CSaveDesktopDlg
-Resource115=IDD_OBJECT_SECURITY (English (U.S.))
+Resource115=IDA_ACTION_EDITOR (English (U.S.))
 Class86=CGraphSettingsPage
-Resource116=IDD_OBJECT_NODE_GENERAL (English (U.S.))
+Resource116=IDA_EPP (English (U.S.))
 Class87=CGraphDataPage
-Resource117=IDD_DCI_DATA_EXPORT (English (U.S.))
+Resource117=IDD_CREATE_TG (English (U.S.))
 Class88=CRemoveTemplateDlg
-Resource118=IDD_OBJECT_PRESENTATION (English (U.S.))
+Resource118=IDD_OBJECT_CAPS (English (U.S.))
 Class89=CAddrChangeDlg
-Resource119=IDD_CREATE_CONTAINER (English (U.S.))
+Resource119=IDD_GROUP_PROPERTIES (English (U.S.))
 Class90=CLastValuesPropDlg
 Class91=CAgentCfgEditor
-Resource120=IDD_OBJECT_STATUS (English (U.S.))
+Resource120=IDD_INPUT_BOX (English (U.S.))
 Class92=CDataExportDlg
 Class93=CServerCfgEditor
-Resource121=IDD_CREATE_NODE (English (U.S.))
-Resource122=IDD_EDIT_TRAP_ARG (English (U.S.))
+Resource121=IDD_SET_PASSWORD (English (U.S.))
+Resource122=IDD_EDIT_RULE_COMMENT (English (U.S.))
 Class94=CEditVariableDlg
-Resource123=IDA_PACKAGE_MGR (English (U.S.))
+Resource123=IDD_OBJECT_STATUS (English (U.S.))
 Class95=CCreateVPNConnDlg
-Resource124=IDD_NEW_USER (English (U.S.))
+Resource124=IDA_GRAPH (English (U.S.))
 Class96=CVPNCPropsGeneral
-Resource125=IDD_DATA_QUERY (English (U.S.))
+Resource125=IDD_MIB_BROWSER (English (U.S.))
 Class97=CEditSubnetDlg
-Resource126=IDD_NEW_ACTION (English (U.S.))
-Resource127=IDD_EDIT_RULE_COMMENT (English (U.S.))
+Resource126=IDD_SELECT_USER (English (U.S.))
+Resource127=IDD_EDIT_EVENT (English (U.S.))
 Class98=CModifiedAgentCfgDlg
 Class99=CSimpleSplitter
 Class100=CAdvSplitter
-Resource128=IDD_EDIT_VARIABLE (English (U.S.))
+Resource128=IDD_CREATE_TEMPLATE (English (U.S.))
 Class101=CTableView
 Class102=CWaitView
 Class103=CWebBrowser
 Class104=CSyslogBrowser
 Class105=CLPPList
-Resource129=IDA_DC_EDITOR (English (U.S.))
+Resource129=IDD_REMOVE_TEMPLATE
 Class106=CDCISchedulePage
-Resource130=IDA_OBJECT_TOOLS_EDITOR (English (U.S.))
+Resource130=IDD_CHANGE_IP (English (U.S.))
 Class107=CObjectPropsStatus
 Class108=CObjectToolsEditor
 Resource131=IDM_VIEW_SPECIFIC (English (U.S.))
-Resource132=IDD_GRAPH_PROP_DATA (English (U.S.))
+Resource132=IDD_CREATE_NODE (English (U.S.))
 Class109=CObjToolPropGeneral
-Resource133=IDD_OBJECT_NODE_POLL (English (U.S.))
+Resource133=IDD_NEW_ACTION (English (U.S.))
 Class110=CObjToolPropColumns
-Resource134=IDD_EDIT_EVENT (English (U.S.))
+Resource134=IDA_OBJECT_BROWSER (English (U.S.))
 Class111=CNewObjectToolDlg
 Class112=CObjToolPropOptions
 Class113=CScriptManager
 Class114=CScriptView
-Resource135=IDD_NEW_OBJECT_TOOL (English (U.S.))
+Resource135=IDD_OBJECT_NETSRV_GENERAL (English (U.S.))
+Class115=CTrapLogBrowser
 Resource136=IDD_OBJTOOL_COLUMNS
 
 [CLS:CConsoleApp]
@@ -3747,3 +3748,11 @@ Control2=IDOK,button,1342242817
 Control3=IDCANCEL,button,1342242816
 Control4=IDC_STATIC,static,1342308352
 
+[CLS:CTrapLogBrowser]
+Type=0
+HeaderFile=TrapLogBrowser.h
+ImplementationFile=TrapLogBrowser.cpp
+BaseClass=CMDIChildWnd
+Filter=M
+VirtualFilter=mfWC
+
index cc3b064..51a7743 100644 (file)
@@ -92,6 +92,7 @@ CConsoleApp::CConsoleApp()
    m_bAlarmBrowserActive = FALSE;
    m_bEventBrowserActive = FALSE;
    m_bSyslogBrowserActive = FALSE;
+   m_bTrapLogBrowserActive = FALSE;
    m_bEventEditorActive = FALSE;
    m_bUserEditorActive = FALSE;
    m_bObjectBrowserActive = FALSE;
@@ -869,7 +870,7 @@ void CConsoleApp::EventHandler(DWORD dwEvent, DWORD dwCode, void *pArg)
             void *pData;
 
             pData = nx_memdup(pArg, sizeof(NXC_EVENT));
-            if (!PostMessage(m_hwndEventBrowser, NXCM_NETXMS_EVENT, 0, (LPARAM)pData))
+            if (!PostMessage(m_hwndEventBrowser, NXCM_NETXMS_EVENT, dwCode, (LPARAM)pData))
                free(pData);
          }
          break;
@@ -880,13 +881,27 @@ void CConsoleApp::EventHandler(DWORD dwEvent, DWORD dwCode, void *pArg)
 
             pRec = (NXC_SYSLOG_RECORD *)nx_memdup(pArg, sizeof(NXC_SYSLOG_RECORD));
             pRec->pszText = _tcsdup(((NXC_SYSLOG_RECORD *)pArg)->pszText);
-            if (!PostMessage(m_hwndSyslogBrowser, NXCM_SYSLOG_RECORD, 0, (LPARAM)pRec))
+            if (!PostMessage(m_hwndSyslogBrowser, NXCM_SYSLOG_RECORD, dwCode, (LPARAM)pRec))
             {
                safe_free(pRec->pszText);
                free(pRec);
             }
          }
          break;
+      case NXC_EVENT_NEW_SNMP_TRAP:
+         if (m_bTrapLogBrowserActive)
+         {
+            NXC_SNMP_TRAP_LOG_RECORD *pRec;
+
+            pRec = (NXC_SNMP_TRAP_LOG_RECORD *)nx_memdup(pArg, sizeof(NXC_SNMP_TRAP_LOG_RECORD));
+            pRec->pszTrapVarbinds = _tcsdup(((NXC_SNMP_TRAP_LOG_RECORD *)pArg)->pszTrapVarbinds);
+            if (!PostMessage(m_hwndTrapLogBrowser, NXCM_TRAP_LOG_RECORD, dwCode, (LPARAM)pRec))
+            {
+               safe_free(pRec->pszTrapVarbinds);
+               free(pRec);
+            }
+         }
+         break;
       case NXC_EVENT_OBJECT_CHANGED:
          ((CMainFrame *)m_pMainWnd)->PostMessage(NXCM_OBJECT_CHANGE, dwCode, (LPARAM)pArg);
          break;
index 121b480..1512ef5 100644 (file)
@@ -510,6 +510,10 @@ SOURCE=.\TrapEditor.cpp
 # End Source File
 # Begin Source File
 
+SOURCE=.\TrapLogBrowser.cpp
+# End Source File
+# Begin Source File
+
 SOURCE=.\TrapParamDlg.cpp
 # End Source File
 # Begin Source File
@@ -986,6 +990,10 @@ SOURCE=.\TrapEditor.h
 # End Source File
 # Begin Source File
 
+SOURCE=.\TrapLogBrowser.h
+# End Source File
+# Begin Source File
+
 SOURCE=.\TrapParamDlg.h
 # End Source File
 # Begin Source File
index 4ca791e..1cafeb5 100644 (file)
@@ -129,6 +129,7 @@ protected:
        DWORD m_dwClientState;
    HWND m_hwndEventBrowser;
    HWND m_hwndSyslogBrowser;
+   HWND m_hwndTrapLogBrowser;
    CActionEditor *m_pwndActionEditor;
    CTrapEditor *m_pwndTrapEditor;
        CAlarmBrowser *m_pwndAlarmBrowser;
@@ -223,6 +224,7 @@ private:
        BOOL m_bAlarmBrowserActive;
        BOOL m_bEventBrowserActive;
        BOOL m_bSyslogBrowserActive;
+       BOOL m_bTrapLogBrowserActive;
        BOOL m_bEventEditorActive;
        BOOL m_bUserEditorActive;
        BOOL m_bObjectBrowserActive;
index 9084058..d310541 100644 (file)
@@ -2912,6 +2912,7 @@ BEGIN
     IDR_DC_EDITOR           "\nData Collection Configuration\nData Collection Configuration"
     IDR_DCI_DATA_VIEW       "\nCollected Data\nCollected Data"
     IDR_TABLE_VIEW          "\nTable View\nTable View"
+    IDR_TRAP_LOG_BROWSER    "\nSNMP Traps Log\nSNMP Traps Log"
 END
 
 STRINGTABLE DISCARDABLE 
index fc213f0..719363f 100644 (file)
 #define IDR_DC_EDITOR                   8108
 #define IDR_DCI_DATA_VIEW               8109
 #define IDR_TABLE_VIEW                  8110
+#define IDR_TRAP_LOG_BROWSER            8111
 #define IDR_DCI_HISTORY_GRAPH           8113
 #define IDR_CTRLPANEL                   8133
 #define IDR_EVENTS                      8137
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_3D_CONTROLS                     1
 #define _APS_NEXT_RESOURCE_VALUE        302
-#define _APS_NEXT_COMMAND_VALUE         32984
+#define _APS_NEXT_COMMAND_VALUE         32986
 #define _APS_NEXT_CONTROL_VALUE         1339
 #define _APS_NEXT_SYMED_VALUE           126
 #endif
index 9e64639..95d403f 100644 (file)
@@ -34,7 +34,7 @@ THREAD_RESULT THREAD_CALL NetReceiver(NXCL_Session *pSession)
    CSCP_MESSAGE *pRawMsg;
    CSCP_BUFFER *pMsgBuffer;
    BYTE *pDecryptionBuffer = NULL;
-   int iErr;
+   int i, iErr;
    BOOL bMsgNotNeeded;
    TCHAR szBuffer[128];
 
@@ -205,7 +205,8 @@ THREAD_RESULT THREAD_CALL NetReceiver(NXCL_Session *pSession)
       }
    }
 
-   pSession->CompleteSync(RCC_COMM_FAILURE);    // Abort active sync operation
+   for(i = 0; i < SYNC_OP_COUNT; i++)
+      pSession->CompleteSync(i, RCC_COMM_FAILURE);    // Abort active sync operation
    DebugPrintf(_T("Network receiver thread stopped"));
    free(pRawMsg);
    free(pMsgBuffer);
index f6f8577..bf05dd8 100644 (file)
@@ -85,7 +85,7 @@ void ProcessEventDBRecord(NXCL_Session *pSession, CSCPMessage *pMsg)
       }
       else
       {
-         pSession->CompleteSync(RCC_SUCCESS);
+         pSession->CompleteSync(SYNC_EVENT_DB, RCC_SUCCESS);
       }
    }
 }
index 94acf84..ca6626f 100644 (file)
@@ -40,7 +40,7 @@ void ProcessEvent(NXCL_Session *pSession, CSCPMessage *pMsg, CSCP_MESSAGE *pRawM
    switch(wCode)
    {
       case CMD_EVENT_LIST_END:
-         pSession->CompleteSync(RCC_SUCCESS);
+         pSession->CompleteSync(SYNC_EVENTS, RCC_SUCCESS);
          break;
       case CMD_EVENT:
          if (pRawMsg != NULL)    // We should receive events as raw data
@@ -74,7 +74,10 @@ void ProcessEvent(NXCL_Session *pSession, CSCPMessage *pMsg, CSCP_MESSAGE *pRawM
 #endif
 
             // Call client's callback to handle new record
-            pSession->CallEventHandler(NXC_EVENT_NEW_ELOG_RECORD, 0, &event);
+            pSession->CallEventHandler(NXC_EVENT_NEW_ELOG_RECORD, 
+                                       (pRawMsg->wFlags & MF_REVERSE_ORDER) ? 
+                                               RECORD_ORDER_REVERSED : RECORD_ORDER_NORMAL,
+                                       &event);
          }
          break;
       default:
@@ -94,7 +97,7 @@ DWORD LIBNXCL_EXPORTABLE NXCSyncEvents(NXC_SESSION hSession, DWORD dwMaxRecords)
    DWORD dwRetCode, dwRqId;
 
    dwRqId = ((NXCL_Session *)hSession)->CreateRqId();
-   ((NXCL_Session *)hSession)->PrepareForSync();
+   ((NXCL_Session *)hSession)->PrepareForSync(SYNC_EVENTS);
 
    msg.SetCode(CMD_GET_EVENTS);
    msg.SetId(dwRqId);
@@ -103,9 +106,9 @@ DWORD LIBNXCL_EXPORTABLE NXCSyncEvents(NXC_SESSION hSession, DWORD dwMaxRecords)
 
    dwRetCode = ((NXCL_Session *)hSession)->WaitForRCC(dwRqId);
    if (dwRetCode == RCC_SUCCESS)
-      dwRetCode = ((NXCL_Session *)hSession)->WaitForSync(INFINITE);
+      dwRetCode = ((NXCL_Session *)hSession)->WaitForSync(SYNC_EVENTS, INFINITE);
    else
-      ((NXCL_Session *)hSession)->UnlockSyncOp();
+      ((NXCL_Session *)hSession)->UnlockSyncOp(SYNC_EVENTS);
 
    return dwRetCode;
 }
@@ -145,9 +148,12 @@ void ProcessSyslogRecords(NXCL_Session *pSession, CSCPMessage *pMsg)
 {
    DWORD i, dwNumRecords, dwId;
    NXC_SYSLOG_RECORD rec;
+   int nOrder;
 
    dwNumRecords = pMsg->GetVariableLong(VID_NUM_RECORDS);
-   DebugPrintf(_T("ProcessSyslogRecords(): %d records in message"), dwNumRecords);
+   nOrder = (int)pMsg->GetVariableShort(VID_RECORDS_ORDER);
+   DebugPrintf(_T("ProcessSyslogRecords(): %d records in message, in %s order"),
+               dwNumRecords, (nOrder == RECORD_ORDER_NORMAL) ? _T("normal") : _T("reversed"));
    for(i = 0, dwId = VID_SYSLOG_MSG_BASE; i < dwNumRecords; i++)
    {
       rec.qwMsgId = pMsg->GetVariableInt64(dwId++);
@@ -160,13 +166,13 @@ void ProcessSyslogRecords(NXCL_Session *pSession, CSCPMessage *pMsg)
       rec.pszText = pMsg->GetVariableStr(dwId++);
 
       // Call client's callback to handle new record
-      pSession->CallEventHandler(NXC_EVENT_NEW_SYSLOG_RECORD, 0, &rec);
+      pSession->CallEventHandler(NXC_EVENT_NEW_SYSLOG_RECORD, nOrder, &rec);
       free(rec.pszText);
    }
 
    // Notify requestor thread if all messages was received
    if (pMsg->IsEndOfSequence())
-      pSession->CompleteSync(RCC_SUCCESS);
+      pSession->CompleteSync(SYNC_SYSLOG, RCC_SUCCESS);
 }
 
 
@@ -181,7 +187,7 @@ DWORD LIBNXCL_EXPORTABLE NXCSyncSyslog(NXC_SESSION hSession, DWORD dwMaxRecords)
    DWORD dwRetCode, dwRqId;
 
    dwRqId = ((NXCL_Session *)hSession)->CreateRqId();
-   ((NXCL_Session *)hSession)->PrepareForSync();
+   ((NXCL_Session *)hSession)->PrepareForSync(SYNC_SYSLOG);
 
    msg.SetCode(CMD_GET_SYSLOG);
    msg.SetId(dwRqId);
@@ -190,9 +196,9 @@ DWORD LIBNXCL_EXPORTABLE NXCSyncSyslog(NXC_SESSION hSession, DWORD dwMaxRecords)
 
    dwRetCode = ((NXCL_Session *)hSession)->WaitForRCC(dwRqId);
    if (dwRetCode == RCC_SUCCESS)
-      dwRetCode = ((NXCL_Session *)hSession)->WaitForSync(INFINITE);
+      dwRetCode = ((NXCL_Session *)hSession)->WaitForSync(SYNC_SYSLOG, INFINITE);
    else
-      ((NXCL_Session *)hSession)->UnlockSyncOp();
+      ((NXCL_Session *)hSession)->UnlockSyncOp(SYNC_SYSLOG);
 
    return dwRetCode;
 }
index 0a3d3e3..37fef8e 100644 (file)
 //
 
 #define NXC_SF_USERDB_LOADED     0x0001
-#define NXC_SF_SYNC_FINISHED     0x0002
-#define NXC_SF_HAS_OBJECT_CACHE  0x0004
+#define NXC_SF_HAS_OBJECT_CACHE  0x0002
+
+
+//
+// Sync operations
+//
+
+#define SYNC_EVENTS     0
+#define SYNC_OBJECTS    1
+#define SYNC_SYSLOG     2
+#define SYNC_TRAP_LOG   3
+#define SYNC_EVENT_DB   4
+#define SYNC_USER_DB    5
+#define SYNC_DCI_LIST   6
+
+#define SYNC_OP_COUNT   7
 
 
 //
@@ -98,7 +112,6 @@ private:
    DWORD m_dwNumObjects;
    INDEX *m_pIndexById;
    MUTEX m_mutexIndexAccess;
-   MUTEX m_mutexSyncOpAccess;
    SOCKET m_hSocket;
    CSCP_ENCRYPTION_CONTEXT *m_pCtx;
    MsgWaitQueue m_msgWaitQueue;
@@ -120,13 +133,15 @@ private:
    DWORD m_dwNumUsers;
    NXC_USER *m_pUserList;
 
+   MUTEX m_mutexSyncOpAccess[SYNC_OP_COUNT];
+   DWORD m_dwSyncExitCode[SYNC_OP_COUNT];
 #ifdef _WIN32
-   HANDLE m_condSyncOp;
+   HANDLE m_condSyncOp[SYNC_OP_COUNT];
 #else
-   pthread_cond_t m_condSyncOp;
-   pthread_mutex_t m_mutexSyncOp;
+   pthread_cond_t m_condSyncOp[SYNC_OP_COUNT];
+   pthread_mutex_t m_mutexSyncOp[SYNC_OP_COUNT];
+   BOOL m_bSyncFinished[SYNC_OP_COUNT];
 #endif
-   DWORD m_dwSyncExitCode;
 
 public:
    DWORD m_dwCommandTimeout;
@@ -165,10 +180,10 @@ public:
 
    void CallEventHandler(DWORD dwEvent, DWORD dwCode, void *pArg);
 
-   DWORD WaitForSync(DWORD dwTimeOut);
-   void PrepareForSync(void);
-   void CompleteSync(DWORD dwRetCode);
-   void UnlockSyncOp(void) { MutexUnlock(m_mutexSyncOpAccess); }
+   DWORD WaitForSync(int nSyncOp, DWORD dwTimeOut);
+   void PrepareForSync(int nSyncOp);
+   void CompleteSync(int nSyncOp, DWORD dwRetCode);
+   void UnlockSyncOp(int nSyncOp) { MutexUnlock(m_mutexSyncOpAccess[nSyncOp]); }
 
    DWORD OpenNodeDCIList(DWORD dwNodeId, NXC_DCI_LIST **ppItemList);
 
index 90d3845..f511cf3 100644 (file)
@@ -323,7 +323,7 @@ void NXCL_Session::ProcessObjectUpdate(CSCPMessage *pMsg)
             qsort(m_pIndexById, m_dwNumObjects, sizeof(INDEX), IndexCompare);
             UnlockObjectIndex();
          }
-         CompleteSync(RCC_SUCCESS);
+         CompleteSync(SYNC_OBJECTS, RCC_SUCCESS);
          break;
       case CMD_OBJECT:
                        pTmp = pMsg->GetVariableStr(VID_OBJECT_NAME);
@@ -383,7 +383,7 @@ DWORD NXCL_Session::SyncObjects(TCHAR *pszCacheFile)
    DWORD dwRetCode, dwRqId;
 
    dwRqId = CreateRqId();
-   PrepareForSync();
+   PrepareForSync(SYNC_OBJECTS);
 
    DestroyAllObjects();
 
@@ -400,9 +400,9 @@ DWORD NXCL_Session::SyncObjects(TCHAR *pszCacheFile)
 
    // If request was successful, wait for object list end or for disconnection
    if (dwRetCode == RCC_SUCCESS)
-      dwRetCode = WaitForSync(INFINITE);
+      dwRetCode = WaitForSync(SYNC_OBJECTS, INFINITE);
    else
-      UnlockSyncOp();
+      UnlockSyncOp(SYNC_OBJECTS);
 
    return dwRetCode;
 }
index 84ccc9c..4cab2f1 100644 (file)
@@ -30,6 +30,8 @@
 
 NXCL_Session::NXCL_Session()
 {
+   int i;
+
    m_dwFlags = 0;
    m_dwMsgId = 0;
    m_dwTimeStamp = 0;
@@ -39,7 +41,6 @@ NXCL_Session::NXCL_Session()
    m_dwNumObjects = 0;
    m_pIndexById = NULL;
    m_mutexIndexAccess = MutexCreate();
-   m_mutexSyncOpAccess = MutexCreate();
    m_dwReceiverBufferSize = 4194304;     // 4MB
    m_hSocket = -1;
    m_pItemList = NULL;
@@ -60,12 +61,18 @@ NXCL_Session::NXCL_Session()
    m_condFileRq = ConditionCreate(FALSE);
    m_mutexFileRq = MutexCreate();
 
+   for(i = 0; i < SYNC_OP_COUNT; i++)
+   {
+      m_mutexSyncOpAccess[i] = MutexCreate();
+      m_dwSyncExitCode[i] = 0;
 #ifdef _WIN32
-   m_condSyncOp = CreateEvent(NULL, FALSE, FALSE, NULL);
+      m_condSyncOp[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
 #else
-   pthread_mutex_init(&m_mutexSyncOp, NULL);
-   pthread_cond_init(&m_condSyncOp, NULL);
+      pthread_mutex_init(&m_mutexSyncOp[i], NULL);
+      pthread_cond_init(&m_condSyncOp[i], NULL);
+      m_bSyncFinished[i] = FALSE;
 #endif
+   }
 }
 
 
@@ -75,6 +82,8 @@ NXCL_Session::NXCL_Session()
 
 NXCL_Session::~NXCL_Session()
 {
+   int i;
+
    Disconnect();
 
    // Wait for receiver thread termination
@@ -82,7 +91,6 @@ NXCL_Session::~NXCL_Session()
       ThreadJoin(m_hRecvThread);
 
    MutexDestroy(m_mutexIndexAccess);
-   MutexDestroy(m_mutexSyncOpAccess);
 
    MutexLock(m_mutexEventAccess, INFINITE);
    MutexUnlock(m_mutexEventAccess);
@@ -94,12 +102,16 @@ NXCL_Session::~NXCL_Session()
    MutexDestroy(m_mutexFileRq);
    ConditionDestroy(m_condFileRq);
 
+   for(i = 0; i < SYNC_OP_COUNT; i++)
+   {
+      MutexDestroy(m_mutexSyncOpAccess[i]);
 #ifdef _WIN32
-   CloseHandle(m_condSyncOp);
+      CloseHandle(m_condSyncOp[i]);
 #else
-   pthread_mutex_destroy(&m_mutexSyncOp);
-   pthread_cond_destroy(&m_condSyncOp);
+      pthread_mutex_destroy(&m_mutexSyncOp[i]);
+      pthread_cond_destroy(&m_condSyncOp[i]);
 #endif
+   }
 
    DestroyEncryptionContext(m_pCtx);
 }
@@ -232,20 +244,20 @@ BOOL NXCL_Session::SendMsg(CSCPMessage *pMsg)
 // Wait for synchronization operation completion
 //
 
-DWORD NXCL_Session::WaitForSync(DWORD dwTimeOut)
+DWORD NXCL_Session::WaitForSync(int nSyncOp, DWORD dwTimeOut)
 {
 #ifdef _WIN32
    DWORD dwRetCode;
 
-   dwRetCode = WaitForSingleObject(m_condSyncOp, dwTimeOut);
-   MutexUnlock(m_mutexSyncOpAccess);
-   return (dwRetCode == WAIT_TIMEOUT) ? RCC_TIMEOUT : m_dwSyncExitCode;
+   dwRetCode = WaitForSingleObject(m_condSyncOp[nSyncOp], dwTimeOut);
+   MutexUnlock(m_mutexSyncOpAccess[nSyncOp]);
+   return (dwRetCode == WAIT_TIMEOUT) ? RCC_TIMEOUT : m_dwSyncExitCode[nSyncOp];
 #else
    int iRetCode;
    DWORD dwResult;
 
-   pthread_mutex_lock(&m_mutexSyncOp);
-   if (!(m_dwFlags & NXC_SF_SYNC_FINISHED))
+   pthread_mutex_lock(&m_mutexSyncOp[nSyncOp]);
+   if (!m_bSyncFinished[nSyncOp])
    {
       if (dwTimeOut != INFINITE)
           {
@@ -254,29 +266,29 @@ DWORD NXCL_Session::WaitForSync(DWORD dwTimeOut)
 
                   timeout.tv_sec = dwTimeOut / 1000;
                   timeout.tv_nsec = (dwTimeOut % 1000) * 1000000;
-                  iRetCode = pthread_cond_reltimedwait_np(&m_condSyncOp, &m_mutexSyncOp, &timeout);
+                  iRetCode = pthread_cond_reltimedwait_np(&m_condSyncOp[nSyncOp], &m_mutexSyncOp[nSyncOp], &timeout);
 #else
                   struct timeval now;
                   struct timespec timeout;
 
                   gettimeofday(&now, NULL);
                   timeout.tv_sec = now.tv_sec + (dwTimeOut / 1000);
-                  timeout.tv_nsec = ( now.tv_usec + ( dwTimeOut % 1000 ) * 1000) * 1000;
-                  iRetCode = pthread_cond_timedwait(&m_condSyncOp, &m_mutexSyncOp, &timeout);
+                  timeout.tv_nsec = (now.tv_usec + (dwTimeOut % 1000) * 1000) * 1000;
+                  iRetCode = pthread_cond_timedwait(&m_condSyncOp[nSyncOp], &m_mutexSyncOp[nSyncOp], &timeout);
 #endif
           }
           else
       {
-         iRetCode = pthread_cond_wait(&m_condSyncOp, &m_mutexSyncOp);
+         iRetCode = pthread_cond_wait(&m_condSyncOp[nSyncOp], &m_mutexSyncOp[nSyncOp]);
       }
-      dwResult = (iRetCode == 0) ? m_dwSyncExitCode : RCC_TIMEOUT;
+      dwResult = (iRetCode == 0) ? m_dwSyncExitCode[nSyncOp] : RCC_TIMEOUT;
    }
    else
    {
-      dwResult = m_dwSyncExitCode;
+      dwResult = m_dwSyncExitCode[nSyncOp];
    }
-   pthread_mutex_unlock(&m_mutexSyncOp);
-   MutexUnlock(m_mutexSyncOpAccess);
+   pthread_mutex_unlock(&m_mutexSyncOp[nSyncOp]);
+   MutexUnlock(m_mutexSyncOpAccess[nSyncOp]);
    return dwResult;
 #endif
 }
@@ -286,14 +298,14 @@ DWORD NXCL_Session::WaitForSync(DWORD dwTimeOut)
 // Prepare for synchronization operation
 //
 
-void NXCL_Session::PrepareForSync(void)
+void NXCL_Session::PrepareForSync(int nSyncOp)
 {
-   MutexLock(m_mutexSyncOpAccess, INFINITE);
-   m_dwSyncExitCode = RCC_SYSTEM_FAILURE;
+   MutexLock(m_mutexSyncOpAccess[nSyncOp], INFINITE);
+   m_dwSyncExitCode[nSyncOp] = RCC_SYSTEM_FAILURE;
 #ifdef _WIN32
-   ResetEvent(m_condSyncOp);
+   ResetEvent(m_condSyncOp[nSyncOp]);
 #else
-   m_dwFlags &= ~NXC_SF_SYNC_FINISHED;
+   m_bSyncFinished[nSyncOp] = FALSE;
 #endif
 }
 
@@ -302,17 +314,17 @@ void NXCL_Session::PrepareForSync(void)
 // Complete synchronization operation
 //
 
-void NXCL_Session::CompleteSync(DWORD dwRetCode)
+void NXCL_Session::CompleteSync(int nSyncOp, DWORD dwRetCode)
 {
 #ifdef _WIN32
-   m_dwSyncExitCode = dwRetCode;
-   SetEvent(m_condSyncOp);
+   m_dwSyncExitCode[nSyncOp] = dwRetCode;
+   SetEvent(m_condSyncOp[nSyncOp]);
 #else
    pthread_mutex_lock(&m_mutexSyncOp);
-   m_dwSyncExitCode = dwRetCode;
-   m_dwFlags |= NXC_SF_SYNC_FINISHED;
-   pthread_cond_signal(&m_condSyncOp);
-   pthread_mutex_unlock(&m_mutexSyncOp);
+   m_dwSyncExitCode[nSyncOp] = dwRetCode;
+   m_bSyncFinished[nSyncOp] = TRUE;
+   pthread_cond_signal(&m_condSyncOp[nSyncOp]);
+   pthread_mutex_unlock(&m_mutexSyncOp[nSyncOp]);
 #endif
 }
 
@@ -326,7 +338,7 @@ void NXCL_Session::ProcessDCI(CSCPMessage *pMsg)
    switch(pMsg->GetCode())
    {
       case CMD_NODE_DCI_LIST_END:
-         CompleteSync(RCC_SUCCESS);
+         CompleteSync(SYNC_DCI_LIST, RCC_SUCCESS);
          break;
       case CMD_NODE_DCI:
          if (m_pItemList != NULL)
@@ -408,7 +420,7 @@ DWORD NXCL_Session::OpenNodeDCIList(DWORD dwNodeId, NXC_DCI_LIST **ppItemList)
    DWORD dwRetCode, dwRqId;
 
    dwRqId = CreateRqId();
-   PrepareForSync();
+   PrepareForSync(SYNC_DCI_LIST);
 
    m_pItemList = (NXC_DCI_LIST *)malloc(sizeof(NXC_DCI_LIST));
    m_pItemList->dwNodeId = dwNodeId;
@@ -425,7 +437,7 @@ DWORD NXCL_Session::OpenNodeDCIList(DWORD dwNodeId, NXC_DCI_LIST **ppItemList)
    if (dwRetCode == RCC_SUCCESS)
    {
       // Wait for DCI list end or for disconnection
-      dwRetCode = WaitForSync(INFINITE);
+      dwRetCode = WaitForSync(SYNC_DCI_LIST, INFINITE);
       if (dwRetCode == RCC_SUCCESS)
       {
          *ppItemList = m_pItemList;
@@ -437,7 +449,7 @@ DWORD NXCL_Session::OpenNodeDCIList(DWORD dwNodeId, NXC_DCI_LIST **ppItemList)
    }
    else
    {
-      UnlockSyncOp();
+      UnlockSyncOp(SYNC_DCI_LIST);
       free(m_pItemList);
    }
 
@@ -456,7 +468,7 @@ DWORD NXCL_Session::LoadEventDB(void)
    DWORD dwRetCode, dwRqId;
 
    dwRqId = CreateRqId();
-   PrepareForSync();
+   PrepareForSync(SYNC_EVENT_DB);
 
    DestroyEventDB();
    MutexLock(m_mutexEventAccess, INFINITE);
@@ -469,9 +481,9 @@ DWORD NXCL_Session::LoadEventDB(void)
 
    /* TODO: this probably should be recoded as loop with calls to WaitForMessage() */
    if (dwRetCode == RCC_SUCCESS)
-      dwRetCode = WaitForSync(INFINITE);
+      dwRetCode = WaitForSync(SYNC_EVENT_DB, INFINITE);
    else
-      UnlockSyncOp();
+      UnlockSyncOp(SYNC_EVENT_DB);
 
    MutexUnlock(m_mutexEventAccess);
    return dwRetCode;
@@ -662,7 +674,7 @@ void NXCL_Session::ProcessUserDBRecord(CSCPMessage *pMsg)
    switch(pMsg->GetCode())
    {
       case CMD_USER_DB_EOF:
-         CompleteSync(RCC_SUCCESS);
+         CompleteSync(SYNC_USER_DB, RCC_SUCCESS);
          break;
       case CMD_USER_DATA:
       case CMD_GROUP_DATA:
@@ -780,7 +792,7 @@ DWORD NXCL_Session::LoadUserDB(void)
    DWORD dwRetCode, dwRqId;
 
    dwRqId = CreateRqId();
-   PrepareForSync();
+   PrepareForSync(SYNC_USER_DB);
    DestroyUserDB();
 
    msg.SetCode(CMD_LOAD_USER_DB);
@@ -791,13 +803,13 @@ DWORD NXCL_Session::LoadUserDB(void)
 
    if (dwRetCode == RCC_SUCCESS)
    {
-      dwRetCode = WaitForSync(INFINITE);
+      dwRetCode = WaitForSync(SYNC_USER_DB, INFINITE);
       if (dwRetCode == RCC_SUCCESS)
          m_dwFlags |= NXC_SF_USERDB_LOADED;
    }
    else
    {
-      UnlockSyncOp();
+      UnlockSyncOp(SYNC_USER_DB);
    }
 
    return dwRetCode;
index e327084..60b9fde 100644 (file)
@@ -235,3 +235,65 @@ DWORD LIBNXCL_EXPORTABLE NXCModifyTrap(NXC_SESSION hSession, NXC_TRAP_CFG_ENTRY
 
    return ((NXCL_Session *)hSession)->WaitForRCC(dwRqId);
 }
+
+
+//
+// Process SNMP trap log records coming from server
+//
+
+void ProcessTrapLogRecords(NXCL_Session *pSession, CSCPMessage *pMsg)
+{
+   DWORD i, dwNumRecords, dwId;
+   NXC_SNMP_TRAP_LOG_RECORD rec;
+   int nOrder;
+
+   dwNumRecords = pMsg->GetVariableLong(VID_NUM_RECORDS);
+   nOrder = (int)pMsg->GetVariableShort(VID_RECORDS_ORDER);
+   DebugPrintf(_T("ProcessTrapLogRecords(): %d records in message, in %s order"),
+               dwNumRecords, (nOrder == RECORD_ORDER_NORMAL) ? _T("normal") : _T("reversed"));
+   for(i = 0, dwId = VID_TRAP_LOG_MSG_BASE; i < dwNumRecords; i++)
+   {
+      rec.qwId = pMsg->GetVariableInt64(dwId++);
+      rec.dwTimeStamp = pMsg->GetVariableLong(dwId++);
+      rec.dwIpAddr = pMsg->GetVariableShort(dwId++);
+      rec.dwObjectId = pMsg->GetVariableLong(dwId++);
+      pMsg->GetVariableStr(dwId++, rec.szTrapOID, MAX_DB_STRING);
+      rec.pszTrapVarbinds = pMsg->GetVariableStr(dwId++);
+
+      // Call client's callback to handle new record
+      pSession->CallEventHandler(NXC_EVENT_NEW_SNMP_TRAP, nOrder, &rec);
+      free(rec.pszTrapVarbinds);
+   }
+
+   // Notify requestor thread if all messages was received
+   if (pMsg->IsEndOfSequence())
+      pSession->CompleteSync(SYNC_TRAP_LOG, RCC_SUCCESS);
+}
+
+
+//
+// Synchronize trap log
+// This function is NOT REENTRANT
+//
+
+DWORD LIBNXCL_EXPORTABLE NXCSyncSNMPTrapLog(NXC_SESSION hSession, DWORD dwMaxRecords)
+{
+   CSCPMessage msg;
+   DWORD dwRetCode, dwRqId;
+
+   dwRqId = ((NXCL_Session *)hSession)->CreateRqId();
+   ((NXCL_Session *)hSession)->PrepareForSync(SYNC_TRAP_LOG);
+
+   msg.SetCode(CMD_GET_TRAP_LOG);
+   msg.SetId(dwRqId);
+   msg.SetVariable(VID_MAX_RECORDS, dwMaxRecords);
+   ((NXCL_Session *)hSession)->SendMsg(&msg);
+
+   dwRetCode = ((NXCL_Session *)hSession)->WaitForRCC(dwRqId);
+   if (dwRetCode == RCC_SUCCESS)
+      dwRetCode = ((NXCL_Session *)hSession)->WaitForSync(SYNC_TRAP_LOG, INFINITE);
+   else
+      ((NXCL_Session *)hSession)->UnlockSyncOp(SYNC_TRAP_LOG);
+
+   return dwRetCode;
+}
index a24f0e2..dcab385 100644 (file)
@@ -1,6 +1,6 @@
 /* 
 ** NetXMS - Network Management System
-** Copyright (C) 2003, 2004, 2005 Victor Kirhenshtein
+** Copyright (C) 2003, 2004, 2005, 2006 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
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software
 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 **
-** $module: debug.cpp
+** File: debug.cpp
 **
 **/
 
index 8bcf897..d8a19bb 100644 (file)
@@ -1,6 +1,6 @@
 /* 
 ** NetXMS - Network Management System
-** Copyright (C) 2003, 2004, 2005 NetXMS Team
+** Copyright (C) 2003, 2004, 2005, 2006 NetXMS Team
 **
 ** 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
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software
 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 **
-** $module: main.cpp
+** File: main.cpp
 **
 **/
 
index 2fb8083..47051ed 100644 (file)
@@ -363,6 +363,7 @@ THREAD_RESULT THREAD_CALL NodePollManager(void *pArg)
    else
       iNumDiscoveryPollers = 0;
    m_iNumPollers = iNumStatusPollers + iNumConfigPollers + iNumDiscoveryPollers + iNumRoutePollers;
+   DbgPrintf(AF_DEBUG_MISC, "NodePollManager: %d pollers to start", m_iNumPollers);
 
    // Prepare static data
    m_pPollerState = (__poller_state *)malloc(sizeof(__poller_state) * m_iNumPollers);
index 053fb95..4dfaba9 100644 (file)
@@ -1,6 +1,6 @@
 /* 
 ** NetXMS - Network Management System
-** Copyright (C) 2003, 2004, 2005 Victor Kirhenshtein
+** Copyright (C) 2003, 2004, 2005, 2006 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
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software
 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 **
-** $module: session.cpp
+** File: session.cpp
 **
 **/
 
@@ -190,6 +190,7 @@ ClientSession::ClientSession(SOCKET hSocket, DWORD dwHostAddr)
    m_hUpdateThread = INVALID_THREAD_HANDLE;
    m_mutexSendEvents = MutexCreate();
    m_mutexSendSyslog = MutexCreate();
+   m_mutexSendTrapLog = MutexCreate();
    m_mutexSendObjects = MutexCreate();
    m_mutexSendAlarms = MutexCreate();
    m_mutexSendActions = MutexCreate();
@@ -224,6 +225,7 @@ ClientSession::~ClientSession()
    safe_free(m_pMsgBuffer);
    MutexDestroy(m_mutexSendEvents);
    MutexDestroy(m_mutexSendSyslog);
+   MutexDestroy(m_mutexSendTrapLog);
    MutexDestroy(m_mutexSendObjects);
    MutexDestroy(m_mutexSendAlarms);
    MutexDestroy(m_mutexSendActions);
@@ -526,7 +528,7 @@ void ClientSession::UpdateThread(void)
       {
          case INFO_CAT_EVENT:
             MutexLock(m_mutexSendEvents, INFINITE);
-            m_pSendQueue->Put(CreateRawCSCPMessage(CMD_EVENT, 0, sizeof(NXC_EVENT), pUpdate->pData, NULL));
+            m_pSendQueue->Put(CreateRawCSCPMessage(CMD_EVENT, 0, 0, sizeof(NXC_EVENT), pUpdate->pData, NULL));
             MutexUnlock(m_mutexSendEvents);
             free(pUpdate->pData);
             break;
@@ -538,6 +540,12 @@ void ClientSession::UpdateThread(void)
             MutexUnlock(m_mutexSendSyslog);
             free(pUpdate->pData);
             break;
+         case INFO_CAT_SNMP_TRAP:
+            MutexLock(m_mutexSendTrapLog, INFINITE);
+            SendMessage((CSCPMessage *)pUpdate->pData);
+            MutexUnlock(m_mutexSendTrapLog);
+            delete (CSCPMessage *)pUpdate->pData;
+            break;
          case INFO_CAT_OBJECT_CHANGE:
             MutexLock(m_mutexSendObjects, INFINITE);
             msg.SetCode(CMD_OBJECT_UPDATE);
@@ -913,6 +921,9 @@ void ClientSession::ProcessingThread(void)
          case CMD_KILL_SESSION:
             KillSession(pMsg);
             break;
+         case CMD_GET_TRAP_LOG:
+            SendTrapLog(pMsg);
+            break;
          default:
             // Pass message to loaded modules
             for(i = 0; i < g_dwNumModules; i++)
@@ -1402,6 +1413,7 @@ void ClientSession::SendAllEvents(CSCPMessage *pRequest)
    NXC_EVENT event;
    DWORD dwRqId, dwMaxRecords, dwNumRows;
    TCHAR szQuery[1024];
+   WORD wFlags;
 #ifndef UNICODE
    char szBuffer[MAX_EVENT_MSG_LENGTH];
 #endif
@@ -1440,19 +1452,27 @@ void ClientSession::SendAllEvents(CSCPMessage *pRequest)
          _sntprintf(szQuery, 1024,
                     _T("SELECT event_id,event_code,event_timestamp,event_source,")
                     _T("event_severity,event_message FROM event_log ")
-                    _T("ORDER BY event_timestamp LIMIT %u OFFSET %u"),
+                    _T("ORDER BY event_id LIMIT %u OFFSET %u"),
                     dwMaxRecords, dwNumRows - min(dwNumRows, dwMaxRecords));
+         wFlags = 0;
          break;
       case DB_SYNTAX_MSSQL:
          _sntprintf(szQuery, 1024,
                     _T("SELECT TOP %u event_id,event_code,event_timestamp,event_source,")
-                    _T("event_severity,event_message INTO temp_log_%d FROM event_log ")
-                    _T("ORDER BY event_timestamp DESC"), dwMaxRecords, m_dwIndex);
-         DBQuery(g_hCoreDB, szQuery);
-         _sntprintf(szQuery, 1024, _T("SELECT * FROM temp_log_%d ORDER BY event_timestamp"), m_dwIndex);
+                    _T("event_severity,event_message FROM event_log ")
+                    _T("ORDER BY event_id DESC"), dwMaxRecords);
+         wFlags = MF_REVERSE_ORDER;
+         break;
+      case DB_SYNTAX_ORACLE:
+         _sntprintf(szQuery, 1024,
+                    _T("SELECT event_id,event_code,event_timestamp,event_source,")
+                    _T("event_severity,event_message FROM event_log ")
+                    _T("WHERE ROWNUM <= %u ORDER BY event_id DESC"), dwMaxRecords);
+         wFlags = MF_REVERSE_ORDER;
          break;
       default:
          szQuery[0] = 0;
+         wFlags = 0;
          break;
    }
    hResult = DBAsyncSelect(g_hCoreDB, szQuery);
@@ -1477,7 +1497,8 @@ void ClientSession::SendAllEvents(CSCPMessage *pRequest)
          ((WCHAR *)event.szMessage)[MAX_EVENT_MSG_LENGTH - 1] = 0;
 #endif
          SwapWideString((WCHAR *)event.szMessage);
-         m_pSendQueue->Put(CreateRawCSCPMessage(CMD_EVENT, dwRqId, sizeof(NXC_EVENT), &event, NULL));
+         m_pSendQueue->Put(CreateRawCSCPMessage(CMD_EVENT, dwRqId, wFlags,
+                                                sizeof(NXC_EVENT), &event, NULL));
       }
       DBFreeAsyncResult(hResult);
    }
@@ -1487,12 +1508,6 @@ void ClientSession::SendAllEvents(CSCPMessage *pRequest)
    SendMessage(&msg);
 
    MutexUnlock(m_mutexSendEvents);
-
-   if (g_dwDBSyntax == DB_SYNTAX_MSSQL)
-   {
-      _stprintf(szQuery, _T("DROP TABLE temp_log_%d"), m_dwIndex);
-      DBQuery(g_hCoreDB, szQuery);
-   }
 }
 
 
@@ -1641,24 +1656,6 @@ void ClientSession::OnNewEvent(Event *pEvent)
 
 
 //
-// Handler for new syslog messages
-//
-
-void ClientSession::OnSyslogMessage(NX_LOG_RECORD *pRec)
-{
-   UPDATE_INFO *pUpdate;
-
-   if (IsAuthenticated() && (m_dwActiveChannels & NXC_CHANNEL_SYSLOG))
-   {
-      pUpdate = (UPDATE_INFO *)malloc(sizeof(UPDATE_INFO));
-      pUpdate->dwCategory = INFO_CAT_SYSLOG_MSG;
-      pUpdate->pData = nx_memdup(pRec, sizeof(NX_LOG_RECORD));
-      m_pUpdateQueue->Put(pUpdate);
-   }
-}
-
-
-//
 // Handler for object changes
 //
 
@@ -2646,7 +2643,7 @@ void ClientSession::GetCollectedData(CSCPMessage *pRequest)
 
             // Prepare and send raw message with fetched data
             m_pSendQueue->Put(
-               CreateRawCSCPMessage(CMD_DCI_DATA, pRequest->GetId(), 
+               CreateRawCSCPMessage(CMD_DCI_DATA, pRequest->GetId(), 0,
                                     dwNumRows * m_dwRowSize[iType] + sizeof(DCI_DATA_HEADER),
                                     pData, NULL));
             free(pData);
@@ -5512,114 +5509,6 @@ void ClientSession::ChangeSubscription(CSCPMessage *pRequest)
 
 
 //
-// Get latest syslog records
-//
-
-void ClientSession::SendSyslog(CSCPMessage *pRequest)
-{
-   CSCPMessage msg;
-   DWORD dwRqId, dwMaxRecords, dwNumRows, dwId;
-   DB_RESULT hTempResult;
-   DB_ASYNC_RESULT hResult;
-   TCHAR szQuery[1024], szBuffer[1024];
-
-   dwRqId = pRequest->GetId();
-   dwMaxRecords = pRequest->GetVariableLong(VID_MAX_RECORDS);
-
-   // Send confirmation message
-   msg.SetCode(CMD_REQUEST_COMPLETED);
-   msg.SetId(dwRqId);
-   msg.SetVariable(VID_RCC, RCC_SUCCESS);
-   SendMessage(&msg);
-   msg.DeleteAllVariables();
-   msg.SetCode(CMD_SYSLOG_RECORDS);
-
-   MutexLock(m_mutexSendSyslog, INFINITE);
-
-   // Retrieve events from database
-   switch(g_dwDBSyntax)
-   {
-      case DB_SYNTAX_MYSQL:
-      case DB_SYNTAX_PGSQL:
-      case DB_SYNTAX_SQLITE:
-         hTempResult = DBSelect(g_hCoreDB, _T("SELECT count(*) FROM syslog"));
-         if (hTempResult != NULL)
-         {
-            if (DBGetNumRows(hTempResult) > 0)
-            {
-               dwNumRows = DBGetFieldULong(hTempResult, 0, 0);
-            }
-            else
-            {
-               dwNumRows = 0;
-            }
-            DBFreeResult(hTempResult);
-         }
-         _sntprintf(szQuery, 1024,
-                    _T("SELECT msg_id,msg_timestamp,facility,severity,")
-                    _T("source_object_id,hostname,msg_tag,msg_text FROM syslog ")
-                    _T("ORDER BY msg_timestamp LIMIT %u OFFSET %u"),
-                    dwMaxRecords, dwNumRows - min(dwNumRows, dwMaxRecords));
-         break;
-      case DB_SYNTAX_MSSQL:
-         _sntprintf(szQuery, 1024,
-                    _T("SELECT TOP %d msg_id,msg_timestamp,facility,severity,")
-                    _T("source_object_id,hostname,msg_tag,msg_text ")
-                    _T("INTO temp_syslog_%d FROM syslog ")
-                    _T("ORDER BY msg_timestamp DESC"), dwMaxRecords, m_dwIndex);
-         DBQuery(g_hCoreDB, szQuery);
-         _sntprintf(szQuery, 1024,
-                    _T("SELECT * FROM temp_syslog_%d ORDER BY msg_timestamp"), m_dwIndex);
-         break;
-      default:
-         szQuery[0] = 0;
-         break;
-   }
-   hResult = DBAsyncSelect(g_hCoreDB, szQuery);
-   if (hResult != NULL)
-   {
-      // Send events, one per message
-      for(dwId = VID_SYSLOG_MSG_BASE, dwNumRows = 0; DBFetch(hResult); dwNumRows++)
-      {
-         if (dwNumRows == 10)
-         {
-            msg.SetVariable(VID_NUM_RECORDS, dwNumRows);
-            SendMessage(&msg);
-            msg.DeleteAllVariables();
-            dwNumRows = 0;
-            dwId = VID_SYSLOG_MSG_BASE;
-         }
-         msg.SetVariable(dwId++, DBGetFieldAsyncUInt64(hResult, 0));
-         msg.SetVariable(dwId++, DBGetFieldAsyncULong(hResult, 1));
-         msg.SetVariable(dwId++, (WORD)DBGetFieldAsyncLong(hResult, 2));
-         msg.SetVariable(dwId++, (WORD)DBGetFieldAsyncLong(hResult, 3));
-         msg.SetVariable(dwId++, DBGetFieldAsyncULong(hResult, 4));
-         msg.SetVariable(dwId++, DBGetFieldAsync(hResult, 5, szBuffer, 1024));
-         msg.SetVariable(dwId++, DBGetFieldAsync(hResult, 6, szBuffer, 1024));
-         DBGetFieldAsync(hResult, 7, szBuffer, 1024);
-         DecodeSQLString(szBuffer);
-         msg.SetVariable(dwId++, szBuffer);
-      }
-      DBFreeAsyncResult(hResult);
-
-      // Send remaining records with End-Of-Sequence notification
-      msg.SetVariable(VID_NUM_RECORDS, dwNumRows);
-      msg.SetEndOfSequence();
-      SendMessage(&msg);
-      msg.DeleteAllVariables();
-   }
-
-   MutexUnlock(m_mutexSendSyslog);
-
-   if (g_dwDBSyntax == DB_SYNTAX_MSSQL)
-   {
-      _stprintf(szQuery, _T("DROP TABLE temp_syslog_%d"), m_dwIndex);
-      DBQuery(g_hCoreDB, szQuery);
-   }
-}
-
-
-//
 // Send list of log policies
 //
 
@@ -6152,3 +6041,258 @@ void ClientSession::KillSession(CSCPMessage *pRequest)
    }
    SendMessage(&msg);
 }
+
+
+//
+// Handler for new syslog messages
+//
+
+void ClientSession::OnSyslogMessage(NX_LOG_RECORD *pRec)
+{
+   UPDATE_INFO *pUpdate;
+
+   if (IsAuthenticated() && (m_dwActiveChannels & NXC_CHANNEL_SYSLOG))
+   {
+      pUpdate = (UPDATE_INFO *)malloc(sizeof(UPDATE_INFO));
+      pUpdate->dwCategory = INFO_CAT_SYSLOG_MSG;
+      pUpdate->pData = nx_memdup(pRec, sizeof(NX_LOG_RECORD));
+      m_pUpdateQueue->Put(pUpdate);
+   }
+}
+
+
+//
+// Get latest syslog records
+//
+
+void ClientSession::SendSyslog(CSCPMessage *pRequest)
+{
+   CSCPMessage msg;
+   DWORD dwMaxRecords, dwNumRows, dwId;
+   DB_RESULT hTempResult;
+   DB_ASYNC_RESULT hResult;
+   TCHAR szQuery[1024], szBuffer[1024];
+   WORD wRecOrder;
+
+   wRecOrder = ((g_dwDBSyntax == DB_SYNTAX_MSSQL) || (g_dwDBSyntax == DB_SYNTAX_ORACLE)) ? RECORD_ORDER_REVERSED : RECORD_ORDER_NORMAL;
+   dwMaxRecords = pRequest->GetVariableLong(VID_MAX_RECORDS);
+
+   // Send confirmation message
+   msg.SetCode(CMD_REQUEST_COMPLETED);
+   msg.SetId(pRequest->GetId());
+   msg.SetVariable(VID_RCC, RCC_SUCCESS);
+   SendMessage(&msg);
+   msg.DeleteAllVariables();
+   msg.SetCode(CMD_SYSLOG_RECORDS);
+
+   MutexLock(m_mutexSendSyslog, INFINITE);
+
+   // Retrieve events from database
+   switch(g_dwDBSyntax)
+   {
+      case DB_SYNTAX_MYSQL:
+      case DB_SYNTAX_PGSQL:
+      case DB_SYNTAX_SQLITE:
+         hTempResult = DBSelect(g_hCoreDB, _T("SELECT count(*) FROM syslog"));
+         if (hTempResult != NULL)
+         {
+            if (DBGetNumRows(hTempResult) > 0)
+            {
+               dwNumRows = DBGetFieldULong(hTempResult, 0, 0);
+            }
+            else
+            {
+               dwNumRows = 0;
+            }
+            DBFreeResult(hTempResult);
+         }
+         _sntprintf(szQuery, 1024,
+                    _T("SELECT msg_id,msg_timestamp,facility,severity,")
+                    _T("source_object_id,hostname,msg_tag,msg_text FROM syslog ")
+                    _T("ORDER BY msg_id LIMIT %u OFFSET %u"),
+                    dwMaxRecords, dwNumRows - min(dwNumRows, dwMaxRecords));
+         break;
+      case DB_SYNTAX_MSSQL:
+         _sntprintf(szQuery, 1024,
+                    _T("SELECT TOP %d msg_id,msg_timestamp,facility,severity,")
+                    _T("source_object_id,hostname,msg_tag,msg_text FROM syslog ")
+                    _T("ORDER BY msg_id DESC"), dwMaxRecords);
+         break;
+      case DB_SYNTAX_ORACLE:
+         _sntprintf(szQuery, 1024,
+                    _T("SELECT msg_id,msg_timestamp,facility,severity,")
+                    _T("source_object_id,hostname,msg_tag,msg_text FROM syslog ")
+                    _T("WHERE ROWNUM <= %u ORDER BY msg_id DESC"), dwMaxRecords);
+         break;
+      default:
+         szQuery[0] = 0;
+         break;
+   }
+   hResult = DBAsyncSelect(g_hCoreDB, szQuery);
+   if (hResult != NULL)
+   {
+      // Send events, one per message
+      for(dwId = VID_SYSLOG_MSG_BASE, dwNumRows = 0; DBFetch(hResult); dwNumRows++)
+      {
+         if (dwNumRows == 10)
+         {
+            msg.SetVariable(VID_NUM_RECORDS, dwNumRows);
+            msg.SetVariable(VID_RECORDS_ORDER, wRecOrder);
+            SendMessage(&msg);
+            msg.DeleteAllVariables();
+            dwNumRows = 0;
+            dwId = VID_SYSLOG_MSG_BASE;
+         }
+         msg.SetVariable(dwId++, DBGetFieldAsyncUInt64(hResult, 0));
+         msg.SetVariable(dwId++, DBGetFieldAsyncULong(hResult, 1));
+         msg.SetVariable(dwId++, (WORD)DBGetFieldAsyncLong(hResult, 2));
+         msg.SetVariable(dwId++, (WORD)DBGetFieldAsyncLong(hResult, 3));
+         msg.SetVariable(dwId++, DBGetFieldAsyncULong(hResult, 4));
+         msg.SetVariable(dwId++, DBGetFieldAsync(hResult, 5, szBuffer, 1024));
+         msg.SetVariable(dwId++, DBGetFieldAsync(hResult, 6, szBuffer, 1024));
+         DBGetFieldAsync(hResult, 7, szBuffer, 1024);
+         DecodeSQLString(szBuffer);
+         msg.SetVariable(dwId++, szBuffer);
+      }
+      DBFreeAsyncResult(hResult);
+
+      // Send remaining records with End-Of-Sequence notification
+      msg.SetVariable(VID_NUM_RECORDS, dwNumRows);
+      msg.SetVariable(VID_RECORDS_ORDER, wRecOrder);
+      msg.SetEndOfSequence();
+      SendMessage(&msg);
+      msg.DeleteAllVariables();
+   }
+
+   MutexUnlock(m_mutexSendSyslog);
+}
+
+
+//
+// Handler for new traps
+//
+
+void ClientSession::OnNewSNMPTrap(CSCPMessage *pMsg)
+{
+   UPDATE_INFO *pUpdate;
+
+   if (IsAuthenticated() && (m_dwActiveChannels & NXC_CHANNEL_SNMP_TRAPS))
+   {
+      pUpdate = (UPDATE_INFO *)malloc(sizeof(UPDATE_INFO));
+      pUpdate->dwCategory = INFO_CAT_SNMP_TRAP;
+      pUpdate->pData = new CSCPMessage(pMsg);
+      m_pUpdateQueue->Put(pUpdate);
+   }
+}
+
+
+//
+// Send collected trap log
+//
+
+void ClientSession::SendTrapLog(CSCPMessage *pRequest)
+{
+   CSCPMessage msg;
+   TCHAR szBuffer[4096], szQuery[1024];
+   DWORD dwId, dwNumRows, dwMaxRecords;
+   DB_RESULT hTempResult;
+   DB_ASYNC_RESULT hResult;
+   WORD wRecOrder;
+
+   wRecOrder = ((g_dwDBSyntax == DB_SYNTAX_MSSQL) || (g_dwDBSyntax == DB_SYNTAX_ORACLE)) ? RECORD_ORDER_REVERSED : RECORD_ORDER_NORMAL;
+   dwMaxRecords = pRequest->GetVariableLong(VID_MAX_RECORDS);
+
+   msg.SetCode(CMD_REQUEST_COMPLETED);
+   msg.SetId(pRequest->GetId());
+
+   if (m_dwSystemAccess & SYSTEM_ACCESS_VIEW_TRAP_LOG)
+   {
+      msg.SetVariable(VID_RCC, RCC_SUCCESS);
+      SendMessage(&msg);
+      msg.DeleteAllVariables();
+      msg.SetCode(CMD_TRAP_LOG_RECORDS);
+
+      MutexLock(m_mutexSendTrapLog, INFINITE);
+
+      // Retrieve trap log records from database
+      switch(g_dwDBSyntax)
+      {
+         case DB_SYNTAX_MYSQL:
+         case DB_SYNTAX_PGSQL:
+         case DB_SYNTAX_SQLITE:
+            hTempResult = DBSelect(g_hCoreDB, _T("SELECT count(*) FROM snmp_trap_log"));
+            if (hTempResult != NULL)
+            {
+               if (DBGetNumRows(hTempResult) > 0)
+               {
+                  dwNumRows = DBGetFieldULong(hTempResult, 0, 0);
+               }
+               else
+               {
+                  dwNumRows = 0;
+               }
+               DBFreeResult(hTempResult);
+            }
+            _sntprintf(szQuery, 1024,
+                       _T("SELECT trap_id,trap_timestamp,ip_addr,object_id,")
+                       _T("trap_oid,trap_varlist FROM snmp_trap_log ")
+                       _T("ORDER BY trap_id LIMIT %u OFFSET %u"),
+                       dwMaxRecords, dwNumRows - min(dwNumRows, dwMaxRecords));
+            break;
+         case DB_SYNTAX_MSSQL:
+            _sntprintf(szQuery, 1024,
+                       _T("SELECT TOP %u trap_id,trap_timestamp,ip_addr,object_id,")
+                       _T("trap_oid,trap_varlist FROM snmp_trap_log ")
+                       _T("ORDER BY trap_id DESC"), dwMaxRecords);
+            break;
+         case DB_SYNTAX_ORACLE:
+            _sntprintf(szQuery, 1024,
+                       _T("SELECT trap_id,trap_timestamp,ip_addr,object_id,")
+                       _T("trap_oid,trap_varlist FROM snmp_trap_log ")
+                       _T("WHERE ROWNUM <= %u ORDER BY msg_id DESC"),
+                       dwMaxRecords);
+            break;
+         default:
+            szQuery[0] = 0;
+            break;
+      }
+      hResult = DBAsyncSelect(g_hCoreDB, szQuery);
+      if (hResult != NULL)
+      {
+         // Send events, one per message
+         for(dwId = VID_TRAP_LOG_MSG_BASE, dwNumRows = 0; DBFetch(hResult); dwNumRows++)
+         {
+            if (dwNumRows == 10)
+            {
+               msg.SetVariable(VID_NUM_RECORDS, dwNumRows);
+               msg.SetVariable(VID_RECORDS_ORDER, wRecOrder);
+               SendMessage(&msg);
+               msg.DeleteAllVariables();
+               dwNumRows = 0;
+               dwId = VID_TRAP_LOG_MSG_BASE;
+            }
+            msg.SetVariable(dwId++, DBGetFieldAsyncUInt64(hResult, 0));
+            msg.SetVariable(dwId++, DBGetFieldAsyncULong(hResult, 1));
+            msg.SetVariable(dwId++, DBGetFieldAsyncIPAddr(hResult, 2));
+            msg.SetVariable(dwId++, DBGetFieldAsyncULong(hResult, 3));
+            msg.SetVariable(dwId++, DBGetFieldAsync(hResult, 4, szBuffer, 256));
+            DBGetFieldAsync(hResult, 7, szBuffer, 4096);
+            DecodeSQLString(szBuffer);
+            msg.SetVariable(dwId++, szBuffer);
+         }
+         DBFreeAsyncResult(hResult);
+
+         // Send remaining records with End-Of-Sequence notification
+         msg.SetVariable(VID_NUM_RECORDS, dwNumRows);
+         msg.SetVariable(VID_RECORDS_ORDER, wRecOrder);
+         msg.SetEndOfSequence();
+      }
+
+      MutexUnlock(m_mutexSendTrapLog);
+   }
+   else
+   {
+      msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
+   }
+   SendMessage(&msg);
+}
index 0eaf0ec..3a84dd5 100644 (file)
@@ -189,13 +189,23 @@ static void GenerateTrapEvent(DWORD dwObjectId, DWORD dwIndex, SNMP_PDU *pdu)
 
 
 //
+// Handler for EnumerateSessions()
+//
+
+static void BroadcastNewTrap(ClientSession *pSession, void *pArg)
+{
+   pSession->OnNewSNMPTrap((CSCPMessage *)pArg);
+}
+
+
+//
 // Process trap
 //
 
 static void ProcessTrap(SNMP_PDU *pdu, struct sockaddr_in *pOrigin)
 {
    DWORD i, dwOriginAddr, dwBufPos, dwBufSize, dwMatchLen, dwMatchIdx;
-   TCHAR *pszTrapArgs, *pszEscTrapArgs, szBuffer[4096], szQuery[8192];
+   TCHAR *pszTrapArgs, szBuffer[4096];
    SNMP_Variable *pVar;
    Node *pNode;
    int iResult;
@@ -210,6 +220,10 @@ static void ProcessTrap(SNMP_PDU *pdu, struct sockaddr_in *pOrigin)
    // Write trap to log if required
    if (m_bLogAllTraps)
    {
+      CSCPMessage msg;
+      TCHAR *pszEscTrapArgs, szQuery[8192];
+      DWORD dwTimeStamp = (DWORD)time(NULL);
+
       dwBufSize = pdu->GetNumVariables() * 4096 + 16;
       pszTrapArgs = (TCHAR *)malloc(sizeof(TCHAR) * dwBufSize);
       pszTrapArgs[0] = 0;
@@ -222,16 +236,31 @@ static void ProcessTrap(SNMP_PDU *pdu, struct sockaddr_in *pOrigin)
                                 pVar->GetValueAsString(szBuffer, 3000));
       }
 
+      // Write new trap to database
       pszEscTrapArgs = EncodeSQLString(pszTrapArgs);
       _sntprintf(szQuery, 8192, _T("INSERT INTO snmp_trap_log (trap_id,timestamp,")
                                 _T("ip_addr,object_id,trap_oid,trap_varlist) VALUES ")
                                 _T("(") INT64_FMT _T(",%d,'%s',%d,'%s','%s')"),
-                 m_qnTrapId++, (DWORD)time(NULL), IpToStr(dwOriginAddr, szBuffer),
-                 (pNode != NULL) ? pNode->Id() : 0, pdu->GetTrapId()->GetValueAsText(),
+                 m_qnTrapId, dwTimeStamp, IpToStr(dwOriginAddr, szBuffer),
+                 (pNode != NULL) ? pNode->Id() : (DWORD)0, pdu->GetTrapId()->GetValueAsText(),
                  pszEscTrapArgs);
-      free(pszTrapArgs);
       free(pszEscTrapArgs);
       QueueSQLRequest(szQuery);
+
+      // Notify connected clients
+      msg.SetCode(CMD_TRAP_LOG_RECORDS);
+      msg.SetVariable(VID_NUM_RECORDS, (DWORD)1);
+      msg.SetVariable(VID_RECORDS_ORDER, (WORD)RECORD_ORDER_NORMAL);
+      msg.SetVariable(VID_TRAP_LOG_MSG_BASE, (QWORD)m_qnTrapId);
+      msg.SetVariable(VID_TRAP_LOG_MSG_BASE + 1, dwTimeStamp);
+      msg.SetVariable(VID_TRAP_LOG_MSG_BASE + 2, dwOriginAddr);
+      msg.SetVariable(VID_TRAP_LOG_MSG_BASE + 3, (pNode != NULL) ? pNode->Id() : (DWORD)0);
+      msg.SetVariable(VID_TRAP_LOG_MSG_BASE + 4, (TCHAR *)pdu->GetTrapId()->GetValueAsText());
+      msg.SetVariable(VID_TRAP_LOG_MSG_BASE + 5, pszTrapArgs);
+      EnumerateClientSessions(BroadcastNewTrap, &msg);
+      free(pszTrapArgs);
+
+      m_qnTrapId++;
    }
 
    // Process trap if it is coming from host registered in database
index b252c32..a95803a 100644 (file)
 #include <string.h>
 #include <stdarg.h>
 
-#ifdef _WIN32
-#define _GETOPT_H_ 1    /* Prevent including getopt.h from net-snmp */
-#define HAVE_SOCKLEN_T  /* Prevent defining socklen_t in net-snmp */
-#endif   /* _WIN32 */
-
 #define SHOW_FLAG_VALUE(x) _T("  %-32s = %d\n"), _T(#x), (g_dwFlags & x) ? 1 : 0
 
 
@@ -230,6 +225,7 @@ typedef void * HSNMPSESSION;
 #define INFO_CAT_ALARM           3
 #define INFO_CAT_ACTION          4
 #define INFO_CAT_SYSLOG_MSG      5
+#define INFO_CAT_SNMP_TRAP       6
 
 
 //
@@ -317,6 +313,7 @@ private:
    THREAD m_hUpdateThread;
    MUTEX m_mutexSendEvents;
    MUTEX m_mutexSendSyslog;
+   MUTEX m_mutexSendTrapLog;
    MUTEX m_mutexSendObjects;
    MUTEX m_mutexSendAlarms;
    MUTEX m_mutexSendActions;
@@ -449,6 +446,7 @@ private:
    void DeleteScript(CSCPMessage *pRequest);
    void SendSessionList(DWORD dwRqId);
    void KillSession(CSCPMessage *pRequest);
+   void SendTrapLog(CSCPMessage *pRequest);
 
 public:
    ClientSession(SOCKET hSocket, DWORD dwHostAddr);
@@ -469,6 +467,7 @@ public:
    const TCHAR *GetClientInfo(void) { return m_szClientInfo; }
    DWORD GetUserId(void) { return m_dwUserId; }
    BOOL IsAuthenticated(void) { return (m_dwFlags & CSF_AUTHENTICATED) ? TRUE : FALSE; }
+   BOOL IsSubscribed(DWORD dwChannel) { return (m_dwActiveChannels & dwChannel) ? TRUE : FALSE; }
    WORD GetCurrentCmd(void) { return m_wCurrentCmd; }
    int GetCipher(void) { return (m_pCtx == NULL) ? -1 : m_pCtx->nCipher; }
 
@@ -477,6 +476,7 @@ public:
 
    void OnNewEvent(Event *pEvent);
    void OnSyslogMessage(NX_LOG_RECORD *pRec);
+   void OnNewSNMPTrap(CSCPMessage *pMsg);
    void OnObjectChange(NetObj *pObject);
    void OnUserDBUpdate(int iCode, DWORD dwUserId, NMS_USER *pUser, NMS_USER_GROUP *pGroup);
    void OnAlarmUpdate(DWORD dwCode, NXC_ALARM *pAlarm);
index 5a9a014..8d00f31 100644 (file)
@@ -78,6 +78,46 @@ static BOOL CreateConfigParam(TCHAR *pszName, TCHAR *pszValue, int iVisible, int
 
 
 //
+// Upgrade from V37 to V38
+//
+
+static BOOL H_UpgradeFromV37(void)
+{
+   static TCHAR m_szBatch[] =
+          "CREATE INDEX idx_event_log_event_timestamp ON event_log(event_timestamp)\n"
+          "CREATE INDEX idx_syslog_msg_timestamp ON syslog(msg_timestamp)\n"
+      "CREATE INDEX idx_snmp_trap_log_trap_timestamp ON snmp_trap_log(trap_timestamp)\n"
+      "<END>";
+
+   if (!CreateTable(_T("CREATE TABLE snmp_trap_log ("
+                                "trap_id $SQL:INT64 not null,"
+                                "trap_timestamp integer not null,"
+                                "ip_addr varchar(15) not null,"
+                                "object_id integer not null,"
+                                "trap_oid varchar(255) not null,"
+                                "trap_varlist $SQL:TEXT not null,"
+                                "PRIMARY KEY(trap_id))")))
+
+      if (!g_bIgnoreErrors)
+         return FALSE;
+
+   if (!SQLBatch(m_szBatch))
+      if (!g_bIgnoreErrors)
+         return FALSE;
+
+   if (!CreateConfigParam(_T("LogAllSNMPTraps"), _T("0"), 1, 1))
+      if (!g_bIgnoreErrors)
+         return FALSE;
+
+   if (!SQLQuery(_T("UPDATE config SET var_value='38' WHERE var_name='DBFormatVersion'")))
+      if (!g_bIgnoreErrors)
+         return FALSE;
+
+   return TRUE;
+}
+
+
+//
 // Upgrade from V36 to V37
 //
 
@@ -1582,6 +1622,7 @@ static struct
    { 34, H_UpgradeFromV34 },
    { 35, H_UpgradeFromV35 },
    { 36, H_UpgradeFromV36 },
+   { 37, H_UpgradeFromV37 },
    { 0, NULL }
 };