1 /*
2  * Copyright (c) 2007-2014, Anthony Minessale II
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of the original author; nor the names of any contributors
17  * may be used to endorse or promote products derived from this software
18  * without specific prior written permission.
19  *
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
25  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #ifndef _ESL_H_
35 #define _ESL_H_
36 
37 #include <stdarg.h>
38 
39 #ifdef __cplusplus
40 extern "C" {
41 #endif /* defined(__cplusplus) */
42 
43 #define esl_copy_string(_x, _y, _z) snprintf(_x, _z, "%s", _y)
44 #define esl_set_string(_x, _y)  esl_copy_string(_x, _y, sizeof(_x))
45 #define ESL_VA_NONE "%s", ""
46 
47 typedef struct esl_event_header esl_event_header_t;
48 typedef struct esl_event esl_event_t;
49 
50 typedef enum {
51 	ESL_POLL_READ = (1 << 0),
52 	ESL_POLL_WRITE = (1 << 1),
53 	ESL_POLL_ERROR = (1 << 2)
54 } esl_poll_t;
55 
56 typedef enum {
57 	ESL_EVENT_TYPE_PLAIN,
58 	ESL_EVENT_TYPE_XML,
59 	ESL_EVENT_TYPE_JSON
60 } esl_event_type_t;
61 
62 #ifdef WIN32
63 #define ESL_SEQ_FWHITE FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY
64 #define ESL_SEQ_BWHITE FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
65 #define ESL_SEQ_FRED FOREGROUND_RED | FOREGROUND_INTENSITY
66 #define ESL_SEQ_BRED FOREGROUND_RED
67 #define ESL_SEQ_FMAGEN FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY
68 #define ESL_SEQ_BMAGEN FOREGROUND_BLUE | FOREGROUND_RED
69 #define ESL_SEQ_FCYAN FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY
70 #define ESL_SEQ_BCYAN FOREGROUND_GREEN | FOREGROUND_BLUE
71 #define ESL_SEQ_FGREEN FOREGROUND_GREEN | FOREGROUND_INTENSITY
72 #define ESL_SEQ_BGREEN FOREGROUND_GREEN
73 #define ESL_SEQ_FYELLOW FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY
74 #define ESL_SEQ_BYELLOW FOREGROUND_RED | FOREGROUND_GREEN
75 #define ESL_SEQ_DEFAULT_COLOR ESL_SEQ_FWHITE
76 #define ESL_SEQ_FBLUE FOREGROUND_BLUE | FOREGROUND_INTENSITY
77 #define ESL_SEQ_BBLUE FOREGROUND_BLUE
78 #define ESL_SEQ_FBLACK 0 | FOREGROUND_INTENSITY
79 #define ESL_SEQ_BBLACK 0
80 #else
81 #define ESL_SEQ_ESC "\033["
82 /* Ansi Control character suffixes */
83 #define ESL_SEQ_HOME_CHAR 'H'
84 #define ESL_SEQ_HOME_CHAR_STR "H"
85 #define ESL_SEQ_CLEARLINE_CHAR '1'
86 #define ESL_SEQ_CLEARLINE_CHAR_STR "1"
87 #define ESL_SEQ_CLEARLINEEND_CHAR "K"
88 #define ESL_SEQ_CLEARSCR_CHAR0 '2'
89 #define ESL_SEQ_CLEARSCR_CHAR1 'J'
90 #define ESL_SEQ_CLEARSCR_CHAR "2J"
91 #define ESL_SEQ_DEFAULT_COLOR ESL_SEQ_ESC ESL_SEQ_END_COLOR	/* Reset to Default fg/bg color */
92 #define ESL_SEQ_AND_COLOR ";"	/* To add multiple color definitions */
93 #define ESL_SEQ_END_COLOR "m"	/* To end color definitions */
94 /* Foreground colors values */
95 #define ESL_SEQ_F_BLACK "30"
96 #define ESL_SEQ_F_RED "31"
97 #define ESL_SEQ_F_GREEN "32"
98 #define ESL_SEQ_F_YELLOW "33"
99 #define ESL_SEQ_F_BLUE "34"
100 #define ESL_SEQ_F_MAGEN "35"
101 #define ESL_SEQ_F_CYAN "36"
102 #define ESL_SEQ_F_WHITE "37"
103 /* Background colors values */
104 #define ESL_SEQ_B_BLACK "40"
105 #define ESL_SEQ_B_RED "41"
106 #define ESL_SEQ_B_GREEN "42"
107 #define ESL_SEQ_B_YELLOW "43"
108 #define ESL_SEQ_B_BLUE "44"
109 #define ESL_SEQ_B_MAGEN "45"
110 #define ESL_SEQ_B_CYAN "46"
111 #define ESL_SEQ_B_WHITE "47"
112 /* Preset escape sequences - Change foreground colors only */
113 #define ESL_SEQ_FBLACK ESL_SEQ_ESC ESL_SEQ_F_BLACK ESL_SEQ_END_COLOR
114 #define ESL_SEQ_FRED ESL_SEQ_ESC ESL_SEQ_F_RED ESL_SEQ_END_COLOR
115 #define ESL_SEQ_FGREEN ESL_SEQ_ESC ESL_SEQ_F_GREEN ESL_SEQ_END_COLOR
116 #define ESL_SEQ_FYELLOW ESL_SEQ_ESC ESL_SEQ_F_YELLOW ESL_SEQ_END_COLOR
117 #define ESL_SEQ_FBLUE ESL_SEQ_ESC ESL_SEQ_F_BLUE ESL_SEQ_END_COLOR
118 #define ESL_SEQ_FMAGEN ESL_SEQ_ESC ESL_SEQ_F_MAGEN ESL_SEQ_END_COLOR
119 #define ESL_SEQ_FCYAN ESL_SEQ_ESC ESL_SEQ_F_CYAN ESL_SEQ_END_COLOR
120 #define ESL_SEQ_FWHITE ESL_SEQ_ESC ESL_SEQ_F_WHITE ESL_SEQ_END_COLOR
121 #define ESL_SEQ_BBLACK ESL_SEQ_ESC ESL_SEQ_B_BLACK ESL_SEQ_END_COLOR
122 #define ESL_SEQ_BRED ESL_SEQ_ESC ESL_SEQ_B_RED ESL_SEQ_END_COLOR
123 #define ESL_SEQ_BGREEN ESL_SEQ_ESC ESL_SEQ_B_GREEN ESL_SEQ_END_COLOR
124 #define ESL_SEQ_BYELLOW ESL_SEQ_ESC ESL_SEQ_B_YELLOW ESL_SEQ_END_COLOR
125 #define ESL_SEQ_BBLUE ESL_SEQ_ESC ESL_SEQ_B_BLUE ESL_SEQ_END_COLOR
126 #define ESL_SEQ_BMAGEN ESL_SEQ_ESC ESL_SEQ_B_MAGEN ESL_SEQ_END_COLOR
127 #define ESL_SEQ_BCYAN ESL_SEQ_ESC ESL_SEQ_B_CYAN ESL_SEQ_END_COLOR
128 #define ESL_SEQ_BWHITE ESL_SEQ_ESC ESL_SEQ_B_WHITE ESL_SEQ_END_COLOR
129 /* Preset escape sequences */
130 #define ESL_SEQ_HOME ESL_SEQ_ESC ESL_SEQ_HOME_CHAR_STR
131 #define ESL_SEQ_CLEARLINE ESL_SEQ_ESC ESL_SEQ_CLEARLINE_CHAR_STR
132 #define ESL_SEQ_CLEARLINEEND ESL_SEQ_ESC ESL_SEQ_CLEARLINEEND_CHAR
133 #define ESL_SEQ_CLEARSCR ESL_SEQ_ESC ESL_SEQ_CLEARSCR_CHAR ESL_SEQ_HOME
134 #endif
135 
136 #if !defined(_XOPEN_SOURCE) && !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__)
137 #define _XOPEN_SOURCE 600
138 #endif
139 
140 #ifndef HAVE_STRINGS_H
141 #define HAVE_STRINGS_H 1
142 #endif
143 #ifndef HAVE_SYS_SOCKET_H
144 #define HAVE_SYS_SOCKET_H 1
145 #endif
146 
147 #ifndef __WINDOWS__
148 #if defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)
149 #define __WINDOWS__
150 #endif
151 #endif
152 
153 #ifdef _MSC_VER
154 #ifndef __inline__
155 #define __inline__ __inline
156 #endif
157 #if (_MSC_VER >= 1400)			/* VC8+ */
158 #ifndef _CRT_SECURE_NO_DEPRECATE
159 #define _CRT_SECURE_NO_DEPRECATE
160 #endif
161 #ifndef _CRT_NONSTDC_NO_DEPRECATE
162 #define _CRT_NONSTDC_NO_DEPRECATE
163 #endif
164 #endif
165 #ifndef strcasecmp
166 #define strcasecmp(s1, s2) _stricmp(s1, s2)
167 #endif
168 #ifndef strncasecmp
169 #define strncasecmp(s1, s2, n) _strnicmp(s1, s2, n)
170 #endif
171 #if _MSC_VER < 1900
172 #define snprintf _snprintf
173 #endif
174 #ifndef S_IRUSR
175 #define S_IRUSR _S_IREAD
176 #endif
177 #ifndef S_IWUSR
178 #define S_IWUSR _S_IWRITE
179 #endif
180 #undef HAVE_STRINGS_H
181 #undef HAVE_SYS_SOCKET_H
182 #endif
183 
184 #include <time.h>
185 #ifndef WIN32
186 #include <sys/time.h>
187 #endif
188 
189 #include <stdarg.h>
190 #include <stdio.h>
191 #include <stdlib.h>
192 #include <string.h>
193 #ifndef WIN32
194 #include <sys/types.h>
195 #include <sys/select.h>
196 #include <netinet/tcp.h>
197 #include <signal.h>
198 #include <unistd.h>
199 #include <ctype.h>
200 #endif
201 
202 #ifdef HAVE_STRINGS_H
203 #include <strings.h>
204 #endif
205 #include <assert.h>
206 
207 #if (_MSC_VER >= 1400)			// VC8+
208 #define esl_assert(expr) assert(expr);__analysis_assume( expr )
209 #endif
210 
211 #ifndef esl_assert
212 #define esl_assert(_x) assert(_x)
213 #endif
214 
215 #define esl_safe_free(_x) if (_x) free(_x); _x = NULL
216 #define esl_strlen_zero(s) (!s || *(s) == '\0')
217 #define esl_strlen_zero_buf(s) (*(s) == '\0')
218 #define end_of(_s) *(*_s == '\0' ? _s : _s + strlen(_s) - 1)
219 
220 #ifdef WIN32
221 #include <winsock2.h>
222 #include <windows.h>
223 typedef SOCKET esl_socket_t;
224 #if !defined(_STDINT) && !defined(uint32_t)
225 typedef unsigned __int64 uint64_t;
226 typedef unsigned __int32 uint32_t;
227 typedef unsigned __int16 uint16_t;
228 typedef unsigned __int8 uint8_t;
229 typedef __int64 int64_t;
230 typedef __int32 int32_t;
231 typedef __int16 int16_t;
232 typedef __int8 int8_t;
233 #endif
234 typedef intptr_t esl_ssize_t;
235 typedef int esl_filehandle_t;
236 #define ESL_SOCK_INVALID INVALID_SOCKET
237 #define strerror_r(num, buf, size) strerror_s(buf, size, num)
238 #if defined(ESL_DECLARE_STATIC)
239 #define ESL_DECLARE(type)			type __stdcall
240 #define ESL_DECLARE_NONSTD(type)		type __cdecl
241 #define ESL_DECLARE_DATA
242 #elif defined(ESL_EXPORTS)
243 #define ESL_DECLARE(type)			__declspec(dllexport) type __stdcall
244 #define ESL_DECLARE_NONSTD(type)		__declspec(dllexport) type __cdecl
245 #define ESL_DECLARE_DATA				__declspec(dllexport)
246 #else
247 #define ESL_DECLARE(type)			__declspec(dllimport) type __stdcall
248 #define ESL_DECLARE_NONSTD(type)		__declspec(dllimport) type __cdecl
249 #define ESL_DECLARE_DATA				__declspec(dllimport)
250 #endif
251 #else
252 #define ESL_DECLARE(type) type
253 #define ESL_DECLARE_NONSTD(type) type
254 #define ESL_DECLARE_DATA
255 #include <stdint.h>
256 #include <sys/types.h>
257 #include <sys/ioctl.h>
258 #include <stdarg.h>
259 #include <sys/socket.h>
260 #include <netinet/in.h>
261 #include <netdb.h>
262 #define ESL_SOCK_INVALID -1
263 typedef int esl_socket_t;
264 typedef ssize_t esl_ssize_t;
265 typedef int esl_filehandle_t;
266 #endif
267 
268 #include "math.h"
269 #include "esl_json.h"
270 
271 typedef int16_t esl_port_t;
272 typedef size_t esl_size_t;
273 
274 typedef enum {
275 	ESL_SUCCESS,
276 	ESL_FAIL,
277 	ESL_BREAK,
278 	ESL_DISCONNECTED,
279 	ESL_GENERR
280 } esl_status_t;
281 
282 #define BUF_CHUNK 65536 * 50
283 #define BUF_START 65536 * 100
284 
285 #include <esl_threadmutex.h>
286 #include <esl_buffer.h>
287 
288 /*! \brief A handle that will hold the socket information and
289            different events received. */
290 typedef struct {
291 	struct sockaddr_storage sockaddr;
292 	struct hostent hostent;
293 	char hostbuf[256];
294 	esl_socket_t sock;
295 	/*! In case of socket error, this will hold the error description as reported by the OS */
296 	char err[256];
297 	/*! The error number reported by the OS */
298 	int errnum;
299 	/*! The inner contents received by the socket. Used only internally. */
300 	esl_buffer_t *packet_buf;
301 	char socket_buf[65536];
302 	/*! Last command reply */
303 	char last_reply[1024];
304 	/*! Last command reply when called with esl_send_recv */
305 	char last_sr_reply[1024];
306 	/*! Last event received. Only populated when **save_event is NULL */
307 	esl_event_t *last_event;
308 	/*! Last event received when called by esl_send_recv */
309 	esl_event_t *last_sr_event;
310 	/*! This will hold already processed events queued by esl_recv_event */
311 	esl_event_t *race_event;
312 	/*! Events that have content-type == text/plain and a body */
313 	esl_event_t *last_ievent;
314 	/*! For outbound socket. Will hold reply information when connect\n\n is sent */
315 	esl_event_t *info_event;
316 	/*! Socket is connected or not */
317 	int connected;
318 	struct sockaddr_in addr;
319 	/*! Internal mutex */
320 	esl_mutex_t *mutex;
321 	int async_execute;
322 	int event_lock;
323 	int destroyed;
324 } esl_handle_t;
325 
326 #define esl_test_flag(obj, flag) ((obj)->flags & flag)
327 #define esl_set_flag(obj, flag) (obj)->flags |= (flag)
328 #define esl_clear_flag(obj, flag) (obj)->flags &= ~(flag)
329 
330 /*! \brief Used internally for truth test */
331 typedef enum {
332 	ESL_TRUE = 1,
333 	ESL_FALSE = 0
334 } esl_bool_t;
335 
336 #ifndef __FUNCTION__
337 #define __FUNCTION__ (const char *)__func__
338 #endif
339 
340 #define ESL_PRE __FILE__, __FUNCTION__, __LINE__
341 #define ESL_LOG_LEVEL_DEBUG 7
342 #define ESL_LOG_LEVEL_INFO 6
343 #define ESL_LOG_LEVEL_NOTICE 5
344 #define ESL_LOG_LEVEL_WARNING 4
345 #define ESL_LOG_LEVEL_ERROR 3
346 #define ESL_LOG_LEVEL_CRIT 2
347 #define ESL_LOG_LEVEL_ALERT 1
348 #define ESL_LOG_LEVEL_EMERG 0
349 
350 #define ESL_LOG_DEBUG ESL_PRE, ESL_LOG_LEVEL_DEBUG
351 #define ESL_LOG_INFO ESL_PRE, ESL_LOG_LEVEL_INFO
352 #define ESL_LOG_NOTICE ESL_PRE, ESL_LOG_LEVEL_NOTICE
353 #define ESL_LOG_WARNING ESL_PRE, ESL_LOG_LEVEL_WARNING
354 #define ESL_LOG_ERROR ESL_PRE, ESL_LOG_LEVEL_ERROR
355 #define ESL_LOG_CRIT ESL_PRE, ESL_LOG_LEVEL_CRIT
356 #define ESL_LOG_ALERT ESL_PRE, ESL_LOG_LEVEL_ALERT
357 #define ESL_LOG_EMERG ESL_PRE, ESL_LOG_LEVEL_EMERG
358 typedef void (*esl_logger_t)(const char *file, const char *func, int line, int level, const char *fmt, ...);
359 
360 
361 ESL_DECLARE(int) esl_vasprintf(char **ret, const char *fmt, va_list ap);
362 
363 ESL_DECLARE_DATA extern esl_logger_t esl_log;
364 
365 /*! Sets the logger for libesl. Default is the null_logger */
366 ESL_DECLARE(void) esl_global_set_logger(esl_logger_t logger);
367 /*! Sets the default log level for libesl */
368 ESL_DECLARE(void) esl_global_set_default_logger(int level);
369 
370 #include "esl_event.h"
371 #include "esl_threadmutex.h"
372 #include "esl_config.h"
373 
374 ESL_DECLARE(size_t) esl_url_encode(const char *url, char *buf, size_t len);
375 ESL_DECLARE(char *)esl_url_decode(char *s);
376 ESL_DECLARE(const char *)esl_stristr(const char *instr, const char *str);
377 ESL_DECLARE(int) esl_toupper(int c);
378 ESL_DECLARE(int) esl_tolower(int c);
379 ESL_DECLARE(int) esl_snprintf(char *buffer, size_t count, const char *fmt, ...);
380 
381 
382 typedef void (*esl_listen_callback_t)(esl_socket_t server_sock, esl_socket_t client_sock, struct sockaddr_in *addr, void *user_data);
383 /*!
384     \brief Attach a handle to an established socket connection
385     \param handle Handle to be attached
386     \param socket Socket to which the handle will be attached
387     \param addr Structure that will contain the connection descritption (look up your os info)
388 */
389 ESL_DECLARE(esl_status_t) esl_attach_handle(esl_handle_t *handle, esl_socket_t socket, struct sockaddr_in *addr);
390 /*!
391     \brief Will bind to host and callback when event is received. Used for outbound socket.
392     \param host Host to bind to
393     \param port Port to bind to
394     \param callback Callback that will be called upon data received
395 */
396 
397 ESL_DECLARE(esl_status_t) esl_listen(const char *host, esl_port_t port, esl_listen_callback_t callback, void *user_data, esl_socket_t *server_sockP);
398 ESL_DECLARE(esl_status_t) esl_listen_threaded(const char *host, esl_port_t port, esl_listen_callback_t callback, void *user_data, int max);
399 /*!
400     \brief Executes application with sendmsg to a specific UUID. Used for outbound socket.
401     \param handle Handle that the msg will be sent
402     \param app Application to execute
403     \param arg Application arguments
404     \param uuid Target UUID for the application
405 */
406 ESL_DECLARE(esl_status_t) esl_execute(esl_handle_t *handle, const char *app, const char *arg, const char *uuid);
407 /*!
408     \brief Send an event
409     \param handle Handle to which the event should be sent
410     \param event Event to be sent
411 */
412 ESL_DECLARE(esl_status_t) esl_sendevent(esl_handle_t *handle, esl_event_t *event);
413 
414 /*!
415     \brief Send an event as a message to be parsed
416     \param handle Handle to which the event should be sent
417     \param event Event to be sent
418 	\param uuid a specific uuid if not the default
419 */
420 ESL_DECLARE(esl_status_t) esl_sendmsg(esl_handle_t *handle, esl_event_t *event, const char *uuid);
421 
422 /*!
423     \brief Connect a handle to a host/port with a specific password. This will also authenticate against the server
424     \param handle Handle to connect
425     \param host Host to be connected
426     \param port Port to be connected
427     \param password FreeSWITCH server username (optional)
428     \param password FreeSWITCH server password
429 	\param timeout Connection timeout, in miliseconds
430 */
431 ESL_DECLARE(esl_status_t) esl_connect_timeout(esl_handle_t *handle, const char *host, esl_port_t port, const char *user, const char *password, uint32_t timeout);
432 #define esl_connect(_handle, _host, _port, _user, _password) esl_connect_timeout(_handle, _host, _port, _user, _password, 0)
433 
434 /*!
435     \brief Disconnect a handle
436     \param handle Handle to be disconnected
437 */
438 ESL_DECLARE(esl_status_t) esl_disconnect(esl_handle_t *handle);
439 /*!
440     \brief Send a raw command using specific handle
441     \param handle Handle to send the command to
442     \param cmd Command to send
443 */
444 ESL_DECLARE(esl_status_t) esl_send(esl_handle_t *handle, const char *cmd);
445 /*!
446     \brief Poll the handle's socket until an event is received or a connection error occurs
447     \param handle Handle to poll
448     \param check_q If set to 1, will check the handle queue (handle->race_event) and return the last event from it
449     \param[out] save_event If this is not NULL, will return the event received
450 */
451 ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_event_t **save_event);
452 /*!
453     \brief Poll the handle's socket until an event is received, a connection error occurs or ms expires
454     \param handle Handle to poll
455     \param ms Maximum time to poll
456     \param check_q If set to 1, will check the handle queue (handle->race_event) and return the last event from it
457     \param[out] save_event If this is not NULL, will return the event received
458 */
459 ESL_DECLARE(esl_status_t) esl_recv_event_timed(esl_handle_t *handle, uint32_t ms, int check_q, esl_event_t **save_event);
460 /*!
461     \brief This will send a command and place its response event on handle->last_sr_event and handle->last_sr_reply
462     \param handle Handle to be used
463     \param cmd Raw command to send
464 */
465 ESL_DECLARE(esl_status_t) esl_send_recv_timed(esl_handle_t *handle, const char *cmd, uint32_t ms);
466 #define esl_send_recv(_handle, _cmd) esl_send_recv_timed(_handle, _cmd, 0)
467 /*!
468     \brief Applies a filter to received events
469     \param handle Handle to apply the filter to
470     \param header Header that the filter will be based on
471     \param value The value of the header to filter
472 */
473 ESL_DECLARE(esl_status_t) esl_filter(esl_handle_t *handle, const char *header, const char *value);
474 /*!
475     \brief Will subscribe to events on the server
476     \param handle Handle to which we will subscribe to events
477     \param etype Event type to subscribe
478     \param value Which event to subscribe to
479 */
480 ESL_DECLARE(esl_status_t) esl_events(esl_handle_t *handle, esl_event_type_t etype, const char *value);
481 
482 ESL_DECLARE(int) esl_wait_sock(esl_socket_t sock, uint32_t ms, esl_poll_t flags);
483 
484 ESL_DECLARE(unsigned int) esl_separate_string_string(char *buf, const char *delim, char **array, unsigned int arraylen);
485 
486 #define esl_recv(_h) esl_recv_event(_h, 0, NULL)
487 #define esl_recv_timed(_h, _ms) esl_recv_event_timed(_h, _ms, 0, NULL)
488 
esl_safe_strcasecmp(const char * s1,const char * s2)489 static __inline__ int esl_safe_strcasecmp(const char *s1, const char *s2)
490 {
491 	if (!(s1 && s2)) {
492 		return 1;
493 	}
494 
495 	return strcasecmp(s1, s2);
496 }
497 
498 #ifdef __cplusplus
499 }
500 #endif /* defined(__cplusplus) */
501 
502 
503 #endif /* defined(_ESL_H_) */
504 
505 /* For Emacs:
506  * Local Variables:
507  * mode:c
508  * indent-tabs-mode:t
509  * tab-width:4
510  * c-basic-offset:4
511  * End:
512  * For VIM:
513  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
514  */
515