license for libnxdb and libnxsrv changed to LGPL
[public/netxms.git] / src / agent / core / trap.cpp
CommitLineData
5039dede
AK
1/*
2** NetXMS multiplatform core agent
3** Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Victor Kirhenshtein
4**
5** This program is free software; you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation; either version 2 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program; if not, write to the Free Software
17** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18**
19** File: trap.cpp
20**
21**/
22
23#include "nxagentd.h"
24#include <stdarg.h>
25
26
27//
28// Static data
29//
30
31static Queue *m_pTrapQueue = NULL;
32
33
34//
35// Trap sender
36//
37
38THREAD_RESULT THREAD_CALL TrapSender(void *pArg)
39{
40 CSCP_MESSAGE *pMsg;
41 DWORD i;
42 BOOL bTrapSent;
43
44 m_pTrapQueue = new Queue;
45 while(1)
46 {
47 pMsg = (CSCP_MESSAGE *)m_pTrapQueue->GetOrBlock();
48 if (pMsg == INVALID_POINTER_VALUE)
49 break;
50
51 bTrapSent = FALSE;
52
53 MutexLock(g_hSessionListAccess, INFINITE);
54 for(i = 0; i < g_dwMaxSessions; i++)
55 if (g_pSessionList[i] != NULL)
4685a2ad 56 if (g_pSessionList[i]->canAcceptTraps())
5039dede 57 {
e4a64da2 58 g_pSessionList[i]->sendRawMessage(pMsg);
5039dede
AK
59 bTrapSent = TRUE;
60 }
61 MutexUnlock(g_hSessionListAccess);
62
63 if (bTrapSent)
64 {
65 free(pMsg);
66 }
67 else
68 {
69 m_pTrapQueue->Insert(pMsg); // Re-queue trap
70 ThreadSleep(1);
71 }
72 }
73 delete m_pTrapQueue;
74 m_pTrapQueue = NULL;
c303351c 75 DebugPrintf(INVALID_INDEX, 1, _T("Trap sender thread terminated"));
5039dede
AK
76 return THREAD_OK;
77}
78
79
80//
81// Shutdown trap sender
82//
83
84void ShutdownTrapSender()
85{
86 m_pTrapQueue->SetShutdownMode();
87}
88
89
90//
91// Send trap to server
92//
93
94void SendTrap(DWORD dwEventCode, int iNumArgs, TCHAR **ppArgList)
95{
96 int i;
97 CSCPMessage msg;
98
c303351c 99 DebugPrintf(INVALID_INDEX, 5, _T("SendTrap(): event_code=%d, num_args=%d, arg[0]=\"%s\" arg[1]=\"%s\" arg[2]=\"%s\""),
9fcdfda7
VK
100 dwEventCode, iNumArgs,
101 (iNumArgs > 0) ? ppArgList[0] : _T("(null)"),
102 (iNumArgs > 1) ? ppArgList[1] : _T("(null)"),
103 (iNumArgs > 2) ? ppArgList[2] : _T("(null)"));
104
5039dede
AK
105 msg.SetCode(CMD_TRAP);
106 msg.SetId(0);
107 msg.SetVariable(VID_EVENT_CODE, dwEventCode);
108 msg.SetVariable(VID_NUM_ARGS, (WORD)iNumArgs);
109 for(i = 0; i < iNumArgs; i++)
110 msg.SetVariable(VID_EVENT_ARG_BASE + i, ppArgList[i]);
111 if (m_pTrapQueue != NULL)
112 m_pTrapQueue->Put(msg.CreateMessage());
113}
114
115
116//
117// Send trap - variant 2
118// Arguments:
119// dwEventCode - Event code
120// pszFormat - Parameter format string, each parameter represented by one character.
121// The following format characters can be used:
122// s - String
123// d - Decimal integer
124// x - Hex integer
125// a - IP address
126// i - Object ID
127// D - 64-bit decimal integer
128// X - 64-bit hex integer
129//
130
131void SendTrap(DWORD dwEventCode, const char *pszFormat, va_list args)
132{
133 int i, iNumArgs;
134 TCHAR *ppArgList[64];
135 static TCHAR badFormat[] = _T("BAD FORMAT");
136
137 iNumArgs = (pszFormat == NULL) ? 0 : (int)strlen(pszFormat);
138 for(i = 0; i < iNumArgs; i++)
139 {
140 switch(pszFormat[i])
141 {
142 case 's':
143 ppArgList[i] = va_arg(args, TCHAR *);
144 if (ppArgList[i] == NULL)
145 ppArgList[i] = (TCHAR *)_T("");
146 break;
147 case 'd':
148 ppArgList[i] = (char *)malloc(16);
149 sprintf(ppArgList[i], "%d", va_arg(args, LONG));
150 break;
151 case 'D':
152 ppArgList[i] = (char *)malloc(32);
153 sprintf(ppArgList[i], INT64_FMT, va_arg(args, INT64));
154 break;
155 case 'x':
156 case 'i':
157 ppArgList[i] = (char *)malloc(16);
158 sprintf(ppArgList[i], "0x%08X", va_arg(args, DWORD));
159 break;
160 case 'X':
161 ppArgList[i] = (char *)malloc(32);
162#ifdef _WIN32
163 sprintf(ppArgList[i], "0x%016I64X", va_arg(args, QWORD));
164#else
165 sprintf(ppArgList[i], "0x%016llX", va_arg(args, QWORD));
166#endif
167 break;
168 case 'a':
169 ppArgList[i] = (char *)malloc(16);
170 IpToStr(va_arg(args, DWORD), ppArgList[i]);
171 break;
172 default:
173 ppArgList[i] = badFormat;
174 break;
175 }
176 }
177
178 SendTrap(dwEventCode, iNumArgs, ppArgList);
179
180 for(i = 0; i < iNumArgs; i++)
181 if ((pszFormat[i] == 'd') || (pszFormat[i] == 'x') ||
182 (pszFormat[i] == 'D') || (pszFormat[i] == 'X') ||
183 (pszFormat[i] == 'i') || (pszFormat[i] == 'a'))
184 free(ppArgList[i]);
185}
186
187
188//
189// Send trap - variant 3
190// Same as variant 2, but uses argument list instead of va_list
191//
192
193void SendTrap(DWORD dwEventCode, const char *pszFormat, ...)
194{
195 va_list args;
196
197 va_start(args, pszFormat);
198 SendTrap(dwEventCode, pszFormat, args);
199 va_end(args);
200}