0485369b800633b8b8c6ba2ab4bdf469fe02fcb9
[public/netxms.git] / src / agent / libnxappc / nxappc.c
1 /*
2 ** NetXMS Application Connector Library
3 ** Copyright (C) 2015-2016 Raden Solutions
4 **
5 ** Permission is hereby granted, free of charge, to any person obtaining
6 ** a copy of this software and associated documentation files
7 ** (the "Software"), to deal in the Software without restriction, including
8 ** without limitation the rights to use, copy, modify, merge, publish,
9 ** distribute, sublicense, and/or sell copies of the Software, and to permit
10 ** persons to whom the Software is furnished to do so, subject to the
11 ** following conditions:
12 **
13 ** The above copyright notice and this permission notice shall be included in
14 ** all copies or substantial portions of the Software.
15 **
16 ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 ** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 ** OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 ** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 ** OTHER DEALINGS IN THE SOFTWARE.
23 **/
24
25 #define _CRT_SECURE_NO_WARNINGS
26
27 #if HAVE_CONFIG_H
28 #include <config.h>
29 #else
30 #define HAVE_ALLOCA_H 1
31 #endif
32
33 #include <stdio.h>
34 #include <string.h>
35 #include <errno.h>
36
37 #ifdef _WIN32
38
39 #include <winsock2.h>
40 #include <windows.h>
41 #include <malloc.h>
42
43 #define SELECT_NFDS(f) (0)
44
45 #else /* _WIN32 */
46
47 #include <unistd.h>
48 #include <sys/time.h>
49 #include <sys/socket.h>
50 #include <sys/un.h>
51 #include <fcntl.h>
52
53 #if HAVE_ALLOCA_H
54 #include <alloca.h>
55 #endif
56
57 #define SOCKET int
58 #define closesocket(x) close(x)
59
60 #define SELECT_NFDS(f) ((f) + 1)
61
62 #ifndef SUN_LEN
63 #define SUN_LEN(su) (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
64 #endif
65
66 #endif /* _WIN32 */
67
68 #include "nxappc.h"
69 #include <nxappc_internal.h>
70
71 static char s_channel[128] = "";
72 static SOCKET s_socket = -1;
73
74 /**
75 * Check if channel is ready
76 */
77 #define CHECK_CHANNEL do { if (s_socket == -1) { nxappc_open_channel(); if (s_socket == -1) return NXAPPC_FAIL; } } while(0)
78
79 /**
80 * Set channel name
81 */
82 int LIBNXAPPC_EXPORTABLE nxappc_set_channel_name(const char *channel)
83 {
84 if (!strcmp(channel, s_channel))
85 return NXAPPC_SUCCESS; // already connected
86 strncpy(s_channel, channel, 128);
87 if (s_socket != -1)
88 {
89 closesocket(s_socket);
90 s_socket = -1;
91 }
92 return NXAPPC_SUCCESS;
93 }
94
95 /**
96 * Open channel for communication
97 */
98 int LIBNXAPPC_EXPORTABLE nxappc_open_channel(void)
99 {
100 #ifdef _WIN32
101 struct sockaddr_in addrLocal;
102 u_long one = 1;
103 #else
104 struct sockaddr_un addrLocal;
105 int f;
106 #endif
107
108 if (s_socket != -1)
109 {
110 closesocket(s_socket);
111 }
112
113 #ifdef _WIN32
114 s_socket = socket(AF_INET, SOCK_DGRAM, 0);
115 if (s_socket == -1)
116 return NXAPPC_FAIL;
117
118 addrLocal.sin_family = AF_INET;
119 addrLocal.sin_addr.s_addr = inet_addr("127.0.0.1");
120 addrLocal.sin_port = htons(atoi(s_channel));
121 if (connect(s_socket, (struct sockaddr *)&addrLocal, sizeof(addrLocal)) == -1)
122 {
123 closesocket(s_socket);
124 s_socket = -1;
125 return NXAPPC_FAIL;
126 }
127
128 #else
129 s_socket = socket(AF_UNIX, SOCK_DGRAM, 0);
130 if (s_socket == -1)
131 return NXAPPC_FAIL;
132
133 addrLocal.sun_family = AF_UNIX;
134 sprintf(addrLocal.sun_path, "/tmp/.nxappc.%s", s_channel);
135 if (connect(s_socket, (struct sockaddr *)&addrLocal, SUN_LEN(&addrLocal)) == -1)
136 {
137 closesocket(s_socket);
138 s_socket = -1;
139 return NXAPPC_FAIL;
140 }
141
142 #endif
143
144 return NXAPPC_SUCCESS;
145 }
146
147 /**
148 * Reset channel
149 */
150 int LIBNXAPPC_EXPORTABLE nxappc_reset_channel(void)
151 {
152 if (s_socket != -1)
153 {
154 closesocket(s_socket);
155 s_socket = -1;
156 }
157 return nxappc_open_channel();
158 }
159
160 /**
161 * Send with retry
162 */
163 static int send_data(void *data, int size)
164 {
165 int rc = send(s_socket, data, size, 0);
166 if (rc >= 0)
167 return rc;
168 rc = nxappc_reset_channel();
169 if (rc < 0)
170 return rc;
171 return send(s_socket, data, size, 0);
172 }
173
174 /**
175 * Send event
176 */
177 int LIBNXAPPC_EXPORTABLE nxappc_send_event(int code, const char *name, const char *format, ...)
178 {
179 CHECK_CHANNEL;
180 return NXAPPC_FAIL;
181 }
182
183 /**
184 * Send binary data
185 */
186 int LIBNXAPPC_EXPORTABLE nxappc_send_data(void *data, int size)
187 {
188 char *msg;
189
190 if ((size < 0) || (size > 65532))
191 return NXAPPC_FAIL;
192
193 CHECK_CHANNEL;
194
195 msg = alloca(size + 4);
196 msg[0] = NXAPPC_CMD_SEND_DATA;
197 msg[1] = 0; // reserved
198 *((unsigned short *)&msg[2]) = (unsigned short)size;
199 memcpy(&msg[4], data, size);
200 return (send_data(msg, size + 4) == size + 4) ? NXAPPC_SUCCESS : NXAPPC_FAIL;
201 }
202
203 /**
204 * Register counter
205 */
206 int LIBNXAPPC_EXPORTABLE nxappc_register_counter(const char *counter, const char *instance)
207 {
208 CHECK_CHANNEL;
209 return NXAPPC_FAIL;
210 }
211
212 /**
213 * Update integer counter
214 */
215 int LIBNXAPPC_EXPORTABLE nxappc_update_counter_long(const char *counter, const char *instance, long diff)
216 {
217 CHECK_CHANNEL;
218 return NXAPPC_FAIL;
219 }
220
221 /**
222 * Update floating point counter
223 */
224 int LIBNXAPPC_EXPORTABLE nxappc_update_counter_double(const char *counter, const char *instance, double diff)
225 {
226 CHECK_CHANNEL;
227 return NXAPPC_FAIL;
228 }
229
230 /**
231 * Reset counter
232 */
233 int LIBNXAPPC_EXPORTABLE nxappc_reset_counter(const char *counter, const char *instance)
234 {
235 CHECK_CHANNEL;
236 return NXAPPC_FAIL;
237 }
238
239 /**
240 * Update integer counter
241 */
242 int LIBNXAPPC_EXPORTABLE nxappc_set_counter_long(const char *counter, const char *instance, long value)
243 {
244 CHECK_CHANNEL;
245
246 return NXAPPC_FAIL;
247 }
248
249 /**
250 * Set floating point counter
251 */
252 int LIBNXAPPC_EXPORTABLE nxappc_set_counter_double(const char *counter, const char *instance, double value)
253 {
254 CHECK_CHANNEL;
255 return NXAPPC_FAIL;
256 }