min/max calls replaced with std::min/std::max
[public/netxms.git] / src / appagent / client.cpp
1 /*
2 ** NetXMS - Network Management System
3 ** Copyright (C) 2003-2013 Victor Kirhenshtein
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU Lesser General Public License as published by
7 ** the Free Software Foundation; either version 3 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 Lesser 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: client.cpp
20 **
21 **/
22
23 #include "appagent-internal.h"
24
25 /**
26 * Connect to application agent
27 */
28 bool APPAGENT_EXPORTABLE AppAgentConnect(const TCHAR *name, HPIPE *hPipe)
29 {
30 #ifdef _WIN32
31 TCHAR pipeName[MAX_PATH];
32 _sntprintf(pipeName, MAX_PATH, _T("\\\\.\\pipe\\appagent.%s"), name);
33
34 reconnect:
35 *hPipe = CreateFile(pipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
36 if (*hPipe == INVALID_HANDLE_VALUE)
37 {
38 if (GetLastError() == ERROR_PIPE_BUSY)
39 {
40 if (WaitNamedPipe(pipeName, 5000))
41 goto reconnect;
42 }
43 return false;
44 }
45
46 DWORD pipeMode = PIPE_READMODE_MESSAGE;
47 SetNamedPipeHandleState(*hPipe, &pipeMode, NULL, NULL);
48 #else
49 *hPipe = socket(AF_UNIX, SOCK_STREAM, 0);
50 if (*hPipe == -1)
51 return false;
52
53 struct sockaddr_un remote;
54 remote.sun_family = AF_UNIX;
55 #ifdef UNICODE
56 sprintf(remote.sun_path, "/tmp/.appagent.%S", name);
57 #else
58 sprintf(remote.sun_path, "/tmp/.appagent.%s", name);
59 #endif
60 if (connect(*hPipe, (struct sockaddr *)&remote, SUN_LEN(&remote)) == -1)
61 {
62 close(*hPipe);
63 return false;
64 }
65 #endif
66
67 return true;
68 }
69
70 /**
71 * Disconnect from application agent
72 */
73 void APPAGENT_EXPORTABLE AppAgentDisconnect(HPIPE hPipe)
74 {
75 #ifdef _WIN32
76 CloseHandle(hPipe);
77 #else
78 close(hPipe);
79 #endif
80 }
81
82 /**
83 * Get metric from application agent
84 */
85 int APPAGENT_EXPORTABLE AppAgentGetMetric(HPIPE hPipe, const TCHAR *name, TCHAR *value, int bufferSize)
86 {
87 int rcc = APPAGENT_RCC_COMM_FAILURE;
88
89 APPAGENT_MSG *request = NewMessage(APPAGENT_CMD_GET_METRIC, 0, ((int)_tcslen(name) + 1) * sizeof(WCHAR));
90 #ifdef UNICODE
91 wcscpy((WCHAR *)request->payload, name);
92 #else
93 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, (WCHAR *)request->payload, (int)strlen(name) + 1);
94 #endif
95
96 if (SendMessageToPipe(hPipe, request))
97 {
98 AppAgentMessageBuffer *mb = new AppAgentMessageBuffer;
99 APPAGENT_MSG *response = ReadMessageFromPipe(hPipe, mb);
100 if (response != NULL)
101 {
102 if (response->command == APPAGENT_CMD_REQUEST_COMPLETED)
103 {
104 rcc = response->rcc;
105 if (rcc == APPAGENT_RCC_SUCCESS)
106 {
107 int valueLen = (response->length - APPAGENT_MSG_HEADER_LEN) / sizeof(TCHAR);
108 #ifdef UNICODE
109 wcslcpy(value, (WCHAR *)response->payload, std::min(valueLen, bufferSize));
110 #else
111 WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR, (WCHAR *)response->payload, valueLen, value, bufferSize, NULL, NULL);
112 value[std::min(valueLen, bufferSize - 1)] = 0;
113 #endif
114 }
115 }
116 free(response);
117 }
118 delete mb;
119 }
120
121 free(request);
122 return rcc;
123 }
124
125 /**
126 * Get all supported metrics from agent
127 */
128 int APPAGENT_EXPORTABLE AppAgentListMetrics(HPIPE hPipe, APPAGENT_METRIC **metrics, UINT32 *size)
129 {
130 return APPAGENT_RCC_BAD_REQUEST;
131 }