rtl433  UNKNOWN
RTL-433 utility
mongoose.h
Go to the documentation of this file.
1 #ifdef MG_MODULE_LINES
2 #line 1 "mongoose/src/mg_common.h"
3 #endif
4 /*
5  * Copyright (c) 2004-2013 Sergey Lyubka
6  * Copyright (c) 2013-2015 Cesanta Software Limited
7  * All rights reserved
8  *
9  * This software is dual-licensed: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation. For the terms of this
12  * license, see <http://www.gnu.org/licenses/>.
13  *
14  * You are free to use this software under the terms of the GNU General
15  * Public License, but WITHOUT ANY WARRANTY; without even the implied
16  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17  * See the GNU General Public License for more details.
18  *
19  * Alternatively, you can license this software under a commercial
20  * license, as set out in <https://www.cesanta.com/license>.
21  */
22 
23 #ifndef CS_MONGOOSE_SRC_COMMON_H_
24 #define CS_MONGOOSE_SRC_COMMON_H_
25 
26 #define MG_VERSION "6.13"
27 
28 /* Local tweaks, applied before any of Mongoose's own headers. */
29 #ifdef MG_LOCALS
30 #include <mg_locals.h>
31 #endif
32 
33 #endif /* CS_MONGOOSE_SRC_COMMON_H_ */
34 #ifdef MG_MODULE_LINES
35 #line 1 "common/platform.h"
36 #endif
37 #ifndef CS_COMMON_PLATFORM_H_
38 #define CS_COMMON_PLATFORM_H_
39 
40 /*
41  * For the "custom" platform, includes and dependencies can be
42  * provided through mg_locals.h.
43  */
44 #define CS_P_CUSTOM 0
45 #define CS_P_UNIX 1
46 #define CS_P_WINDOWS 2
47 #define CS_P_ESP32 15
48 #define CS_P_ESP8266 3
49 #define CS_P_CC3100 6
50 #define CS_P_CC3200 4
51 #define CS_P_CC3220 17
52 #define CS_P_MSP432 5
53 #define CS_P_TM4C129 14
54 #define CS_P_MBED 7
55 #define CS_P_WINCE 8
56 #define CS_P_NXP_LPC 13
57 #define CS_P_NXP_KINETIS 9
58 #define CS_P_NRF51 12
59 #define CS_P_NRF52 10
60 #define CS_P_PIC32 11
61 #define CS_P_STM32 16
62 /* Next id: 18 */
63 
64 /* If not specified explicitly, we guess platform by defines. */
65 #ifndef CS_PLATFORM
66 
67 #if defined(TARGET_IS_MSP432P4XX) || defined(__MSP432P401R__)
68 #define CS_PLATFORM CS_P_MSP432
69 #elif defined(cc3200) || defined(TARGET_IS_CC3200)
70 #define CS_PLATFORM CS_P_CC3200
71 #elif defined(cc3220) || defined(TARGET_IS_CC3220)
72 #define CS_PLATFORM CS_P_CC3220
73 #elif defined(__unix__) || defined(__APPLE__)
74 #define CS_PLATFORM CS_P_UNIX
75 #elif defined(WINCE)
76 #define CS_PLATFORM CS_P_WINCE
77 #elif defined(_WIN32)
78 #define CS_PLATFORM CS_P_WINDOWS
79 #elif defined(__MBED__)
80 #define CS_PLATFORM CS_P_MBED
81 #elif defined(__USE_LPCOPEN)
82 #define CS_PLATFORM CS_P_NXP_LPC
83 #elif defined(FRDM_K64F) || defined(FREEDOM)
84 #define CS_PLATFORM CS_P_NXP_KINETIS
85 #elif defined(PIC32)
86 #define CS_PLATFORM CS_P_PIC32
87 #elif defined(ESP_PLATFORM)
88 #define CS_PLATFORM CS_P_ESP32
89 #elif defined(ICACHE_FLASH)
90 #define CS_PLATFORM CS_P_ESP8266
91 #elif defined(TARGET_IS_TM4C129_RA0) || defined(TARGET_IS_TM4C129_RA1) || \
92  defined(TARGET_IS_TM4C129_RA2)
93 #define CS_PLATFORM CS_P_TM4C129
94 #elif defined(STM32)
95 #define CS_PLATFORM CS_P_STM32
96 #endif
97 
98 #ifndef CS_PLATFORM
99 #error "CS_PLATFORM is not specified and we couldn't guess it."
100 #endif
101 
102 #endif /* !defined(CS_PLATFORM) */
103 
104 #define MG_NET_IF_SOCKET 1
105 #define MG_NET_IF_SIMPLELINK 2
106 #define MG_NET_IF_LWIP_LOW_LEVEL 3
107 #define MG_NET_IF_PIC32 4
108 #define MG_NET_IF_NULL 5
109 
110 #define MG_SSL_IF_OPENSSL 1
111 #define MG_SSL_IF_MBEDTLS 2
112 #define MG_SSL_IF_SIMPLELINK 3
113 
114 /* Amalgamated: #include "common/platforms/platform_unix.h" */
115 /* Amalgamated: #include "common/platforms/platform_windows.h" */
116 /* Amalgamated: #include "common/platforms/platform_esp32.h" */
117 /* Amalgamated: #include "common/platforms/platform_esp8266.h" */
118 /* Amalgamated: #include "common/platforms/platform_cc3100.h" */
119 /* Amalgamated: #include "common/platforms/platform_cc3200.h" */
120 /* Amalgamated: #include "common/platforms/platform_cc3220.h" */
121 /* Amalgamated: #include "common/platforms/platform_mbed.h" */
122 /* Amalgamated: #include "common/platforms/platform_nrf51.h" */
123 /* Amalgamated: #include "common/platforms/platform_nrf52.h" */
124 /* Amalgamated: #include "common/platforms/platform_wince.h" */
125 /* Amalgamated: #include "common/platforms/platform_nxp_lpc.h" */
126 /* Amalgamated: #include "common/platforms/platform_nxp_kinetis.h" */
127 /* Amalgamated: #include "common/platforms/platform_pic32.h" */
128 /* Amalgamated: #include "common/platforms/platform_stm32.h" */
129 
130 /* Common stuff */
131 
132 #if !defined(PRINTF_LIKE)
133 #if defined(__GNUC__) || defined(__clang__) || defined(__TI_COMPILER_VERSION__)
134 #define PRINTF_LIKE(f, a) __attribute__((format(printf, f, a)))
135 #else
136 #define PRINTF_LIKE(f, a)
137 #endif
138 #endif
139 
140 #if !defined(WEAK)
141 #if (defined(__GNUC__) || defined(__clang__) || \
142  defined(__TI_COMPILER_VERSION__)) && \
143  !defined(_WIN32)
144 #define WEAK __attribute__((weak))
145 #else
146 #define WEAK
147 #endif
148 #endif
149 
150 #ifdef __GNUC__
151 #define NORETURN __attribute__((noreturn))
152 #define NOINLINE __attribute__((noinline))
153 #define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
154 #define NOINSTR __attribute__((no_instrument_function))
155 #define DO_NOT_WARN_UNUSED __attribute__((unused))
156 #else
157 #define NORETURN
158 #define NOINLINE
159 #define WARN_UNUSED_RESULT
160 #define NOINSTR
161 #define DO_NOT_WARN_UNUSED
162 #endif /* __GNUC__ */
163 
164 #ifndef ARRAY_SIZE
165 #define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
166 #endif
167 
168 #endif /* CS_COMMON_PLATFORM_H_ */
169 #ifdef MG_MODULE_LINES
170 #line 1 "common/platforms/platform_windows.h"
171 #endif
172 #ifndef CS_COMMON_PLATFORMS_PLATFORM_WINDOWS_H_
173 #define CS_COMMON_PLATFORMS_PLATFORM_WINDOWS_H_
174 #if CS_PLATFORM == CS_P_WINDOWS
175 
176 /*
177  * MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)
178  * MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)
179  * MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012)
180  * MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010)
181  * MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008)
182  * MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005)
183  * MSVC++ 7.1 _MSC_VER == 1310 (Visual Studio 2003)
184  * MSVC++ 7.0 _MSC_VER == 1300
185  * MSVC++ 6.0 _MSC_VER == 1200
186  * MSVC++ 5.0 _MSC_VER == 1100
187  */
188 #ifdef _MSC_VER
189 #pragma warning(disable : 4127) /* FD_SET() emits warning, disable it */
190 #pragma warning(disable : 4204) /* missing c99 support */
191 #endif
192 
193 #ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
194 #define _WINSOCK_DEPRECATED_NO_WARNINGS 1
195 #endif
196 
197 #ifndef _CRT_SECURE_NO_WARNINGS
198 #define _CRT_SECURE_NO_WARNINGS
199 #endif
200 
201 #include <assert.h>
202 #include <direct.h>
203 #include <errno.h>
204 #include <fcntl.h>
205 #include <io.h>
206 #include <limits.h>
207 #include <signal.h>
208 #include <stddef.h>
209 #include <stdio.h>
210 #include <stdlib.h>
211 #include <sys/stat.h>
212 #include <time.h>
213 #include <ctype.h>
214 
215 #ifdef _MSC_VER
216 #pragma comment(lib, "ws2_32.lib") /* Linking with winsock library */
217 #endif
218 
219 #include <winsock2.h>
220 #include <ws2tcpip.h>
221 #include <windows.h>
222 #include <process.h>
223 
224 #if _MSC_VER < 1700
225 typedef int bool;
226 #else
227 #include <stdbool.h>
228 #endif
229 
230 #if defined(_MSC_VER) && _MSC_VER >= 1800
231 #define strdup _strdup
232 #endif
233 
234 #ifndef EINPROGRESS
235 #define EINPROGRESS WSAEINPROGRESS
236 #endif
237 #ifndef EWOULDBLOCK
238 #define EWOULDBLOCK WSAEWOULDBLOCK
239 #endif
240 #ifndef __func__
241 #define STRX(x) #x
242 #define STR(x) STRX(x)
243 #define __func__ __FILE__ ":" STR(__LINE__)
244 #endif
245 #define snprintf _snprintf
246 #define vsnprintf _vsnprintf
247 #define to64(x) _atoi64(x)
248 #if !defined(__MINGW32__) && !defined(__MINGW64__)
249 #define popen(x, y) _popen((x), (y))
250 #define pclose(x) _pclose(x)
251 #define fileno _fileno
252 #endif
253 #if defined(_MSC_VER) && _MSC_VER >= 1400
254 #define fseeko(x, y, z) _fseeki64((x), (y), (z))
255 #else
256 #define fseeko(x, y, z) fseek((x), (y), (z))
257 #endif
258 #if defined(_MSC_VER) && _MSC_VER <= 1200
259 typedef unsigned long uintptr_t;
260 typedef long intptr_t;
261 #endif
262 typedef int socklen_t;
263 #if _MSC_VER >= 1700
264 #include <stdint.h>
265 #else
266 typedef signed char int8_t;
267 typedef unsigned char uint8_t;
268 typedef int int32_t;
269 typedef unsigned int uint32_t;
270 typedef short int16_t;
271 typedef unsigned short uint16_t;
272 typedef __int64 int64_t;
273 typedef unsigned __int64 uint64_t;
274 #endif
275 typedef SOCKET sock_t;
277 #ifndef UINT16_MAX
278 #define UINT16_MAX 65535
279 #endif
280 #ifndef UINT32_MAX
281 #define UINT32_MAX 4294967295
282 #endif
283 #ifndef pid_t
284 #define pid_t HANDLE
285 #endif
286 #define INT64_FMT "I64d"
287 #define INT64_X_FMT "I64x"
288 #define SIZE_T_FMT "Iu"
289 typedef struct _stati64 cs_stat_t;
290 #ifndef S_ISDIR
291 #define S_ISDIR(x) (((x) &_S_IFMT) == _S_IFDIR)
292 #endif
293 #ifndef S_ISREG
294 #define S_ISREG(x) (((x) &_S_IFMT) == _S_IFREG)
295 #endif
296 #define DIRSEP '\\'
297 #define CS_DEFINE_DIRENT
298 
299 #ifndef va_copy
300 #ifdef __va_copy
301 #define va_copy __va_copy
302 #else
303 #define va_copy(x, y) (x) = (y)
304 #endif
305 #endif
306 
307 #ifndef MG_MAX_HTTP_REQUEST_SIZE
308 #define MG_MAX_HTTP_REQUEST_SIZE 8192
309 #endif
310 
311 #ifndef MG_MAX_HTTP_SEND_MBUF
312 #define MG_MAX_HTTP_SEND_MBUF 4096
313 #endif
314 
315 #ifndef MG_MAX_HTTP_HEADERS
316 #define MG_MAX_HTTP_HEADERS 40
317 #endif
318 
319 #ifndef CS_ENABLE_STDIO
320 #define CS_ENABLE_STDIO 1
321 #endif
322 
323 #ifndef MG_ENABLE_BROADCAST
324 #define MG_ENABLE_BROADCAST 1
325 #endif
326 
327 #ifndef MG_ENABLE_DIRECTORY_LISTING
328 #define MG_ENABLE_DIRECTORY_LISTING 1
329 #endif
330 
331 #ifndef MG_ENABLE_FILESYSTEM
332 #define MG_ENABLE_FILESYSTEM 1
333 #endif
334 
335 #ifndef MG_ENABLE_HTTP_CGI
336 #define MG_ENABLE_HTTP_CGI MG_ENABLE_FILESYSTEM
337 #endif
338 
339 #ifndef MG_NET_IF
340 #define MG_NET_IF MG_NET_IF_SOCKET
341 #endif
342 
343 /* https://stackoverflow.com/questions/16647819/timegm-cross-platform */
344 #define timegm _mkgmtime
345 
346 #define gmtime_r(a, b) \
347  do { \
348  *(b) = *gmtime(a); \
349  } while (0)
350 
351 #endif /* CS_PLATFORM == CS_P_WINDOWS */
352 #endif /* CS_COMMON_PLATFORMS_PLATFORM_WINDOWS_H_ */
353 #ifdef MG_MODULE_LINES
354 #line 1 "common/platforms/platform_unix.h"
355 #endif
356 #ifndef CS_COMMON_PLATFORMS_PLATFORM_UNIX_H_
357 #define CS_COMMON_PLATFORMS_PLATFORM_UNIX_H_
358 #if CS_PLATFORM == CS_P_UNIX
359 
360 #ifndef _XOPEN_SOURCE
361 #define _XOPEN_SOURCE 600
362 #endif
363 
364 /* <inttypes.h> wants this for C++ */
365 #ifndef __STDC_FORMAT_MACROS
366 #define __STDC_FORMAT_MACROS
367 #endif
368 
369 /* C++ wants that for INT64_MAX */
370 #ifndef __STDC_LIMIT_MACROS
371 #define __STDC_LIMIT_MACROS
372 #endif
373 
374 /* Enable fseeko() and ftello() functions */
375 #ifndef _LARGEFILE_SOURCE
376 #define _LARGEFILE_SOURCE
377 #endif
378 
379 /* Enable 64-bit file offsets */
380 #ifndef _FILE_OFFSET_BITS
381 #define _FILE_OFFSET_BITS 64
382 #endif
383 
384 #include <arpa/inet.h>
385 #include <assert.h>
386 #include <ctype.h>
387 #include <dirent.h>
388 #include <errno.h>
389 #include <fcntl.h>
390 #include <inttypes.h>
391 #include <stdint.h>
392 #include <limits.h>
393 #include <math.h>
394 #include <netdb.h>
395 #include <netinet/in.h>
396 #include <pthread.h>
397 #include <signal.h>
398 #include <stdarg.h>
399 #include <stdbool.h>
400 #include <stdio.h>
401 #include <stdlib.h>
402 #include <string.h>
403 #include <sys/param.h>
404 #include <sys/socket.h>
405 #include <sys/select.h>
406 #include <sys/stat.h>
407 #include <sys/time.h>
408 #include <sys/types.h>
409 #include <unistd.h>
410 
411 #ifdef __APPLE__
412 #include <machine/endian.h>
413 #ifndef BYTE_ORDER
414 #define LITTLE_ENDIAN __DARWIN_LITTLE_ENDIAN
415 #define BIG_ENDIAN __DARWIN_BIG_ENDIAN
416 #define PDP_ENDIAN __DARWIN_PDP_ENDIAN
417 #define BYTE_ORDER __DARWIN_BYTE_ORDER
418 #endif
419 #endif
420 
421 /*
422  * osx correctly avoids defining strtoll when compiling in strict ansi mode.
423  * c++ 11 standard defines strtoll as well.
424  * We require strtoll, and if your embedded pre-c99 compiler lacks one, please
425  * implement a shim.
426  */
427 #if !(defined(__cplusplus) && __cplusplus >= 201103L) && \
428  !(defined(__DARWIN_C_LEVEL) && __DARWIN_C_LEVEL >= 200809L)
429 long long strtoll(const char *, char **, int);
430 #endif
431 
432 typedef int sock_t;
433 #define INVALID_SOCKET (-1)
434 #define SIZE_T_FMT "zu"
435 typedef struct stat cs_stat_t;
436 #define DIRSEP '/'
437 #define to64(x) strtoll(x, NULL, 10)
438 #define INT64_FMT PRId64
439 #define INT64_X_FMT PRIx64
440 
441 #ifndef __cdecl
442 #define __cdecl
443 #endif
444 
445 #ifndef va_copy
446 #ifdef __va_copy
447 #define va_copy __va_copy
448 #else
449 #define va_copy(x, y) (x) = (y)
450 #endif
451 #endif
452 
453 #define closesocket(x) close(x)
454 
455 #ifndef MG_MAX_HTTP_REQUEST_SIZE
456 #define MG_MAX_HTTP_REQUEST_SIZE 8192
457 #endif
458 
459 #ifndef MG_MAX_HTTP_SEND_MBUF
460 #define MG_MAX_HTTP_SEND_MBUF 4096
461 #endif
462 
463 #ifndef MG_MAX_HTTP_HEADERS
464 #define MG_MAX_HTTP_HEADERS 40
465 #endif
466 
467 #ifndef CS_ENABLE_STDIO
468 #define CS_ENABLE_STDIO 1
469 #endif
470 
471 #ifndef MG_ENABLE_BROADCAST
472 #define MG_ENABLE_BROADCAST 1
473 #endif
474 
475 #ifndef MG_ENABLE_DIRECTORY_LISTING
476 #define MG_ENABLE_DIRECTORY_LISTING 1
477 #endif
478 
479 #ifndef MG_ENABLE_FILESYSTEM
480 #define MG_ENABLE_FILESYSTEM 1
481 #endif
482 
483 #ifndef MG_ENABLE_HTTP_CGI
484 #define MG_ENABLE_HTTP_CGI MG_ENABLE_FILESYSTEM
485 #endif
486 
487 #ifndef MG_NET_IF
488 #define MG_NET_IF MG_NET_IF_SOCKET
489 #endif
490 
491 #ifndef MG_HOSTS_FILE_NAME
492 #define MG_HOSTS_FILE_NAME "/etc/hosts"
493 #endif
494 
495 #ifndef MG_RESOLV_CONF_FILE_NAME
496 #define MG_RESOLV_CONF_FILE_NAME "/etc/resolv.conf"
497 #endif
498 
499 #endif /* CS_PLATFORM == CS_P_UNIX */
500 #endif /* CS_COMMON_PLATFORMS_PLATFORM_UNIX_H_ */
501 #ifdef MG_MODULE_LINES
502 #line 1 "common/platforms/platform_esp32.h"
503 #endif
504 /*
505  * Copyright (c) 2014-2018 Cesanta Software Limited
506  * All rights reserved
507  *
508  * Licensed under the Apache License, Version 2.0 (the ""License"");
509  * you may not use this file except in compliance with the License.
510  * You may obtain a copy of the License at
511  *
512  * http://www.apache.org/licenses/LICENSE-2.0
513  *
514  * Unless required by applicable law or agreed to in writing, software
515  * distributed under the License is distributed on an ""AS IS"" BASIS,
516  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
517  * See the License for the specific language governing permissions and
518  * limitations under the License.
519  */
520 
521 #ifndef CS_COMMON_PLATFORMS_PLATFORM_ESP32_H_
522 #define CS_COMMON_PLATFORMS_PLATFORM_ESP32_H_
523 #if CS_PLATFORM == CS_P_ESP32
524 
525 #include <assert.h>
526 #include <ctype.h>
527 #include <dirent.h>
528 #include <fcntl.h>
529 #include <inttypes.h>
530 #include <machine/endian.h>
531 #include <stdbool.h>
532 #include <stdint.h>
533 #include <string.h>
534 #include <sys/stat.h>
535 #include <sys/time.h>
536 
537 #define SIZE_T_FMT "u"
538 typedef struct stat cs_stat_t;
539 #define DIRSEP '/'
540 #define to64(x) strtoll(x, NULL, 10)
541 #define INT64_FMT PRId64
542 #define INT64_X_FMT PRIx64
543 #define __cdecl
544 #define _FILE_OFFSET_BITS 32
545 
546 #define MG_LWIP 1
547 
548 #ifndef MG_NET_IF
549 #define MG_NET_IF MG_NET_IF_SOCKET
550 #endif
551 
552 #ifndef CS_ENABLE_STDIO
553 #define CS_ENABLE_STDIO 1
554 #endif
555 
556 #endif /* CS_PLATFORM == CS_P_ESP32 */
557 #endif /* CS_COMMON_PLATFORMS_PLATFORM_ESP32_H_ */
558 #ifdef MG_MODULE_LINES
559 #line 1 "common/platforms/platform_esp8266.h"
560 #endif
561 /*
562  * Copyright (c) 2014-2018 Cesanta Software Limited
563  * All rights reserved
564  *
565  * Licensed under the Apache License, Version 2.0 (the ""License"");
566  * you may not use this file except in compliance with the License.
567  * You may obtain a copy of the License at
568  *
569  * http://www.apache.org/licenses/LICENSE-2.0
570  *
571  * Unless required by applicable law or agreed to in writing, software
572  * distributed under the License is distributed on an ""AS IS"" BASIS,
573  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
574  * See the License for the specific language governing permissions and
575  * limitations under the License.
576  */
577 
578 #ifndef CS_COMMON_PLATFORMS_PLATFORM_ESP8266_H_
579 #define CS_COMMON_PLATFORMS_PLATFORM_ESP8266_H_
580 #if CS_PLATFORM == CS_P_ESP8266
581 
582 #include <assert.h>
583 #include <ctype.h>
584 #include <fcntl.h>
585 #include <inttypes.h>
586 #include <machine/endian.h>
587 #include <stdbool.h>
588 #include <string.h>
589 #include <sys/stat.h>
590 #include <sys/time.h>
591 
592 #define SIZE_T_FMT "u"
593 typedef struct stat cs_stat_t;
594 #define DIRSEP '/'
595 #if !defined(MGOS_VFS_DEFINE_DIRENT)
596 #define CS_DEFINE_DIRENT
597 #endif
598 
599 #define to64(x) strtoll(x, NULL, 10)
600 #define INT64_FMT PRId64
601 #define INT64_X_FMT PRIx64
602 #define __cdecl
603 #define _FILE_OFFSET_BITS 32
604 
605 #define MG_LWIP 1
606 
607 /* struct timeval is defined in sys/time.h. */
608 #define LWIP_TIMEVAL_PRIVATE 0
609 
610 #ifndef MG_NET_IF
611 #include <lwip/opt.h>
612 #if LWIP_SOCKET /* RTOS SDK has LWIP sockets */
613 #define MG_NET_IF MG_NET_IF_SOCKET
614 #else
615 #define MG_NET_IF MG_NET_IF_LWIP_LOW_LEVEL
616 #endif
617 #endif
618 
619 #ifndef CS_ENABLE_STDIO
620 #define CS_ENABLE_STDIO 1
621 #endif
622 
623 #define inet_ntop(af, src, dst, size) \
624  (((af) == AF_INET) ? ipaddr_ntoa_r((const ip_addr_t *) (src), (dst), (size)) \
625  : NULL)
626 #define inet_pton(af, src, dst) \
627  (((af) == AF_INET) ? ipaddr_aton((src), (ip_addr_t *) (dst)) : 0)
628 
629 #endif /* CS_PLATFORM == CS_P_ESP8266 */
630 #endif /* CS_COMMON_PLATFORMS_PLATFORM_ESP8266_H_ */
631 #ifdef MG_MODULE_LINES
632 #line 1 "common/platforms/platform_cc3100.h"
633 #endif
634 /*
635  * Copyright (c) 2014-2018 Cesanta Software Limited
636  * All rights reserved
637  *
638  * Licensed under the Apache License, Version 2.0 (the ""License"");
639  * you may not use this file except in compliance with the License.
640  * You may obtain a copy of the License at
641  *
642  * http://www.apache.org/licenses/LICENSE-2.0
643  *
644  * Unless required by applicable law or agreed to in writing, software
645  * distributed under the License is distributed on an ""AS IS"" BASIS,
646  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
647  * See the License for the specific language governing permissions and
648  * limitations under the License.
649  */
650 
651 #ifndef CS_COMMON_PLATFORMS_PLATFORM_CC3100_H_
652 #define CS_COMMON_PLATFORMS_PLATFORM_CC3100_H_
653 #if CS_PLATFORM == CS_P_CC3100
654 
655 #include <assert.h>
656 #include <ctype.h>
657 #include <errno.h>
658 #include <inttypes.h>
659 #include <stdint.h>
660 #include <string.h>
661 #include <time.h>
662 
663 #define MG_NET_IF MG_NET_IF_SIMPLELINK
664 #define MG_SSL_IF MG_SSL_IF_SIMPLELINK
665 
666 /*
667  * CC3100 SDK and STM32 SDK include headers w/out path, just like
668  * #include "simplelink.h". As result, we have to add all required directories
669  * into Makefile IPATH and do the same thing (include w/out path)
670  */
671 
672 #include <simplelink.h>
673 #include <netapp.h>
674 #undef timeval
675 
676 typedef int sock_t;
677 #define INVALID_SOCKET (-1)
678 
679 #define to64(x) strtoll(x, NULL, 10)
680 #define INT64_FMT PRId64
681 #define INT64_X_FMT PRIx64
682 #define SIZE_T_FMT "u"
683 
684 #define SOMAXCONN 8
685 
686 const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
687 char *inet_ntoa(struct in_addr in);
688 int inet_pton(int af, const char *src, void *dst);
689 
690 #endif /* CS_PLATFORM == CS_P_CC3100 */
691 #endif /* CS_COMMON_PLATFORMS_PLATFORM_CC3100_H_ */
692 #ifdef MG_MODULE_LINES
693 #line 1 "common/platforms/platform_cc3200.h"
694 #endif
695 /*
696  * Copyright (c) 2014-2018 Cesanta Software Limited
697  * All rights reserved
698  *
699  * Licensed under the Apache License, Version 2.0 (the ""License"");
700  * you may not use this file except in compliance with the License.
701  * You may obtain a copy of the License at
702  *
703  * http://www.apache.org/licenses/LICENSE-2.0
704  *
705  * Unless required by applicable law or agreed to in writing, software
706  * distributed under the License is distributed on an ""AS IS"" BASIS,
707  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
708  * See the License for the specific language governing permissions and
709  * limitations under the License.
710  */
711 
712 #ifndef CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_
713 #define CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_
714 #if CS_PLATFORM == CS_P_CC3200
715 
716 #include <assert.h>
717 #include <ctype.h>
718 #include <errno.h>
719 #include <inttypes.h>
720 #include <stdbool.h>
721 #include <stdint.h>
722 #include <string.h>
723 #include <time.h>
724 
725 #ifndef __TI_COMPILER_VERSION__
726 #include <fcntl.h>
727 #include <sys/time.h>
728 #endif
729 
730 #define MG_NET_IF MG_NET_IF_SIMPLELINK
731 #define MG_SSL_IF MG_SSL_IF_SIMPLELINK
732 
733 /* Only SPIFFS supports directories, SLFS does not. */
734 #if defined(CC3200_FS_SPIFFS) && !defined(MG_ENABLE_DIRECTORY_LISTING)
735 #define MG_ENABLE_DIRECTORY_LISTING 1
736 #endif
737 
738 /* Amalgamated: #include "common/platforms/simplelink/cs_simplelink.h" */
739 
740 typedef int sock_t;
741 #define INVALID_SOCKET (-1)
742 #define SIZE_T_FMT "u"
743 typedef struct stat cs_stat_t;
744 #define DIRSEP '/'
745 #define to64(x) strtoll(x, NULL, 10)
746 #define INT64_FMT PRId64
747 #define INT64_X_FMT PRIx64
748 #define __cdecl
749 
750 #define fileno(x) -1
751 
752 /* Some functions we implement for Mongoose. */
753 
754 #ifdef __cplusplus
755 extern "C" {
756 #endif
757 
758 #ifdef __TI_COMPILER_VERSION__
759 struct SlTimeval_t;
760 #define timeval SlTimeval_t
761 int gettimeofday(struct timeval *t, void *tz);
762 int settimeofday(const struct timeval *tv, const void *tz);
763 
764 int asprintf(char **strp, const char *fmt, ...);
765 
766 #endif
767 
768 /* TI's libc does not have stat & friends, add them. */
769 #ifdef __TI_COMPILER_VERSION__
770 
771 #include <file.h>
772 
773 typedef unsigned int mode_t;
774 typedef size_t _off_t;
775 typedef long ssize_t;
776 
777 struct stat {
778  int st_ino;
779  mode_t st_mode;
780  int st_nlink;
781  time_t st_mtime;
782  off_t st_size;
783 };
784 
785 int _stat(const char *pathname, struct stat *st);
786 int stat(const char *pathname, struct stat *st);
787 
788 #define __S_IFMT 0170000
789 
790 #define __S_IFDIR 0040000
791 #define __S_IFCHR 0020000
792 #define __S_IFREG 0100000
793 
794 #define __S_ISTYPE(mode, mask) (((mode) &__S_IFMT) == (mask))
795 
796 #define S_IFDIR __S_IFDIR
797 #define S_IFCHR __S_IFCHR
798 #define S_IFREG __S_IFREG
799 #define S_ISDIR(mode) __S_ISTYPE((mode), __S_IFDIR)
800 #define S_ISREG(mode) __S_ISTYPE((mode), __S_IFREG)
801 
802 /* 5.x series compilers don't have va_copy, 16.x do. */
803 #if __TI_COMPILER_VERSION__ < 16000000
804 #define va_copy(apc, ap) ((apc) = (ap))
805 #endif
806 
807 #endif /* __TI_COMPILER_VERSION__ */
808 
809 #ifdef CC3200_FS_SLFS
810 #define MG_FS_SLFS
811 #endif
812 
813 #if (defined(CC3200_FS_SPIFFS) || defined(CC3200_FS_SLFS)) && \
814  !defined(MG_ENABLE_FILESYSTEM)
815 #define MG_ENABLE_FILESYSTEM 1
816 #define CS_DEFINE_DIRENT
817 #endif
818 
819 #ifndef CS_ENABLE_STDIO
820 #define CS_ENABLE_STDIO 1
821 #endif
822 
823 #ifdef __cplusplus
824 }
825 #endif
826 
827 #endif /* CS_PLATFORM == CS_P_CC3200 */
828 #endif /* CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_ */
829 #ifdef MG_MODULE_LINES
830 #line 1 "common/platforms/platform_cc3220.h"
831 #endif
832 /*
833  * Copyright (c) 2014-2018 Cesanta Software Limited
834  * All rights reserved
835  *
836  * Licensed under the Apache License, Version 2.0 (the ""License"");
837  * you may not use this file except in compliance with the License.
838  * You may obtain a copy of the License at
839  *
840  * http://www.apache.org/licenses/LICENSE-2.0
841  *
842  * Unless required by applicable law or agreed to in writing, software
843  * distributed under the License is distributed on an ""AS IS"" BASIS,
844  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
845  * See the License for the specific language governing permissions and
846  * limitations under the License.
847  */
848 
849 #ifndef CS_COMMON_PLATFORMS_PLATFORM_CC3220_H_
850 #define CS_COMMON_PLATFORMS_PLATFORM_CC3220_H_
851 #if CS_PLATFORM == CS_P_CC3220
852 
853 #include <assert.h>
854 #include <ctype.h>
855 #include <errno.h>
856 #include <inttypes.h>
857 #include <stdbool.h>
858 #include <stdint.h>
859 #include <string.h>
860 #include <time.h>
861 
862 #ifndef __TI_COMPILER_VERSION__
863 #include <fcntl.h>
864 #include <sys/time.h>
865 #endif
866 
867 #define MG_NET_IF MG_NET_IF_SIMPLELINK
868 #ifndef MG_SSL_IF
869 #define MG_SSL_IF MG_SSL_IF_SIMPLELINK
870 #endif
871 
872 /* Only SPIFFS supports directories, SLFS does not. */
873 #if defined(CC3220_FS_SPIFFS) && !defined(MG_ENABLE_DIRECTORY_LISTING)
874 #define MG_ENABLE_DIRECTORY_LISTING 1
875 #endif
876 
877 /* Amalgamated: #include "common/platforms/simplelink/cs_simplelink.h" */
878 
879 typedef int sock_t;
880 #define INVALID_SOCKET (-1)
881 #define SIZE_T_FMT "u"
882 typedef struct stat cs_stat_t;
883 #define DIRSEP '/'
884 #define to64(x) strtoll(x, NULL, 10)
885 #define INT64_FMT PRId64
886 #define INT64_X_FMT PRIx64
887 #define __cdecl
888 
889 #define fileno(x) -1
890 
891 /* Some functions we implement for Mongoose. */
892 
893 #ifdef __cplusplus
894 extern "C" {
895 #endif
896 
897 #ifdef __TI_COMPILER_VERSION__
898 struct SlTimeval_t;
899 #define timeval SlTimeval_t
900 int gettimeofday(struct timeval *t, void *tz);
901 int settimeofday(const struct timeval *tv, const void *tz);
902 
903 int asprintf(char **strp, const char *fmt, ...);
904 
905 #endif
906 
907 /* TI's libc does not have stat & friends, add them. */
908 #ifdef __TI_COMPILER_VERSION__
909 
910 #include <file.h>
911 
912 typedef unsigned int mode_t;
913 typedef size_t _off_t;
914 typedef long ssize_t;
915 
916 struct stat {
917  int st_ino;
918  mode_t st_mode;
919  int st_nlink;
920  time_t st_mtime;
921  off_t st_size;
922 };
923 
924 int _stat(const char *pathname, struct stat *st);
925 int stat(const char *pathname, struct stat *st);
926 
927 #define __S_IFMT 0170000
928 
929 #define __S_IFDIR 0040000
930 #define __S_IFCHR 0020000
931 #define __S_IFREG 0100000
932 
933 #define __S_ISTYPE(mode, mask) (((mode) &__S_IFMT) == (mask))
934 
935 #define S_IFDIR __S_IFDIR
936 #define S_IFCHR __S_IFCHR
937 #define S_IFREG __S_IFREG
938 #define S_ISDIR(mode) __S_ISTYPE((mode), __S_IFDIR)
939 #define S_ISREG(mode) __S_ISTYPE((mode), __S_IFREG)
940 
941 #endif /* __TI_COMPILER_VERSION__ */
942 
943 #ifndef CS_ENABLE_STDIO
944 #define CS_ENABLE_STDIO 1
945 #endif
946 
947 #ifdef __cplusplus
948 }
949 #endif
950 
951 #endif /* CS_PLATFORM == CS_P_CC3220 */
952 #endif /* CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_ */
953 #ifdef MG_MODULE_LINES
954 #line 1 "common/platforms/platform_msp432.h"
955 #endif
956 /*
957  * Copyright (c) 2014-2018 Cesanta Software Limited
958  * All rights reserved
959  *
960  * Licensed under the Apache License, Version 2.0 (the ""License"");
961  * you may not use this file except in compliance with the License.
962  * You may obtain a copy of the License at
963  *
964  * http://www.apache.org/licenses/LICENSE-2.0
965  *
966  * Unless required by applicable law or agreed to in writing, software
967  * distributed under the License is distributed on an ""AS IS"" BASIS,
968  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
969  * See the License for the specific language governing permissions and
970  * limitations under the License.
971  */
972 
973 #ifndef CS_COMMON_PLATFORMS_PLATFORM_MSP432_H_
974 #define CS_COMMON_PLATFORMS_PLATFORM_MSP432_H_
975 #if CS_PLATFORM == CS_P_MSP432
976 
977 #include <assert.h>
978 #include <ctype.h>
979 #include <errno.h>
980 #include <inttypes.h>
981 #include <stdint.h>
982 #include <string.h>
983 #include <time.h>
984 
985 #ifndef __TI_COMPILER_VERSION__
986 #include <fcntl.h>
987 #include <sys/time.h>
988 #endif
989 
990 #define MG_NET_IF MG_NET_IF_SIMPLELINK
991 #define MG_SSL_IF MG_SSL_IF_SIMPLELINK
992 
993 /* Amalgamated: #include "common/platforms/simplelink/cs_simplelink.h" */
994 
995 typedef int sock_t;
996 #define INVALID_SOCKET (-1)
997 #define SIZE_T_FMT "u"
998 typedef struct stat cs_stat_t;
999 #define DIRSEP '/'
1000 #define to64(x) strtoll(x, NULL, 10)
1001 #define INT64_FMT PRId64
1002 #define INT64_X_FMT PRIx64
1003 #define __cdecl
1004 
1005 #define fileno(x) -1
1006 
1007 /* Some functions we implement for Mongoose. */
1008 
1009 #ifdef __cplusplus
1010 extern "C" {
1011 #endif
1012 
1013 #ifdef __TI_COMPILER_VERSION__
1014 struct SlTimeval_t;
1015 #define timeval SlTimeval_t
1016 int gettimeofday(struct timeval *t, void *tz);
1017 #endif
1018 
1019 /* TI's libc does not have stat & friends, add them. */
1020 #ifdef __TI_COMPILER_VERSION__
1021 
1022 #include <file.h>
1023 
1024 typedef unsigned int mode_t;
1025 typedef size_t _off_t;
1026 typedef long ssize_t;
1027 
1028 struct stat {
1029  int st_ino;
1030  mode_t st_mode;
1031  int st_nlink;
1032  time_t st_mtime;
1033  off_t st_size;
1034 };
1035 
1036 int _stat(const char *pathname, struct stat *st);
1037 #define stat(a, b) _stat(a, b)
1038 
1039 #define __S_IFMT 0170000
1040 
1041 #define __S_IFDIR 0040000
1042 #define __S_IFCHR 0020000
1043 #define __S_IFREG 0100000
1044 
1045 #define __S_ISTYPE(mode, mask) (((mode) &__S_IFMT) == (mask))
1046 
1047 #define S_IFDIR __S_IFDIR
1048 #define S_IFCHR __S_IFCHR
1049 #define S_IFREG __S_IFREG
1050 #define S_ISDIR(mode) __S_ISTYPE((mode), __S_IFDIR)
1051 #define S_ISREG(mode) __S_ISTYPE((mode), __S_IFREG)
1052 
1053 /* As of 5.2.7, TI compiler does not support va_copy() yet. */
1054 #define va_copy(apc, ap) ((apc) = (ap))
1055 
1056 #endif /* __TI_COMPILER_VERSION__ */
1057 
1058 #ifndef CS_ENABLE_STDIO
1059 #define CS_ENABLE_STDIO 1
1060 #endif
1061 
1062 #if (defined(CC3200_FS_SPIFFS) || defined(CC3200_FS_SLFS)) && \
1063  !defined(MG_ENABLE_FILESYSTEM)
1064 #define MG_ENABLE_FILESYSTEM 1
1065 #endif
1066 
1067 #ifdef __cplusplus
1068 }
1069 #endif
1070 
1071 #endif /* CS_PLATFORM == CS_P_MSP432 */
1072 #endif /* CS_COMMON_PLATFORMS_PLATFORM_MSP432_H_ */
1073 #ifdef MG_MODULE_LINES
1074 #line 1 "common/platforms/platform_tm4c129.h"
1075 #endif
1076 /*
1077  * Copyright (c) 2014-2018 Cesanta Software Limited
1078  * All rights reserved
1079  *
1080  * Licensed under the Apache License, Version 2.0 (the ""License"");
1081  * you may not use this file except in compliance with the License.
1082  * You may obtain a copy of the License at
1083  *
1084  * http://www.apache.org/licenses/LICENSE-2.0
1085  *
1086  * Unless required by applicable law or agreed to in writing, software
1087  * distributed under the License is distributed on an ""AS IS"" BASIS,
1088  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1089  * See the License for the specific language governing permissions and
1090  * limitations under the License.
1091  */
1092 
1093 #ifndef CS_COMMON_PLATFORMS_PLATFORM_TM4C129_H_
1094 #define CS_COMMON_PLATFORMS_PLATFORM_TM4C129_H_
1095 #if CS_PLATFORM == CS_P_TM4C129
1096 
1097 #include <assert.h>
1098 #include <ctype.h>
1099 #include <errno.h>
1100 #include <inttypes.h>
1101 #include <stdint.h>
1102 #include <string.h>
1103 #include <time.h>
1104 
1105 #ifndef __TI_COMPILER_VERSION__
1106 #include <fcntl.h>
1107 #include <sys/time.h>
1108 #endif
1109 
1110 #define SIZE_T_FMT "u"
1111 typedef struct stat cs_stat_t;
1112 #define DIRSEP '/'
1113 #define to64(x) strtoll(x, NULL, 10)
1114 #define INT64_FMT PRId64
1115 #define INT64_X_FMT PRIx64
1116 #define __cdecl
1117 
1118 #ifndef MG_NET_IF
1119 #include <lwip/opt.h>
1120 #if LWIP_SOCKET
1121 #define MG_NET_IF MG_NET_IF_SOCKET
1122 #else
1123 #define MG_NET_IF MG_NET_IF_LWIP_LOW_LEVEL
1124 #endif
1125 #define MG_LWIP 1
1126 #elif MG_NET_IF == MG_NET_IF_SIMPLELINK
1127 /* Amalgamated: #include "common/platforms/simplelink/cs_simplelink.h" */
1128 #endif
1129 
1130 #ifndef CS_ENABLE_STDIO
1131 #define CS_ENABLE_STDIO 1
1132 #endif
1133 
1134 #ifdef __TI_COMPILER_VERSION__
1135 /* As of 5.2.8, TI compiler does not support va_copy() yet. */
1136 #define va_copy(apc, ap) ((apc) = (ap))
1137 #endif /* __TI_COMPILER_VERSION__ */
1138 
1139 #ifdef __cplusplus
1140 }
1141 #endif
1142 
1143 #endif /* CS_PLATFORM == CS_P_TM4C129 */
1144 #endif /* CS_COMMON_PLATFORMS_PLATFORM_TM4C129_H_ */
1145 #ifdef MG_MODULE_LINES
1146 #line 1 "common/platforms/platform_mbed.h"
1147 #endif
1148 /*
1149  * Copyright (c) 2014-2018 Cesanta Software Limited
1150  * All rights reserved
1151  *
1152  * Licensed under the Apache License, Version 2.0 (the ""License"");
1153  * you may not use this file except in compliance with the License.
1154  * You may obtain a copy of the License at
1155  *
1156  * http://www.apache.org/licenses/LICENSE-2.0
1157  *
1158  * Unless required by applicable law or agreed to in writing, software
1159  * distributed under the License is distributed on an ""AS IS"" BASIS,
1160  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1161  * See the License for the specific language governing permissions and
1162  * limitations under the License.
1163  */
1164 
1165 #ifndef CS_COMMON_PLATFORMS_PLATFORM_MBED_H_
1166 #define CS_COMMON_PLATFORMS_PLATFORM_MBED_H_
1167 #if CS_PLATFORM == CS_P_MBED
1168 
1169 /*
1170  * mbed.h contains C++ code (e.g. templates), thus, it should be processed
1171  * only if included directly to startup file (ex: main.cpp)
1172  */
1173 #ifdef __cplusplus
1174 /* Amalgamated: #include "mbed.h" */
1175 #endif /* __cplusplus */
1176 
1177 #include <assert.h>
1178 #include <ctype.h>
1179 #include <errno.h>
1180 #include <inttypes.h>
1181 #include <stdint.h>
1182 #include <string.h>
1183 #include <time.h>
1184 #include <sys/stat.h>
1185 #include <sys/types.h>
1186 #include <fcntl.h>
1187 #include <stdio.h>
1188 
1189 typedef struct stat cs_stat_t;
1190 #define DIRSEP '/'
1191 
1192 #ifndef CS_ENABLE_STDIO
1193 #define CS_ENABLE_STDIO 1
1194 #endif
1195 
1196 /*
1197  * mbed can be compiled with the ARM compiler which
1198  * just doesn't come with a gettimeofday shim
1199  * because it's a BSD API and ARM targets embedded
1200  * non-unix platforms.
1201  */
1202 #if defined(__ARMCC_VERSION) || defined(__ICCARM__)
1203 #define _TIMEVAL_DEFINED
1204 #define gettimeofday _gettimeofday
1205 
1206 /* copied from GCC on ARM; for some reason useconds are signed */
1207 typedef long suseconds_t; /* microseconds (signed) */
1208 struct timeval {
1209  time_t tv_sec; /* seconds */
1210  suseconds_t tv_usec; /* and microseconds */
1211 };
1212 
1213 #endif
1214 
1215 #if MG_NET_IF == MG_NET_IF_SIMPLELINK
1216 
1217 #define MG_SIMPLELINK_NO_OSI 1
1218 
1219 #include <simplelink.h>
1220 
1221 typedef int sock_t;
1222 #define INVALID_SOCKET (-1)
1223 
1224 #define to64(x) strtoll(x, NULL, 10)
1225 #define INT64_FMT PRId64
1226 #define INT64_X_FMT PRIx64
1227 #define SIZE_T_FMT "u"
1228 
1229 #define SOMAXCONN 8
1230 
1231 const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
1232 char *inet_ntoa(struct in_addr in);
1233 int inet_pton(int af, const char *src, void *dst);
1234 int inet_aton(const char *cp, struct in_addr *inp);
1235 in_addr_t inet_addr(const char *cp);
1236 
1237 #endif /* MG_NET_IF == MG_NET_IF_SIMPLELINK */
1238 
1239 #endif /* CS_PLATFORM == CS_P_MBED */
1240 #endif /* CS_COMMON_PLATFORMS_PLATFORM_MBED_H_ */
1241 #ifdef MG_MODULE_LINES
1242 #line 1 "common/platforms/platform_nrf51.h"
1243 #endif
1244 /*
1245  * Copyright (c) 2014-2018 Cesanta Software Limited
1246  * All rights reserved
1247  *
1248  * Licensed under the Apache License, Version 2.0 (the ""License"");
1249  * you may not use this file except in compliance with the License.
1250  * You may obtain a copy of the License at
1251  *
1252  * http://www.apache.org/licenses/LICENSE-2.0
1253  *
1254  * Unless required by applicable law or agreed to in writing, software
1255  * distributed under the License is distributed on an ""AS IS"" BASIS,
1256  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1257  * See the License for the specific language governing permissions and
1258  * limitations under the License.
1259  */
1260 #ifndef CS_COMMON_PLATFORMS_PLATFORM_NRF51_H_
1261 #define CS_COMMON_PLATFORMS_PLATFORM_NRF51_H_
1262 #if CS_PLATFORM == CS_P_NRF51
1263 
1264 #include <assert.h>
1265 #include <ctype.h>
1266 #include <inttypes.h>
1267 #include <stdint.h>
1268 #include <string.h>
1269 #include <time.h>
1270 
1271 #define to64(x) strtoll(x, NULL, 10)
1272 
1273 #define MG_NET_IF MG_NET_IF_LWIP_LOW_LEVEL
1274 #define MG_LWIP 1
1275 #define MG_ENABLE_IPV6 1
1276 
1277 /*
1278  * For ARM C Compiler, make lwip to export `struct timeval`; for other
1279  * compilers, suppress it.
1280  */
1281 #if !defined(__ARMCC_VERSION)
1282 #define LWIP_TIMEVAL_PRIVATE 0
1283 #else
1284 struct timeval;
1285 int gettimeofday(struct timeval *tp, void *tzp);
1286 #endif
1287 
1288 #define INT64_FMT PRId64
1289 #define SIZE_T_FMT "u"
1290 
1291 /*
1292  * ARM C Compiler doesn't have strdup, so we provide it
1293  */
1294 #define CS_ENABLE_STRDUP defined(__ARMCC_VERSION)
1295 
1296 #endif /* CS_PLATFORM == CS_P_NRF51 */
1297 #endif /* CS_COMMON_PLATFORMS_PLATFORM_NRF51_H_ */
1298 #ifdef MG_MODULE_LINES
1299 #line 1 "common/platforms/platform_nrf52.h"
1300 #endif
1301 /*
1302  * Copyright (c) 2014-2018 Cesanta Software Limited
1303  * All rights reserved
1304  *
1305  * Licensed under the Apache License, Version 2.0 (the ""License"");
1306  * you may not use this file except in compliance with the License.
1307  * You may obtain a copy of the License at
1308  *
1309  * http://www.apache.org/licenses/LICENSE-2.0
1310  *
1311  * Unless required by applicable law or agreed to in writing, software
1312  * distributed under the License is distributed on an ""AS IS"" BASIS,
1313  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1314  * See the License for the specific language governing permissions and
1315  * limitations under the License.
1316  */
1317 #ifndef CS_COMMON_PLATFORMS_PLATFORM_NRF52_H_
1318 #define CS_COMMON_PLATFORMS_PLATFORM_NRF52_H_
1319 #if CS_PLATFORM == CS_P_NRF52
1320 
1321 #include <assert.h>
1322 #include <ctype.h>
1323 #include <errno.h>
1324 #include <inttypes.h>
1325 #include <stdbool.h>
1326 #include <stdint.h>
1327 #include <string.h>
1328 #include <time.h>
1329 
1330 #define to64(x) strtoll(x, NULL, 10)
1331 
1332 #define MG_NET_IF MG_NET_IF_LWIP_LOW_LEVEL
1333 #define MG_LWIP 1
1334 #define MG_ENABLE_IPV6 1
1335 
1336 #if !defined(ENOSPC)
1337 #define ENOSPC 28 /* No space left on device */
1338 #endif
1339 
1340 /*
1341  * For ARM C Compiler, make lwip to export `struct timeval`; for other
1342  * compilers, suppress it.
1343  */
1344 #if !defined(__ARMCC_VERSION)
1345 #define LWIP_TIMEVAL_PRIVATE 0
1346 #endif
1347 
1348 #define INT64_FMT PRId64
1349 #define SIZE_T_FMT "u"
1350 
1351 /*
1352  * ARM C Compiler doesn't have strdup, so we provide it
1353  */
1354 #define CS_ENABLE_STRDUP defined(__ARMCC_VERSION)
1355 
1356 #endif /* CS_PLATFORM == CS_P_NRF52 */
1357 #endif /* CS_COMMON_PLATFORMS_PLATFORM_NRF52_H_ */
1358 #ifdef MG_MODULE_LINES
1359 #line 1 "common/platforms/simplelink/cs_simplelink.h"
1360 #endif
1361 /*
1362  * Copyright (c) 2014-2018 Cesanta Software Limited
1363  * All rights reserved
1364  *
1365  * Licensed under the Apache License, Version 2.0 (the ""License"");
1366  * you may not use this file except in compliance with the License.
1367  * You may obtain a copy of the License at
1368  *
1369  * http://www.apache.org/licenses/LICENSE-2.0
1370  *
1371  * Unless required by applicable law or agreed to in writing, software
1372  * distributed under the License is distributed on an ""AS IS"" BASIS,
1373  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1374  * See the License for the specific language governing permissions and
1375  * limitations under the License.
1376  */
1377 
1378 #ifndef CS_COMMON_PLATFORMS_SIMPLELINK_CS_SIMPLELINK_H_
1379 #define CS_COMMON_PLATFORMS_SIMPLELINK_CS_SIMPLELINK_H_
1380 
1381 #if defined(MG_NET_IF) && MG_NET_IF == MG_NET_IF_SIMPLELINK
1382 
1383 /* If simplelink.h is already included, all bets are off. */
1384 #if !defined(__SIMPLELINK_H__)
1385 
1386 #include <stdbool.h>
1387 
1388 #ifndef __TI_COMPILER_VERSION__
1389 #undef __CONCAT
1390 #undef FD_CLR
1391 #undef FD_ISSET
1392 #undef FD_SET
1393 #undef FD_SETSIZE
1394 #undef FD_ZERO
1395 #undef fd_set
1396 #endif
1397 
1398 #if CS_PLATFORM == CS_P_CC3220
1399 #include <ti/drivers/net/wifi/porting/user.h>
1400 #include <ti/drivers/net/wifi/simplelink.h>
1401 #include <ti/drivers/net/wifi/sl_socket.h>
1402 #include <ti/drivers/net/wifi/netapp.h>
1403 #else
1404 /* We want to disable SL_INC_STD_BSD_API_NAMING, so we include user.h ourselves
1405  * and undef it. */
1406 #define PROVISIONING_API_H_
1407 #include <simplelink/user.h>
1408 #undef PROVISIONING_API_H_
1409 #undef SL_INC_STD_BSD_API_NAMING
1410 
1411 #include <simplelink/include/simplelink.h>
1412 #include <simplelink/include/netapp.h>
1413 #endif /* CS_PLATFORM == CS_P_CC3220 */
1414 
1415 /* Now define only the subset of the BSD API that we use.
1416  * Notably, close(), read() and write() are not defined. */
1417 #define AF_INET SL_AF_INET
1418 
1419 #define socklen_t SlSocklen_t
1420 #define sockaddr SlSockAddr_t
1421 #define sockaddr_in SlSockAddrIn_t
1422 #define in_addr SlInAddr_t
1423 
1424 #define SOCK_STREAM SL_SOCK_STREAM
1425 #define SOCK_DGRAM SL_SOCK_DGRAM
1426 
1427 #define htonl sl_Htonl
1428 #define ntohl sl_Ntohl
1429 #define htons sl_Htons
1430 #define ntohs sl_Ntohs
1431 
1432 #ifndef EACCES
1433 #define EACCES SL_EACCES
1434 #endif
1435 #ifndef EAFNOSUPPORT
1436 #define EAFNOSUPPORT SL_EAFNOSUPPORT
1437 #endif
1438 #ifndef EAGAIN
1439 #define EAGAIN SL_EAGAIN
1440 #endif
1441 #ifndef EBADF
1442 #define EBADF SL_EBADF
1443 #endif
1444 #ifndef EINVAL
1445 #define EINVAL SL_EINVAL
1446 #endif
1447 #ifndef ENOMEM
1448 #define ENOMEM SL_ENOMEM
1449 #endif
1450 #ifndef EWOULDBLOCK
1451 #define EWOULDBLOCK SL_EWOULDBLOCK
1452 #endif
1453 
1454 #define SOMAXCONN 8
1455 
1456 #ifdef __cplusplus
1457 extern "C" {
1458 #endif
1459 
1460 const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
1461 char *inet_ntoa(struct in_addr in);
1462 int inet_pton(int af, const char *src, void *dst);
1463 
1464 struct mg_mgr;
1465 struct mg_connection;
1466 
1467 typedef void (*mg_init_cb)(struct mg_mgr *mgr);
1468 bool mg_start_task(int priority, int stack_size, mg_init_cb mg_init);
1469 
1470 void mg_run_in_task(void (*cb)(struct mg_mgr *mgr, void *arg), void *cb_arg);
1471 
1472 int sl_fs_init(void);
1473 
1474 void sl_restart_cb(struct mg_mgr *mgr);
1475 
1476 int sl_set_ssl_opts(int sock, struct mg_connection *nc);
1477 
1478 #ifdef __cplusplus
1479 }
1480 #endif
1481 
1482 #endif /* !defined(__SIMPLELINK_H__) */
1483 
1484 /* Compatibility with older versions of SimpleLink */
1485 #if SL_MAJOR_VERSION_NUM < 2
1486 
1487 #define SL_ERROR_BSD_EAGAIN SL_EAGAIN
1488 #define SL_ERROR_BSD_EALREADY SL_EALREADY
1489 #define SL_ERROR_BSD_ENOPROTOOPT SL_ENOPROTOOPT
1490 #define SL_ERROR_BSD_ESECDATEERROR SL_ESECDATEERROR
1491 #define SL_ERROR_BSD_ESECSNOVERIFY SL_ESECSNOVERIFY
1492 #define SL_ERROR_FS_FAILED_TO_ALLOCATE_MEM SL_FS_ERR_FAILED_TO_ALLOCATE_MEM
1493 #define SL_ERROR_FS_FILE_HAS_NOT_BEEN_CLOSE_CORRECTLY \
1494  SL_FS_FILE_HAS_NOT_BEEN_CLOSE_CORRECTLY
1495 #define SL_ERROR_FS_FILE_NAME_EXIST SL_FS_FILE_NAME_EXIST
1496 #define SL_ERROR_FS_FILE_NOT_EXISTS SL_FS_ERR_FILE_NOT_EXISTS
1497 #define SL_ERROR_FS_NO_AVAILABLE_NV_INDEX SL_FS_ERR_NO_AVAILABLE_NV_INDEX
1498 #define SL_ERROR_FS_NOT_ENOUGH_STORAGE_SPACE SL_FS_ERR_NO_AVAILABLE_BLOCKS
1499 #define SL_ERROR_FS_NOT_SUPPORTED SL_FS_ERR_NOT_SUPPORTED
1500 #define SL_ERROR_FS_WRONG_FILE_NAME SL_FS_WRONG_FILE_NAME
1501 #define SL_ERROR_FS_INVALID_HANDLE SL_FS_ERR_INVALID_HANDLE
1502 #define SL_NETCFG_MAC_ADDRESS_GET SL_MAC_ADDRESS_GET
1503 #define SL_SOCKET_FD_ZERO SL_FD_ZERO
1504 #define SL_SOCKET_FD_SET SL_FD_SET
1505 #define SL_SOCKET_FD_ISSET SL_FD_ISSET
1506 #define SL_SO_SECURE_DOMAIN_NAME_VERIFICATION SO_SECURE_DOMAIN_NAME_VERIFICATION
1507 
1508 #define SL_FS_READ FS_MODE_OPEN_READ
1509 #define SL_FS_WRITE FS_MODE_OPEN_WRITE
1510 
1511 #define SL_FI_FILE_SIZE(fi) ((fi).FileLen)
1512 #define SL_FI_FILE_MAX_SIZE(fi) ((fi).AllocatedLen)
1513 
1514 #define SlDeviceVersion_t SlVersionFull
1515 #define sl_DeviceGet sl_DevGet
1516 #define SL_DEVICE_GENERAL SL_DEVICE_GENERAL_CONFIGURATION
1517 #define SL_LEN_TYPE _u8
1518 #define SL_OPT_TYPE _u8
1519 
1520 #else /* SL_MAJOR_VERSION_NUM >= 2 */
1521 
1522 #define FS_MODE_OPEN_CREATE(max_size, flag) \
1523  (SL_FS_CREATE | SL_FS_CREATE_MAX_SIZE(max_size))
1524 #define SL_FI_FILE_SIZE(fi) ((fi).Len)
1525 #define SL_FI_FILE_MAX_SIZE(fi) ((fi).MaxSize)
1526 
1527 #define SL_LEN_TYPE _u16
1528 #define SL_OPT_TYPE _u16
1529 
1530 #endif /* SL_MAJOR_VERSION_NUM < 2 */
1531 
1532 int slfs_open(const unsigned char *fname, uint32_t flags);
1533 
1534 #endif /* MG_NET_IF == MG_NET_IF_SIMPLELINK */
1535 
1536 #endif /* CS_COMMON_PLATFORMS_SIMPLELINK_CS_SIMPLELINK_H_ */
1537 #ifdef MG_MODULE_LINES
1538 #line 1 "common/platforms/platform_wince.h"
1539 #endif
1540 #ifndef CS_COMMON_PLATFORMS_PLATFORM_WINCE_H_
1541 #define CS_COMMON_PLATFORMS_PLATFORM_WINCE_H_
1542 
1543 #if CS_PLATFORM == CS_P_WINCE
1544 
1545 /*
1546  * MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)
1547  * MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)
1548  * MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012)
1549  * MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010)
1550  * MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008)
1551  * MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005)
1552  * MSVC++ 7.1 _MSC_VER == 1310 (Visual Studio 2003)
1553  * MSVC++ 7.0 _MSC_VER == 1300
1554  * MSVC++ 6.0 _MSC_VER == 1200
1555  * MSVC++ 5.0 _MSC_VER == 1100
1556  */
1557 #pragma warning(disable : 4127) /* FD_SET() emits warning, disable it */
1558 #pragma warning(disable : 4204) /* missing c99 support */
1559 
1560 #ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
1561 #define _WINSOCK_DEPRECATED_NO_WARNINGS 1
1562 #endif
1563 
1564 #ifndef _CRT_SECURE_NO_WARNINGS
1565 #define _CRT_SECURE_NO_WARNINGS
1566 #endif
1567 
1568 #include <assert.h>
1569 #include <limits.h>
1570 #include <stddef.h>
1571 #include <stdio.h>
1572 #include <stdlib.h>
1573 #include <time.h>
1574 
1575 #pragma comment(lib, "ws2.lib") /* Linking with WinCE winsock library */
1576 
1577 #include <winsock2.h>
1578 #include <ws2tcpip.h>
1579 #include <windows.h>
1580 
1581 #define strdup _strdup
1582 
1583 #ifndef EINPROGRESS
1584 #define EINPROGRESS WSAEINPROGRESS
1585 #endif
1586 
1587 #ifndef EWOULDBLOCK
1588 #define EWOULDBLOCK WSAEWOULDBLOCK
1589 #endif
1590 
1591 #ifndef EAGAIN
1592 #define EAGAIN EWOULDBLOCK
1593 #endif
1594 
1595 #ifndef __func__
1596 #define STRX(x) #x
1597 #define STR(x) STRX(x)
1598 #define __func__ __FILE__ ":" STR(__LINE__)
1599 #endif
1600 
1601 #define snprintf _snprintf
1602 #define fileno _fileno
1603 #define vsnprintf _vsnprintf
1604 #define sleep(x) Sleep((x) *1000)
1605 #define to64(x) _atoi64(x)
1606 #define rmdir _rmdir
1607 
1608 #if defined(_MSC_VER) && _MSC_VER >= 1400
1609 #define fseeko(x, y, z) _fseeki64((x), (y), (z))
1610 #else
1611 #define fseeko(x, y, z) fseek((x), (y), (z))
1612 #endif
1613 
1614 typedef int socklen_t;
1615 
1616 #if _MSC_VER >= 1700
1617 #include <stdint.h>
1618 #else
1619 typedef signed char int8_t;
1620 typedef unsigned char uint8_t;
1621 typedef int int32_t;
1622 typedef unsigned int uint32_t;
1623 typedef short int16_t;
1624 typedef unsigned short uint16_t;
1625 typedef __int64 int64_t;
1626 typedef unsigned __int64 uint64_t;
1627 #endif
1628 
1629 typedef SOCKET sock_t;
1630 typedef uint32_t in_addr_t;
1631 
1632 #ifndef UINT16_MAX
1633 #define UINT16_MAX 65535
1634 #endif
1635 
1636 #ifndef UINT32_MAX
1637 #define UINT32_MAX 4294967295
1638 #endif
1639 
1640 #ifndef pid_t
1641 #define pid_t HANDLE
1642 #endif
1643 
1644 #define INT64_FMT "I64d"
1645 #define INT64_X_FMT "I64x"
1646 /* TODO(alashkin): check if this is correct */
1647 #define SIZE_T_FMT "u"
1648 
1649 #define DIRSEP '\\'
1650 #define CS_DEFINE_DIRENT
1651 
1652 #ifndef va_copy
1653 #ifdef __va_copy
1654 #define va_copy __va_copy
1655 #else
1656 #define va_copy(x, y) (x) = (y)
1657 #endif
1658 #endif
1659 
1660 #ifndef MG_MAX_HTTP_REQUEST_SIZE
1661 #define MG_MAX_HTTP_REQUEST_SIZE 8192
1662 #endif
1663 
1664 #ifndef MG_MAX_HTTP_SEND_MBUF
1665 #define MG_MAX_HTTP_SEND_MBUF 4096
1666 #endif
1667 
1668 #ifndef MG_MAX_HTTP_HEADERS
1669 #define MG_MAX_HTTP_HEADERS 40
1670 #endif
1671 
1672 #ifndef CS_ENABLE_STDIO
1673 #define CS_ENABLE_STDIO 1
1674 #endif
1675 
1676 #define abort() DebugBreak();
1677 
1678 #ifndef BUFSIZ
1679 #define BUFSIZ 4096
1680 #endif
1681 /*
1682  * Explicitly disabling MG_ENABLE_THREADS for WinCE
1683  * because they are enabled for _WIN32 by default
1684  */
1685 #ifndef MG_ENABLE_THREADS
1686 #define MG_ENABLE_THREADS 0
1687 #endif
1688 
1689 #ifndef MG_ENABLE_FILESYSTEM
1690 #define MG_ENABLE_FILESYSTEM 1
1691 #endif
1692 
1693 #ifndef MG_NET_IF
1694 #define MG_NET_IF MG_NET_IF_SOCKET
1695 #endif
1696 
1697 typedef struct _stati64 {
1698  uint32_t st_mtime;
1699  uint32_t st_size;
1700  uint32_t st_mode;
1701 } cs_stat_t;
1702 
1703 /*
1704  * WinCE 6.0 has a lot of useful definitions in ATL (not windows.h) headers
1705  * use #ifdefs to avoid conflicts
1706  */
1707 
1708 #ifndef ENOENT
1709 #define ENOENT ERROR_PATH_NOT_FOUND
1710 #endif
1711 
1712 #ifndef EACCES
1713 #define EACCES ERROR_ACCESS_DENIED
1714 #endif
1715 
1716 #ifndef ENOMEM
1717 #define ENOMEM ERROR_NOT_ENOUGH_MEMORY
1718 #endif
1719 
1720 #ifndef _UINTPTR_T_DEFINED
1721 typedef unsigned int *uintptr_t;
1722 #endif
1723 
1724 #define _S_IFREG 2
1725 #define _S_IFDIR 4
1726 
1727 #ifndef S_ISDIR
1728 #define S_ISDIR(x) (((x) &_S_IFDIR) != 0)
1729 #endif
1730 
1731 #ifndef S_ISREG
1732 #define S_ISREG(x) (((x) &_S_IFREG) != 0)
1733 #endif
1734 
1735 int open(const char *filename, int oflag, int pmode);
1736 int _wstati64(const wchar_t *path, cs_stat_t *st);
1737 const char *strerror();
1738 
1739 #endif /* CS_PLATFORM == CS_P_WINCE */
1740 #endif /* CS_COMMON_PLATFORMS_PLATFORM_WINCE_H_ */
1741 #ifdef MG_MODULE_LINES
1742 #line 1 "common/platforms/platform_nxp_lpc.h"
1743 #endif
1744 /*
1745  * Copyright (c) 2014-2018 Cesanta Software Limited
1746  * All rights reserved
1747  *
1748  * Licensed under the Apache License, Version 2.0 (the ""License"");
1749  * you may not use this file except in compliance with the License.
1750  * You may obtain a copy of the License at
1751  *
1752  * http://www.apache.org/licenses/LICENSE-2.0
1753  *
1754  * Unless required by applicable law or agreed to in writing, software
1755  * distributed under the License is distributed on an ""AS IS"" BASIS,
1756  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1757  * See the License for the specific language governing permissions and
1758  * limitations under the License.
1759  */
1760 
1761 #ifndef CS_COMMON_PLATFORMS_PLATFORM_NXP_LPC_H_
1762 #define CS_COMMON_PLATFORMS_PLATFORM_NXP_LPC_H_
1763 
1764 #if CS_PLATFORM == CS_P_NXP_LPC
1765 
1766 #include <ctype.h>
1767 #include <stdint.h>
1768 #include <string.h>
1769 
1770 #define SIZE_T_FMT "u"
1771 typedef struct stat cs_stat_t;
1772 #define INT64_FMT "lld"
1773 #define INT64_X_FMT "llx"
1774 #define __cdecl
1775 
1776 #define MG_LWIP 1
1777 
1778 #define MG_NET_IF MG_NET_IF_LWIP_LOW_LEVEL
1779 
1780 /*
1781  * LPCXpress comes with 3 C library implementations: Newlib, NewlibNano and
1782  *Redlib.
1783  * See https://community.nxp.com/message/630860 for more details.
1784  *
1785  * Redlib is the default and lacks certain things, so we provide them.
1786  */
1787 #ifdef __REDLIB_INTERFACE_VERSION__
1788 
1789 /* Let LWIP define timeval for us. */
1790 #define LWIP_TIMEVAL_PRIVATE 1
1791 
1792 #define va_copy(d, s) __builtin_va_copy(d, s)
1793 
1794 #define CS_ENABLE_TO64 1
1795 #define to64(x) cs_to64(x)
1796 
1797 #define CS_ENABLE_STRDUP 1
1798 
1799 #else
1800 
1801 #include <sys/time.h>
1802 #define LWIP_TIMEVAL_PRIVATE 0
1803 #define to64(x) strtoll(x, NULL, 10)
1804 
1805 #endif
1806 
1807 #endif /* CS_PLATFORM == CS_P_NXP_LPC */
1808 #endif /* CS_COMMON_PLATFORMS_PLATFORM_NXP_LPC_H_ */
1809 #ifdef MG_MODULE_LINES
1810 #line 1 "common/platforms/platform_nxp_kinetis.h"
1811 #endif
1812 /*
1813  * Copyright (c) 2014-2018 Cesanta Software Limited
1814  * All rights reserved
1815  *
1816  * Licensed under the Apache License, Version 2.0 (the ""License"");
1817  * you may not use this file except in compliance with the License.
1818  * You may obtain a copy of the License at
1819  *
1820  * http://www.apache.org/licenses/LICENSE-2.0
1821  *
1822  * Unless required by applicable law or agreed to in writing, software
1823  * distributed under the License is distributed on an ""AS IS"" BASIS,
1824  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1825  * See the License for the specific language governing permissions and
1826  * limitations under the License.
1827  */
1828 
1829 #ifndef CS_COMMON_PLATFORMS_PLATFORM_NXP_KINETIS_H_
1830 #define CS_COMMON_PLATFORMS_PLATFORM_NXP_KINETIS_H_
1831 
1832 #if CS_PLATFORM == CS_P_NXP_KINETIS
1833 
1834 #include <ctype.h>
1835 #include <inttypes.h>
1836 #include <string.h>
1837 #include <sys/time.h>
1838 
1839 #define SIZE_T_FMT "u"
1840 typedef struct stat cs_stat_t;
1841 #define to64(x) strtoll(x, NULL, 10)
1842 #define INT64_FMT "lld"
1843 #define INT64_X_FMT "llx"
1844 #define __cdecl
1845 
1846 #define MG_LWIP 1
1847 
1848 #define MG_NET_IF MG_NET_IF_LWIP_LOW_LEVEL
1849 
1850 /* struct timeval is defined in sys/time.h. */
1851 #define LWIP_TIMEVAL_PRIVATE 0
1852 
1853 #endif /* CS_PLATFORM == CS_P_NXP_KINETIS */
1854 #endif /* CS_COMMON_PLATFORMS_PLATFORM_NXP_KINETIS_H_ */
1855 #ifdef MG_MODULE_LINES
1856 #line 1 "common/platforms/platform_pic32.h"
1857 #endif
1858 /*
1859  * Copyright (c) 2014-2018 Cesanta Software Limited
1860  * All rights reserved
1861  *
1862  * Licensed under the Apache License, Version 2.0 (the ""License"");
1863  * you may not use this file except in compliance with the License.
1864  * You may obtain a copy of the License at
1865  *
1866  * http://www.apache.org/licenses/LICENSE-2.0
1867  *
1868  * Unless required by applicable law or agreed to in writing, software
1869  * distributed under the License is distributed on an ""AS IS"" BASIS,
1870  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1871  * See the License for the specific language governing permissions and
1872  * limitations under the License.
1873  */
1874 
1875 #ifndef CS_COMMON_PLATFORMS_PLATFORM_PIC32_H_
1876 #define CS_COMMON_PLATFORMS_PLATFORM_PIC32_H_
1877 
1878 #if CS_PLATFORM == CS_P_PIC32
1879 
1880 #define MG_NET_IF MG_NET_IF_PIC32
1881 
1882 #include <stdint.h>
1883 #include <time.h>
1884 #include <ctype.h>
1885 #include <stdlib.h>
1886 
1887 #include <system_config.h>
1888 #include <system_definitions.h>
1889 
1890 #include <sys/types.h>
1891 
1892 typedef TCP_SOCKET sock_t;
1893 #define to64(x) strtoll(x, NULL, 10)
1894 
1895 #define SIZE_T_FMT "lu"
1896 #define INT64_FMT "lld"
1897 
1898 #ifndef CS_ENABLE_STDIO
1899 #define CS_ENABLE_STDIO 1
1900 #endif
1901 
1902 char *inet_ntoa(struct in_addr in);
1903 
1904 #endif /* CS_PLATFORM == CS_P_PIC32 */
1905 
1906 #endif /* CS_COMMON_PLATFORMS_PLATFORM_PIC32_H_ */
1907 #ifdef MG_MODULE_LINES
1908 #line 1 "common/platforms/platform_stm32.h"
1909 #endif
1910 /*
1911  * Copyright (c) 2014-2018 Cesanta Software Limited
1912  * All rights reserved
1913  *
1914  * Licensed under the Apache License, Version 2.0 (the ""License"");
1915  * you may not use this file except in compliance with the License.
1916  * You may obtain a copy of the License at
1917  *
1918  * http://www.apache.org/licenses/LICENSE-2.0
1919  *
1920  * Unless required by applicable law or agreed to in writing, software
1921  * distributed under the License is distributed on an ""AS IS"" BASIS,
1922  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1923  * See the License for the specific language governing permissions and
1924  * limitations under the License.
1925  */
1926 
1927 #ifndef CS_COMMON_PLATFORMS_PLATFORM_STM32_H_
1928 #define CS_COMMON_PLATFORMS_PLATFORM_STM32_H_
1929 #if CS_PLATFORM == CS_P_STM32
1930 
1931 #include <ctype.h>
1932 #include <errno.h>
1933 #include <fcntl.h>
1934 #include <stdint.h>
1935 #include <stdio.h>
1936 #include <string.h>
1937 #include <sys/stat.h>
1938 #include <sys/time.h>
1939 #include <sys/types.h>
1940 #include <unistd.h>
1941 #include <dirent.h>
1942 
1943 #include <stm32_sdk_hal.h>
1944 
1945 #define to64(x) strtoll(x, NULL, 10)
1946 #define INT64_FMT "lld"
1947 #define SIZE_T_FMT "u"
1948 typedef struct stat cs_stat_t;
1949 #define DIRSEP '/'
1950 
1951 #ifndef CS_ENABLE_STDIO
1952 #define CS_ENABLE_STDIO 1
1953 #endif
1954 
1955 #ifndef MG_ENABLE_FILESYSTEM
1956 #define MG_ENABLE_FILESYSTEM 1
1957 #endif
1958 
1959 #endif /* CS_PLATFORM == CS_P_STM32 */
1960 #endif /* CS_COMMON_PLATFORMS_PLATFORM_STM32_H_ */
1961 #ifdef MG_MODULE_LINES
1962 #line 1 "common/platforms/lwip/mg_lwip.h"
1963 #endif
1964 /*
1965  * Copyright (c) 2014-2018 Cesanta Software Limited
1966  * All rights reserved
1967  *
1968  * Licensed under the Apache License, Version 2.0 (the ""License"");
1969  * you may not use this file except in compliance with the License.
1970  * You may obtain a copy of the License at
1971  *
1972  * http://www.apache.org/licenses/LICENSE-2.0
1973  *
1974  * Unless required by applicable law or agreed to in writing, software
1975  * distributed under the License is distributed on an ""AS IS"" BASIS,
1976  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1977  * See the License for the specific language governing permissions and
1978  * limitations under the License.
1979  */
1980 
1981 #ifndef CS_COMMON_PLATFORMS_LWIP_MG_LWIP_H_
1982 #define CS_COMMON_PLATFORMS_LWIP_MG_LWIP_H_
1983 
1984 #ifndef MG_LWIP
1985 #define MG_LWIP 0
1986 #endif
1987 
1988 #if MG_LWIP
1989 
1990 /*
1991  * When compiling for nRF5x chips with arm-none-eabi-gcc, it has BYTE_ORDER
1992  * already defined, so in order to avoid warnings in lwip, we have to undefine
1993  * it.
1994  *
1995  * TODO: Check if in the future versions of nRF5 SDK that changes.
1996  * Current version of nRF51 SDK: 0.8.0
1997  * nRF5 SDK: 0.9.0
1998  */
1999 #if CS_PLATFORM == CS_P_NRF51 || CS_PLATFORM == CS_P_NRF52
2000 #undef BYTE_ORDER
2001 #endif
2002 
2003 #include <lwip/opt.h>
2004 #include <lwip/err.h>
2005 #include <lwip/ip_addr.h>
2006 #include <lwip/inet.h>
2007 #include <lwip/netdb.h>
2008 #include <lwip/dns.h>
2009 
2010 #ifndef LWIP_PROVIDE_ERRNO
2011 #include <errno.h>
2012 #endif
2013 
2014 #if LWIP_SOCKET
2015 #include <lwip/sockets.h>
2016 #else
2017 /* We really need the definitions from sockets.h. */
2018 #undef LWIP_SOCKET
2019 #define LWIP_SOCKET 1
2020 #include <lwip/sockets.h>
2021 #undef LWIP_SOCKET
2022 #define LWIP_SOCKET 0
2023 #endif
2024 
2025 #define INVALID_SOCKET (-1)
2026 #define SOMAXCONN 10
2027 typedef int sock_t;
2028 
2029 #if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL
2030 struct mg_mgr;
2031 struct mg_connection;
2032 void mg_lwip_set_keepalive_params(struct mg_connection *nc, int idle,
2033  int interval, int count);
2034 #endif
2035 
2036 /* For older version of LWIP */
2037 #ifndef ipX_2_ip
2038 #define ipX_2_ip(x) (x)
2039 #endif
2040 
2041 #endif /* MG_LWIP */
2042 
2043 #endif /* CS_COMMON_PLATFORMS_LWIP_MG_LWIP_H_ */
2044 #ifdef MG_MODULE_LINES
2045 #line 1 "common/cs_md5.h"
2046 #endif
2047 /*
2048  * Copyright (c) 2014-2018 Cesanta Software Limited
2049  * All rights reserved
2050  *
2051  * Licensed under the Apache License, Version 2.0 (the ""License"");
2052  * you may not use this file except in compliance with the License.
2053  * You may obtain a copy of the License at
2054  *
2055  * http://www.apache.org/licenses/LICENSE-2.0
2056  *
2057  * Unless required by applicable law or agreed to in writing, software
2058  * distributed under the License is distributed on an ""AS IS"" BASIS,
2059  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2060  * See the License for the specific language governing permissions and
2061  * limitations under the License.
2062  */
2063 
2064 #ifndef CS_COMMON_MD5_H_
2065 #define CS_COMMON_MD5_H_
2066 
2067 /* Amalgamated: #include "common/platform.h" */
2068 
2069 #ifndef CS_DISABLE_MD5
2070 #define CS_DISABLE_MD5 0
2071 #endif
2072 
2073 #ifdef __cplusplus
2074 extern "C" {
2075 #endif /* __cplusplus */
2076 
2077 typedef struct {
2078  uint32_t buf[4];
2079  uint32_t bits[2];
2080  unsigned char in[64];
2081 } cs_md5_ctx;
2082 
2083 void cs_md5_init(cs_md5_ctx *c);
2084 void cs_md5_update(cs_md5_ctx *c, const unsigned char *data, size_t len);
2085 void cs_md5_final(unsigned char *md, cs_md5_ctx *c);
2086 
2087 #ifdef __cplusplus
2088 }
2089 #endif /* __cplusplus */
2090 
2091 #endif /* CS_COMMON_MD5_H_ */
2092 #ifdef MG_MODULE_LINES
2093 #line 1 "common/cs_sha1.h"
2094 #endif
2095 /*
2096  * Copyright (c) 2014-2018 Cesanta Software Limited
2097  * All rights reserved
2098  *
2099  * Licensed under the Apache License, Version 2.0 (the ""License"");
2100  * you may not use this file except in compliance with the License.
2101  * You may obtain a copy of the License at
2102  *
2103  * http://www.apache.org/licenses/LICENSE-2.0
2104  *
2105  * Unless required by applicable law or agreed to in writing, software
2106  * distributed under the License is distributed on an ""AS IS"" BASIS,
2107  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2108  * See the License for the specific language governing permissions and
2109  * limitations under the License.
2110  */
2111 
2112 #ifndef CS_COMMON_SHA1_H_
2113 #define CS_COMMON_SHA1_H_
2114 
2115 #ifndef CS_DISABLE_SHA1
2116 #define CS_DISABLE_SHA1 0
2117 #endif
2118 
2119 #if !CS_DISABLE_SHA1
2120 
2121 /* Amalgamated: #include "common/platform.h" */
2122 
2123 #ifdef __cplusplus
2124 extern "C" {
2125 #endif /* __cplusplus */
2126 
2127 typedef struct {
2128  uint32_t state[5];
2129  uint32_t count[2];
2130  unsigned char buffer[64];
2131 } cs_sha1_ctx;
2132 
2133 void cs_sha1_init(cs_sha1_ctx *);
2134 void cs_sha1_update(cs_sha1_ctx *, const unsigned char *data, uint32_t len);
2135 void cs_sha1_final(unsigned char digest[20], cs_sha1_ctx *);
2136 void cs_hmac_sha1(const unsigned char *key, size_t key_len,
2137  const unsigned char *text, size_t text_len,
2138  unsigned char out[20]);
2139 #ifdef __cplusplus
2140 }
2141 #endif /* __cplusplus */
2142 
2143 #endif /* CS_DISABLE_SHA1 */
2144 
2145 #endif /* CS_COMMON_SHA1_H_ */
2146 #ifdef MG_MODULE_LINES
2147 #line 1 "common/cs_time.h"
2148 #endif
2149 /*
2150  * Copyright (c) 2014-2018 Cesanta Software Limited
2151  * All rights reserved
2152  *
2153  * Licensed under the Apache License, Version 2.0 (the ""License"");
2154  * you may not use this file except in compliance with the License.
2155  * You may obtain a copy of the License at
2156  *
2157  * http://www.apache.org/licenses/LICENSE-2.0
2158  *
2159  * Unless required by applicable law or agreed to in writing, software
2160  * distributed under the License is distributed on an ""AS IS"" BASIS,
2161  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2162  * See the License for the specific language governing permissions and
2163  * limitations under the License.
2164  */
2165 
2166 #ifndef CS_COMMON_CS_TIME_H_
2167 #define CS_COMMON_CS_TIME_H_
2168 
2169 #include <time.h>
2170 
2171 /* Amalgamated: #include "common/platform.h" */
2172 
2173 #ifdef __cplusplus
2174 extern "C" {
2175 #endif /* __cplusplus */
2176 
2177 /* Sub-second granularity time(). */
2178 double cs_time(void);
2179 
2180 /*
2181  * Similar to (non-standard) timegm, converts broken-down time into the number
2182  * of seconds since Unix Epoch.
2183  */
2184 double cs_timegm(const struct tm *tm);
2185 
2186 #ifdef __cplusplus
2187 }
2188 #endif /* __cplusplus */
2189 
2190 #endif /* CS_COMMON_CS_TIME_H_ */
2191 #ifdef MG_MODULE_LINES
2192 #line 1 "common/mg_str.h"
2193 #endif
2194 /*
2195  * Copyright (c) 2014-2018 Cesanta Software Limited
2196  * All rights reserved
2197  *
2198  * Licensed under the Apache License, Version 2.0 (the ""License"");
2199  * you may not use this file except in compliance with the License.
2200  * You may obtain a copy of the License at
2201  *
2202  * http://www.apache.org/licenses/LICENSE-2.0
2203  *
2204  * Unless required by applicable law or agreed to in writing, software
2205  * distributed under the License is distributed on an ""AS IS"" BASIS,
2206  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2207  * See the License for the specific language governing permissions and
2208  * limitations under the License.
2209  */
2210 
2211 #ifndef CS_COMMON_MG_STR_H_
2212 #define CS_COMMON_MG_STR_H_
2213 
2214 #include <stddef.h>
2215 
2216 #ifdef __cplusplus
2217 extern "C" {
2218 #endif
2219 
2220 /* Describes chunk of memory */
2221 struct mg_str {
2222  const char *p; /* Memory chunk pointer */
2223  size_t len; /* Memory chunk length */
2224 };
2225 
2226 /*
2227  * Helper function for creating mg_str struct from plain C string.
2228  * `NULL` is allowed and becomes `{NULL, 0}`.
2229  */
2230 struct mg_str mg_mk_str(const char *s);
2231 
2232 /*
2233  * Like `mg_mk_str`, but takes string length explicitly.
2234  */
2235 struct mg_str mg_mk_str_n(const char *s, size_t len);
2236 
2237 /* Macro for initializing mg_str. */
2238 #define MG_MK_STR(str_literal) \
2239  { str_literal, sizeof(str_literal) - 1 }
2240 #define MG_NULL_STR \
2241  { NULL, 0 }
2242 
2243 /*
2244  * Cross-platform version of `strcmp()` where where first string is
2245  * specified by `struct mg_str`.
2246  */
2247 int mg_vcmp(const struct mg_str *str2, const char *str1);
2248 
2249 /*
2250  * Cross-platform version of `strncasecmp()` where first string is
2251  * specified by `struct mg_str`.
2252  */
2253 int mg_vcasecmp(const struct mg_str *str2, const char *str1);
2254 
2255 /* Creates a copy of s (heap-allocated). */
2256 struct mg_str mg_strdup(const struct mg_str s);
2257 
2258 /*
2259  * Creates a copy of s (heap-allocated).
2260  * Resulting string is NUL-terminated (but NUL is not included in len).
2261  */
2262 struct mg_str mg_strdup_nul(const struct mg_str s);
2263 
2264 /*
2265  * Locates character in a string.
2266  */
2267 const char *mg_strchr(const struct mg_str s, int c);
2268 
2269 /*
2270  * Compare two `mg_str`s; return value is the same as `strcmp`.
2271  */
2272 int mg_strcmp(const struct mg_str str1, const struct mg_str str2);
2273 
2274 /*
2275  * Like `mg_strcmp`, but compares at most `n` characters.
2276  */
2277 int mg_strncmp(const struct mg_str str1, const struct mg_str str2, size_t n);
2278 
2279 /*
2280  * Finds the first occurrence of a substring `needle` in the `haystack`.
2281  */
2282 const char *mg_strstr(const struct mg_str haystack, const struct mg_str needle);
2283 
2284 /* Strip whitespace at the start and the end of s */
2285 struct mg_str mg_strstrip(struct mg_str s);
2286 
2287 #ifdef __cplusplus
2288 }
2289 #endif
2290 
2291 #endif /* CS_COMMON_MG_STR_H_ */
2292 #ifdef MG_MODULE_LINES
2293 #line 1 "common/mbuf.h"
2294 #endif
2295 /*
2296  * Copyright (c) 2014-2018 Cesanta Software Limited
2297  * All rights reserved
2298  *
2299  * Licensed under the Apache License, Version 2.0 (the ""License"");
2300  * you may not use this file except in compliance with the License.
2301  * You may obtain a copy of the License at
2302  *
2303  * http://www.apache.org/licenses/LICENSE-2.0
2304  *
2305  * Unless required by applicable law or agreed to in writing, software
2306  * distributed under the License is distributed on an ""AS IS"" BASIS,
2307  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2308  * See the License for the specific language governing permissions and
2309  * limitations under the License.
2310  */
2311 
2312 /*
2313  * Mbufs are mutable/growing memory buffers, like C++ strings.
2314  * Mbuf can append data to the end of a buffer or insert data into arbitrary
2315  * position in the middle of a buffer. The buffer grows automatically when
2316  * needed.
2317  */
2318 
2319 #ifndef CS_COMMON_MBUF_H_
2320 #define CS_COMMON_MBUF_H_
2321 
2322 #include <stdlib.h>
2323 /* Amalgamated: #include "common/platform.h" */
2324 
2325 #if defined(__cplusplus)
2326 extern "C" {
2327 #endif
2328 
2329 #ifndef MBUF_SIZE_MULTIPLIER
2330 #define MBUF_SIZE_MULTIPLIER 1.5
2331 #endif
2332 
2333 #ifndef MBUF_SIZE_MAX_HEADROOM
2334 #ifdef BUFSIZ
2335 #define MBUF_SIZE_MAX_HEADROOM BUFSIZ
2336 #else
2337 #define MBUF_SIZE_MAX_HEADROOM 1024
2338 #endif
2339 #endif
2340 
2341 /* Memory buffer descriptor */
2342 struct mbuf {
2343  char *buf; /* Buffer pointer */
2344  size_t len; /* Data length. Data is located between offset 0 and len. */
2345  size_t size; /* Buffer size allocated by realloc(1). Must be >= len */
2346 };
2347 
2348 /*
2349  * Initialises an Mbuf.
2350  * `initial_capacity` specifies the initial capacity of the mbuf.
2351  */
2352 void mbuf_init(struct mbuf *, size_t initial_capacity);
2353 
2354 /* Frees the space allocated for the mbuffer and resets the mbuf structure. */
2355 void mbuf_free(struct mbuf *);
2356 
2357 /*
2358  * Appends data to the Mbuf.
2359  *
2360  * Returns the number of bytes appended or 0 if out of memory.
2361  */
2362 size_t mbuf_append(struct mbuf *, const void *data, size_t data_size);
2363 
2364 /*
2365  * Inserts data at a specified offset in the Mbuf.
2366  *
2367  * Existing data will be shifted forwards and the buffer will
2368  * be grown if necessary.
2369  * Returns the number of bytes inserted.
2370  */
2371 size_t mbuf_insert(struct mbuf *, size_t, const void *, size_t);
2372 
2373 /* Removes `data_size` bytes from the beginning of the buffer. */
2374 void mbuf_remove(struct mbuf *, size_t data_size);
2375 
2376 /*
2377  * Resizes an Mbuf.
2378  *
2379  * If `new_size` is smaller than buffer's `len`, the
2380  * resize is not performed.
2381  */
2382 void mbuf_resize(struct mbuf *, size_t new_size);
2383 
2384 /* Shrinks an Mbuf by resizing its `size` to `len`. */
2385 void mbuf_trim(struct mbuf *);
2386 
2387 #if defined(__cplusplus)
2388 }
2389 #endif /* __cplusplus */
2390 
2391 #endif /* CS_COMMON_MBUF_H_ */
2392 #ifdef MG_MODULE_LINES
2393 #line 1 "common/cs_base64.h"
2394 #endif
2395 /*
2396  * Copyright (c) 2014-2018 Cesanta Software Limited
2397  * All rights reserved
2398  *
2399  * Licensed under the Apache License, Version 2.0 (the ""License"");
2400  * you may not use this file except in compliance with the License.
2401  * You may obtain a copy of the License at
2402  *
2403  * http://www.apache.org/licenses/LICENSE-2.0
2404  *
2405  * Unless required by applicable law or agreed to in writing, software
2406  * distributed under the License is distributed on an ""AS IS"" BASIS,
2407  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2408  * See the License for the specific language governing permissions and
2409  * limitations under the License.
2410  */
2411 
2412 #ifndef CS_COMMON_CS_BASE64_H_
2413 #define CS_COMMON_CS_BASE64_H_
2414 
2415 #ifndef DISABLE_BASE64
2416 #define DISABLE_BASE64 0
2417 #endif
2418 
2419 #if !DISABLE_BASE64
2420 
2421 #include <stdio.h>
2422 
2423 #ifdef __cplusplus
2424 extern "C" {
2425 #endif
2426 
2427 typedef void (*cs_base64_putc_t)(char, void *);
2428 
2430  /* cannot call it putc because it's a macro on some environments */
2432  unsigned char chunk[3];
2434  void *user_data;
2435 };
2436 
2437 void cs_base64_init(struct cs_base64_ctx *ctx, cs_base64_putc_t putc,
2438  void *user_data);
2439 void cs_base64_update(struct cs_base64_ctx *ctx, const char *str, size_t len);
2440 void cs_base64_finish(struct cs_base64_ctx *ctx);
2441 
2442 void cs_base64_encode(const unsigned char *src, int src_len, char *dst);
2443 void cs_fprint_base64(FILE *f, const unsigned char *src, int src_len);
2444 
2445 /*
2446  * Decodes a base64 string `s` length `len` into `dst`.
2447  * `dst` must have enough space to hold the result.
2448  * `*dec_len` will contain the resulting length of the string in `dst`
2449  * while return value will return number of processed bytes in `src`.
2450  * Return value == len indicates successful processing of all the data.
2451  */
2452 int cs_base64_decode(const unsigned char *s, int len, char *dst, int *dec_len);
2453 
2454 #ifdef __cplusplus
2455 }
2456 #endif
2457 
2458 #endif /* DISABLE_BASE64 */
2459 
2460 #endif /* CS_COMMON_CS_BASE64_H_ */
2461 #ifdef MG_MODULE_LINES
2462 #line 1 "common/str_util.h"
2463 #endif
2464 /*
2465  * Copyright (c) 2014-2018 Cesanta Software Limited
2466  * All rights reserved
2467  *
2468  * Licensed under the Apache License, Version 2.0 (the ""License"");
2469  * you may not use this file except in compliance with the License.
2470  * You may obtain a copy of the License at
2471  *
2472  * http://www.apache.org/licenses/LICENSE-2.0
2473  *
2474  * Unless required by applicable law or agreed to in writing, software
2475  * distributed under the License is distributed on an ""AS IS"" BASIS,
2476  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2477  * See the License for the specific language governing permissions and
2478  * limitations under the License.
2479  */
2480 
2481 #ifndef CS_COMMON_STR_UTIL_H_
2482 #define CS_COMMON_STR_UTIL_H_
2483 
2484 #include <stdarg.h>
2485 #include <stdlib.h>
2486 
2487 /* Amalgamated: #include "common/mg_str.h" */
2488 /* Amalgamated: #include "common/platform.h" */
2489 
2490 #ifndef CS_ENABLE_STRDUP
2491 #define CS_ENABLE_STRDUP 0
2492 #endif
2493 
2494 #ifndef CS_ENABLE_TO64
2495 #define CS_ENABLE_TO64 0
2496 #endif
2497 
2498 /*
2499  * Expands to a string representation of its argument: e.g.
2500  * `CS_STRINGIFY_LIT(5) expands to "5"`
2501  */
2502 #if !defined(_MSC_VER) || _MSC_VER >= 1900
2503 #define CS_STRINGIFY_LIT(...) #__VA_ARGS__
2504 #else
2505 #define CS_STRINGIFY_LIT(x) #x
2506 #endif
2507 
2508 /*
2509  * Expands to a string representation of its argument, which is allowed
2510  * to be a macro: e.g.
2511  *
2512  * #define FOO 123
2513  * CS_STRINGIFY_MACRO(FOO)
2514  *
2515  * expands to 123.
2516  */
2517 #define CS_STRINGIFY_MACRO(x) CS_STRINGIFY_LIT(x)
2518 
2519 #ifdef __cplusplus
2520 extern "C" {
2521 #endif
2522 
2523 /*
2524  * Equivalent of standard `strnlen()`.
2525  */
2526 size_t c_strnlen(const char *s, size_t maxlen);
2527 
2528 /*
2529  * Equivalent of standard `snprintf()`.
2530  */
2531 int c_snprintf(char *buf, size_t buf_size, const char *format, ...)
2532  PRINTF_LIKE(3, 4);
2533 
2534 /*
2535  * Equivalent of standard `vsnprintf()`.
2536  */
2537 int c_vsnprintf(char *buf, size_t buf_size, const char *format, va_list ap);
2538 
2539 /*
2540  * Find the first occurrence of find in s, where the search is limited to the
2541  * first slen characters of s.
2542  */
2543 const char *c_strnstr(const char *s, const char *find, size_t slen);
2544 
2545 /*
2546  * Stringify binary data. Output buffer size must be 2 * size_of_input + 1
2547  * because each byte of input takes 2 bytes in string representation
2548  * plus 1 byte for the terminating \0 character.
2549  */
2550 void cs_to_hex(char *to, const unsigned char *p, size_t len);
2551 
2552 /*
2553  * Convert stringified binary data back to binary.
2554  * Does the reverse of `cs_to_hex()`.
2555  */
2556 void cs_from_hex(char *to, const char *p, size_t len);
2557 
2558 #if CS_ENABLE_STRDUP
2559 /*
2560  * Equivalent of standard `strdup()`, defined if only `CS_ENABLE_STRDUP` is 1.
2561  */
2562 char *strdup(const char *src);
2563 #endif
2564 
2565 #if CS_ENABLE_TO64
2566 #include <stdint.h>
2567 /*
2568  * Simple string -> int64 conversion routine.
2569  */
2570 int64_t cs_to64(const char *s);
2571 #endif
2572 
2573 /*
2574  * Cross-platform version of `strncasecmp()`.
2575  */
2576 int mg_ncasecmp(const char *s1, const char *s2, size_t len);
2577 
2578 /*
2579  * Cross-platform version of `strcasecmp()`.
2580  */
2581 int mg_casecmp(const char *s1, const char *s2);
2582 
2583 /*
2584  * Prints message to the buffer. If the buffer is large enough to hold the
2585  * message, it returns buffer. If buffer is to small, it allocates a large
2586  * enough buffer on heap and returns allocated buffer.
2587  * This is a supposed use case:
2588  *
2589  * ```c
2590  * char buf[5], *p = buf;
2591  * mg_avprintf(&p, sizeof(buf), "%s", "hi there");
2592  * use_p_somehow(p);
2593  * if (p != buf) {
2594  * free(p);
2595  * }
2596  * ```
2597  *
2598  * The purpose of this is to avoid malloc-ing if generated strings are small.
2599  */
2600 int mg_asprintf(char **buf, size_t size, const char *fmt, ...)
2601  PRINTF_LIKE(3, 4);
2602 
2603 /* Same as mg_asprintf, but takes varargs list. */
2604 int mg_avprintf(char **buf, size_t size, const char *fmt, va_list ap);
2605 
2606 /*
2607  * A helper function for traversing a comma separated list of values.
2608  * It returns a list pointer shifted to the next value or NULL if the end
2609  * of the list found.
2610  * The value is stored in a val vector. If the value has a form "x=y", then
2611  * eq_val vector is initialised to point to the "y" part, and val vector length
2612  * is adjusted to point only to "x".
2613  * If the list is just a comma separated list of entries, like "aa,bb,cc" then
2614  * `eq_val` will contain zero-length string.
2615  *
2616  * The purpose of this function is to parse comma separated string without
2617  * any copying/memory allocation.
2618  */
2619 const char *mg_next_comma_list_entry(const char *list, struct mg_str *val,
2620  struct mg_str *eq_val);
2621 
2622 /*
2623  * Like `mg_next_comma_list_entry()`, but takes `list` as `struct mg_str`.
2624  */
2625 struct mg_str mg_next_comma_list_entry_n(struct mg_str list, struct mg_str *val,
2626  struct mg_str *eq_val);
2627 
2628 /*
2629  * Matches 0-terminated string (mg_match_prefix) or string with given length
2630  * mg_match_prefix_n against a glob pattern. Glob syntax:
2631  * ```
2632  * - * matches zero or more characters until a slash character /
2633  * - ** matches zero or more characters
2634  * - ? Matches exactly one character which is not a slash /
2635  * - | or , divides alternative patterns
2636  * - any other character matches itself
2637  * ```
2638  * Match is case-insensitive. Return number of bytes matched.
2639  * Examples:
2640  * ```
2641  * mg_match_prefix("a*f", len, "abcdefgh") == 6
2642  * mg_match_prefix("a*f", len, "abcdexgh") == 0
2643  * mg_match_prefix("a*f|de*,xy", len, "defgh") == 5
2644  * mg_match_prefix("?*", len, "abc") == 3
2645  * mg_match_prefix("?*", len, "") == 0
2646  * ```
2647  */
2648 size_t mg_match_prefix(const char *pattern, int pattern_len, const char *str);
2649 
2650 /*
2651  * Like `mg_match_prefix()`, but takes `pattern` and `str` as `struct mg_str`.
2652  */
2653 size_t mg_match_prefix_n(const struct mg_str pattern, const struct mg_str str);
2654 
2655 #ifdef __cplusplus
2656 }
2657 #endif
2658 
2659 #endif /* CS_COMMON_STR_UTIL_H_ */
2660 #ifdef MG_MODULE_LINES
2661 #line 1 "common/queue.h"
2662 #endif
2663 /* clang-format off */
2664 /*-
2665  * Copyright (c) 1991, 1993
2666  * The Regents of the University of California. All rights reserved.
2667  *
2668  * Redistribution and use in source and binary forms, with or without
2669  * modification, are permitted provided that the following conditions
2670  * are met:
2671  * 1. Redistributions of source code must retain the above copyright
2672  * notice, this list of conditions and the following disclaimer.
2673  * 2. Redistributions in binary form must reproduce the above copyright
2674  * notice, this list of conditions and the following disclaimer in the
2675  * documentation and/or other materials provided with the distribution.
2676  * 4. Neither the name of the University nor the names of its contributors
2677  * may be used to endorse or promote products derived from this software
2678  * without specific prior written permission.
2679  *
2680  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2681  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2682  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2683  * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2684  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2685  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2686  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2687  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2688  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2689  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2690  * SUCH DAMAGE.
2691  *
2692  * @(#)queue.h 8.5 (Berkeley) 8/20/94
2693  * $FreeBSD$
2694  */
2695 
2696 #ifndef _SYS_QUEUE_H_
2697 #define _SYS_QUEUE_H_
2698 
2699 /*
2700  * This file defines four types of data structures: singly-linked lists,
2701  * singly-linked tail queues, lists and tail queues.
2702  *
2703  * A singly-linked list is headed by a single forward pointer. The elements
2704  * are singly linked for minimum space and pointer manipulation overhead at
2705  * the expense of O(n) removal for arbitrary elements. New elements can be
2706  * added to the list after an existing element or at the head of the list.
2707  * Elements being removed from the head of the list should use the explicit
2708  * macro for this purpose for optimum efficiency. A singly-linked list may
2709  * only be traversed in the forward direction. Singly-linked lists are ideal
2710  * for applications with large datasets and few or no removals or for
2711  * implementing a LIFO queue.
2712  *
2713  * A singly-linked tail queue is headed by a pair of pointers, one to the
2714  * head of the list and the other to the tail of the list. The elements are
2715  * singly linked for minimum space and pointer manipulation overhead at the
2716  * expense of O(n) removal for arbitrary elements. New elements can be added
2717  * to the list after an existing element, at the head of the list, or at the
2718  * end of the list. Elements being removed from the head of the tail queue
2719  * should use the explicit macro for this purpose for optimum efficiency.
2720  * A singly-linked tail queue may only be traversed in the forward direction.
2721  * Singly-linked tail queues are ideal for applications with large datasets
2722  * and few or no removals or for implementing a FIFO queue.
2723  *
2724  * A list is headed by a single forward pointer (or an array of forward
2725  * pointers for a hash table header). The elements are doubly linked
2726  * so that an arbitrary element can be removed without a need to
2727  * traverse the list. New elements can be added to the list before
2728  * or after an existing element or at the head of the list. A list
2729  * may be traversed in either direction.
2730  *
2731  * A tail queue is headed by a pair of pointers, one to the head of the
2732  * list and the other to the tail of the list. The elements are doubly
2733  * linked so that an arbitrary element can be removed without a need to
2734  * traverse the list. New elements can be added to the list before or
2735  * after an existing element, at the head of the list, or at the end of
2736  * the list. A tail queue may be traversed in either direction.
2737  *
2738  * For details on the use of these macros, see the queue(3) manual page.
2739  *
2740  *
2741  * SLIST LIST STAILQ TAILQ
2742  * _HEAD + + + +
2743  * _CLASS_HEAD + + + +
2744  * _HEAD_INITIALIZER + + + +
2745  * _ENTRY + + + +
2746  * _CLASS_ENTRY + + + +
2747  * _INIT + + + +
2748  * _EMPTY + + + +
2749  * _FIRST + + + +
2750  * _NEXT + + + +
2751  * _PREV - + - +
2752  * _LAST - - + +
2753  * _FOREACH + + + +
2754  * _FOREACH_FROM + + + +
2755  * _FOREACH_SAFE + + + +
2756  * _FOREACH_FROM_SAFE + + + +
2757  * _FOREACH_REVERSE - - - +
2758  * _FOREACH_REVERSE_FROM - - - +
2759  * _FOREACH_REVERSE_SAFE - - - +
2760  * _FOREACH_REVERSE_FROM_SAFE - - - +
2761  * _INSERT_HEAD + + + +
2762  * _INSERT_BEFORE - + - +
2763  * _INSERT_AFTER + + + +
2764  * _INSERT_TAIL - - + +
2765  * _CONCAT - - + +
2766  * _REMOVE_AFTER + - + -
2767  * _REMOVE_HEAD + - + -
2768  * _REMOVE + + + +
2769  * _SWAP + + + +
2770  *
2771  */
2772 #ifdef QUEUE_MACRO_DEBUG
2773 /* Store the last 2 places the queue element or head was altered */
2774 struct qm_trace {
2775  unsigned long lastline;
2776  unsigned long prevline;
2777  const char *lastfile;
2778  const char *prevfile;
2779 };
2780 
2781 #define TRACEBUF struct qm_trace trace;
2782 #define TRACEBUF_INITIALIZER { __LINE__, 0, __FILE__, NULL } ,
2783 #define TRASHIT(x) do {(x) = (void *)-1;} while (0)
2784 #define QMD_SAVELINK(name, link) void **name = (void *)&(link)
2785 
2786 #define QMD_TRACE_HEAD(head) do { \
2787  (head)->trace.prevline = (head)->trace.lastline; \
2788  (head)->trace.prevfile = (head)->trace.lastfile; \
2789  (head)->trace.lastline = __LINE__; \
2790  (head)->trace.lastfile = __FILE__; \
2791 } while (0)
2792 
2793 #define QMD_TRACE_ELEM(elem) do { \
2794  (elem)->trace.prevline = (elem)->trace.lastline; \
2795  (elem)->trace.prevfile = (elem)->trace.lastfile; \
2796  (elem)->trace.lastline = __LINE__; \
2797  (elem)->trace.lastfile = __FILE__; \
2798 } while (0)
2799 
2800 #else
2801 #define QMD_TRACE_ELEM(elem)
2802 #define QMD_TRACE_HEAD(head)
2803 #define QMD_SAVELINK(name, link)
2804 #define TRACEBUF
2805 #define TRACEBUF_INITIALIZER
2806 #define TRASHIT(x)
2807 #endif /* QUEUE_MACRO_DEBUG */
2808 
2809 #ifdef __cplusplus
2810 /*
2811  * In C++ there can be structure lists and class lists:
2812  */
2813 #define QUEUE_TYPEOF(type) type
2814 #else
2815 #define QUEUE_TYPEOF(type) struct type
2816 #endif
2817 
2818 /*
2819  * Singly-linked List declarations.
2820  */
2821 #define SLIST_HEAD(name, type) \
2822 struct name { \
2823  struct type *slh_first; /* first element */ \
2824 }
2825 
2826 #define SLIST_CLASS_HEAD(name, type) \
2827 struct name { \
2828  class type *slh_first; /* first element */ \
2829 }
2830 
2831 #define SLIST_HEAD_INITIALIZER(head) \
2832  { NULL }
2833 
2834 #define SLIST_ENTRY(type) \
2835 struct { \
2836  struct type *sle_next; /* next element */ \
2837 }
2838 
2839 #define SLIST_CLASS_ENTRY(type) \
2840 struct { \
2841  class type *sle_next; /* next element */ \
2842 }
2843 
2844 /*
2845  * Singly-linked List functions.
2846  */
2847 #define SLIST_EMPTY(head) ((head)->slh_first == NULL)
2848 
2849 #define SLIST_FIRST(head) ((head)->slh_first)
2850 
2851 #define SLIST_FOREACH(var, head, field) \
2852  for ((var) = SLIST_FIRST((head)); \
2853  (var); \
2854  (var) = SLIST_NEXT((var), field))
2855 
2856 #define SLIST_FOREACH_FROM(var, head, field) \
2857  for ((var) = ((var) ? (var) : SLIST_FIRST((head))); \
2858  (var); \
2859  (var) = SLIST_NEXT((var), field))
2860 
2861 #define SLIST_FOREACH_SAFE(var, head, field, tvar) \
2862  for ((var) = SLIST_FIRST((head)); \
2863  (var) && ((tvar) = SLIST_NEXT((var), field), 1); \
2864  (var) = (tvar))
2865 
2866 #define SLIST_FOREACH_FROM_SAFE(var, head, field, tvar) \
2867  for ((var) = ((var) ? (var) : SLIST_FIRST((head))); \
2868  (var) && ((tvar) = SLIST_NEXT((var), field), 1); \
2869  (var) = (tvar))
2870 
2871 #define SLIST_FOREACH_PREVPTR(var, varp, head, field) \
2872  for ((varp) = &SLIST_FIRST((head)); \
2873  ((var) = *(varp)) != NULL; \
2874  (varp) = &SLIST_NEXT((var), field))
2875 
2876 #define SLIST_INIT(head) do { \
2877  SLIST_FIRST((head)) = NULL; \
2878 } while (0)
2879 
2880 #define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
2881  SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
2882  SLIST_NEXT((slistelm), field) = (elm); \
2883 } while (0)
2884 
2885 #define SLIST_INSERT_HEAD(head, elm, field) do { \
2886  SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
2887  SLIST_FIRST((head)) = (elm); \
2888 } while (0)
2889 
2890 #define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
2891 
2892 #define SLIST_REMOVE(head, elm, type, field) do { \
2893  QMD_SAVELINK(oldnext, (elm)->field.sle_next); \
2894  if (SLIST_FIRST((head)) == (elm)) { \
2895  SLIST_REMOVE_HEAD((head), field); \
2896  } \
2897  else { \
2898  QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head); \
2899  while (SLIST_NEXT(curelm, field) != (elm)) \
2900  curelm = SLIST_NEXT(curelm, field); \
2901  SLIST_REMOVE_AFTER(curelm, field); \
2902  } \
2903  TRASHIT(*oldnext); \
2904 } while (0)
2905 
2906 #define SLIST_REMOVE_AFTER(elm, field) do { \
2907  SLIST_NEXT(elm, field) = \
2908  SLIST_NEXT(SLIST_NEXT(elm, field), field); \
2909 } while (0)
2910 
2911 #define SLIST_REMOVE_HEAD(head, field) do { \
2912  SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
2913 } while (0)
2914 
2915 #define SLIST_SWAP(head1, head2, type) do { \
2916  QUEUE_TYPEOF(type) *swap_first = SLIST_FIRST(head1); \
2917  SLIST_FIRST(head1) = SLIST_FIRST(head2); \
2918  SLIST_FIRST(head2) = swap_first; \
2919 } while (0)
2920 
2921 /*
2922  * Singly-linked Tail queue declarations.
2923  */
2924 #define STAILQ_HEAD(name, type) \
2925 struct name { \
2926  struct type *stqh_first;/* first element */ \
2927  struct type **stqh_last;/* addr of last next element */ \
2928 }
2929 
2930 #define STAILQ_CLASS_HEAD(name, type) \
2931 struct name { \
2932  class type *stqh_first; /* first element */ \
2933  class type **stqh_last; /* addr of last next element */ \
2934 }
2935 
2936 #define STAILQ_HEAD_INITIALIZER(head) \
2937  { NULL, &(head).stqh_first }
2938 
2939 #define STAILQ_ENTRY(type) \
2940 struct { \
2941  struct type *stqe_next; /* next element */ \
2942 }
2943 
2944 #define STAILQ_CLASS_ENTRY(type) \
2945 struct { \
2946  class type *stqe_next; /* next element */ \
2947 }
2948 
2949 /*
2950  * Singly-linked Tail queue functions.
2951  */
2952 #define STAILQ_CONCAT(head1, head2) do { \
2953  if (!STAILQ_EMPTY((head2))) { \
2954  *(head1)->stqh_last = (head2)->stqh_first; \
2955  (head1)->stqh_last = (head2)->stqh_last; \
2956  STAILQ_INIT((head2)); \
2957  } \
2958 } while (0)
2959 
2960 #define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
2961 
2962 #define STAILQ_FIRST(head) ((head)->stqh_first)
2963 
2964 #define STAILQ_FOREACH(var, head, field) \
2965  for((var) = STAILQ_FIRST((head)); \
2966  (var); \
2967  (var) = STAILQ_NEXT((var), field))
2968 
2969 #define STAILQ_FOREACH_FROM(var, head, field) \
2970  for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); \
2971  (var); \
2972  (var) = STAILQ_NEXT((var), field))
2973 
2974 #define STAILQ_FOREACH_SAFE(var, head, field, tvar) \
2975  for ((var) = STAILQ_FIRST((head)); \
2976  (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \
2977  (var) = (tvar))
2978 
2979 #define STAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \
2980  for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); \
2981  (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \
2982  (var) = (tvar))
2983 
2984 #define STAILQ_INIT(head) do { \
2985  STAILQ_FIRST((head)) = NULL; \
2986  (head)->stqh_last = &STAILQ_FIRST((head)); \
2987 } while (0)
2988 
2989 #define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
2990  if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
2991  (head)->stqh_last = &STAILQ_NEXT((elm), field); \
2992  STAILQ_NEXT((tqelm), field) = (elm); \
2993 } while (0)
2994 
2995 #define STAILQ_INSERT_HEAD(head, elm, field) do { \
2996  if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
2997  (head)->stqh_last = &STAILQ_NEXT((elm), field); \
2998  STAILQ_FIRST((head)) = (elm); \
2999 } while (0)
3000 
3001 #define STAILQ_INSERT_TAIL(head, elm, field) do { \
3002  STAILQ_NEXT((elm), field) = NULL; \
3003  *(head)->stqh_last = (elm); \
3004  (head)->stqh_last = &STAILQ_NEXT((elm), field); \
3005 } while (0)
3006 
3007 #define STAILQ_LAST(head, type, field) \
3008  (STAILQ_EMPTY((head)) ? NULL : \
3009  __containerof((head)->stqh_last, \
3010  QUEUE_TYPEOF(type), field.stqe_next))
3011 
3012 #define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
3013 
3014 #define STAILQ_REMOVE(head, elm, type, field) do { \
3015  QMD_SAVELINK(oldnext, (elm)->field.stqe_next); \
3016  if (STAILQ_FIRST((head)) == (elm)) { \
3017  STAILQ_REMOVE_HEAD((head), field); \
3018  } \
3019  else { \
3020  QUEUE_TYPEOF(type) *curelm = STAILQ_FIRST(head); \
3021  while (STAILQ_NEXT(curelm, field) != (elm)) \
3022  curelm = STAILQ_NEXT(curelm, field); \
3023  STAILQ_REMOVE_AFTER(head, curelm, field); \
3024  } \
3025  TRASHIT(*oldnext); \
3026 } while (0)
3027 
3028 #define STAILQ_REMOVE_AFTER(head, elm, field) do { \
3029  if ((STAILQ_NEXT(elm, field) = \
3030  STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \
3031  (head)->stqh_last = &STAILQ_NEXT((elm), field); \
3032 } while (0)
3033 
3034 #define STAILQ_REMOVE_HEAD(head, field) do { \
3035  if ((STAILQ_FIRST((head)) = \
3036  STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
3037  (head)->stqh_last = &STAILQ_FIRST((head)); \
3038 } while (0)
3039 
3040 #define STAILQ_SWAP(head1, head2, type) do { \
3041  QUEUE_TYPEOF(type) *swap_first = STAILQ_FIRST(head1); \
3042  QUEUE_TYPEOF(type) **swap_last = (head1)->stqh_last; \
3043  STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \
3044  (head1)->stqh_last = (head2)->stqh_last; \
3045  STAILQ_FIRST(head2) = swap_first; \
3046  (head2)->stqh_last = swap_last; \
3047  if (STAILQ_EMPTY(head1)) \
3048  (head1)->stqh_last = &STAILQ_FIRST(head1); \
3049  if (STAILQ_EMPTY(head2)) \
3050  (head2)->stqh_last = &STAILQ_FIRST(head2); \
3051 } while (0)
3052 
3053 
3054 /*
3055  * List declarations.
3056  */
3057 #define LIST_HEAD(name, type) \
3058 struct name { \
3059  struct type *lh_first; /* first element */ \
3060 }
3061 
3062 #define LIST_CLASS_HEAD(name, type) \
3063 struct name { \
3064  class type *lh_first; /* first element */ \
3065 }
3066 
3067 #define LIST_HEAD_INITIALIZER(head) \
3068  { NULL }
3069 
3070 #define LIST_ENTRY(type) \
3071 struct { \
3072  struct type *le_next; /* next element */ \
3073  struct type **le_prev; /* address of previous next element */ \
3074 }
3075 
3076 #define LIST_CLASS_ENTRY(type) \
3077 struct { \
3078  class type *le_next; /* next element */ \
3079  class type **le_prev; /* address of previous next element */ \
3080 }
3081 
3082 /*
3083  * List functions.
3084  */
3085 
3086 #if (defined(_KERNEL) && defined(INVARIANTS))
3087 #define QMD_LIST_CHECK_HEAD(head, field) do { \
3088  if (LIST_FIRST((head)) != NULL && \
3089  LIST_FIRST((head))->field.le_prev != \
3090  &LIST_FIRST((head))) \
3091  panic("Bad list head %p first->prev != head", (head)); \
3092 } while (0)
3093 
3094 #define QMD_LIST_CHECK_NEXT(elm, field) do { \
3095  if (LIST_NEXT((elm), field) != NULL && \
3096  LIST_NEXT((elm), field)->field.le_prev != \
3097  &((elm)->field.le_next)) \
3098  panic("Bad link elm %p next->prev != elm", (elm)); \
3099 } while (0)
3100 
3101 #define QMD_LIST_CHECK_PREV(elm, field) do { \
3102  if (*(elm)->field.le_prev != (elm)) \
3103  panic("Bad link elm %p prev->next != elm", (elm)); \
3104 } while (0)
3105 #else
3106 #define QMD_LIST_CHECK_HEAD(head, field)
3107 #define QMD_LIST_CHECK_NEXT(elm, field)
3108 #define QMD_LIST_CHECK_PREV(elm, field)
3109 #endif /* (_KERNEL && INVARIANTS) */
3110 
3111 #define LIST_EMPTY(head) ((head)->lh_first == NULL)
3112 
3113 #define LIST_FIRST(head) ((head)->lh_first)
3114 
3115 #define LIST_FOREACH(var, head, field) \
3116  for ((var) = LIST_FIRST((head)); \
3117  (var); \
3118  (var) = LIST_NEXT((var), field))
3119 
3120 #define LIST_FOREACH_FROM(var, head, field) \
3121  for ((var) = ((var) ? (var) : LIST_FIRST((head))); \
3122  (var); \
3123  (var) = LIST_NEXT((var), field))
3124 
3125 #define LIST_FOREACH_SAFE(var, head, field, tvar) \
3126  for ((var) = LIST_FIRST((head)); \
3127  (var) && ((tvar) = LIST_NEXT((var), field), 1); \
3128  (var) = (tvar))
3129 
3130 #define LIST_FOREACH_FROM_SAFE(var, head, field, tvar) \
3131  for ((var) = ((var) ? (var) : LIST_FIRST((head))); \
3132  (var) && ((tvar) = LIST_NEXT((var), field), 1); \
3133  (var) = (tvar))
3134 
3135 #define LIST_INIT(head) do { \
3136  LIST_FIRST((head)) = NULL; \
3137 } while (0)
3138 
3139 #define LIST_INSERT_AFTER(listelm, elm, field) do { \
3140  QMD_LIST_CHECK_NEXT(listelm, field); \
3141  if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
3142  LIST_NEXT((listelm), field)->field.le_prev = \
3143  &LIST_NEXT((elm), field); \
3144  LIST_NEXT((listelm), field) = (elm); \
3145  (elm)->field.le_prev = &LIST_NEXT((listelm), field); \
3146 } while (0)
3147 
3148 #define LIST_INSERT_BEFORE(listelm, elm, field) do { \
3149  QMD_LIST_CHECK_PREV(listelm, field); \
3150  (elm)->field.le_prev = (listelm)->field.le_prev; \
3151  LIST_NEXT((elm), field) = (listelm); \
3152  *(listelm)->field.le_prev = (elm); \
3153  (listelm)->field.le_prev = &LIST_NEXT((elm), field); \
3154 } while (0)
3155 
3156 #define LIST_INSERT_HEAD(head, elm, field) do { \
3157  QMD_LIST_CHECK_HEAD((head), field); \
3158  if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
3159  LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
3160  LIST_FIRST((head)) = (elm); \
3161  (elm)->field.le_prev = &LIST_FIRST((head)); \
3162 } while (0)
3163 
3164 #define LIST_NEXT(elm, field) ((elm)->field.le_next)
3165 
3166 #define LIST_PREV(elm, head, type, field) \
3167  ((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL : \
3168  __containerof((elm)->field.le_prev, \
3169  QUEUE_TYPEOF(type), field.le_next))
3170 
3171 #define LIST_REMOVE(elm, field) do { \
3172  QMD_SAVELINK(oldnext, (elm)->field.le_next); \
3173  QMD_SAVELINK(oldprev, (elm)->field.le_prev); \
3174  QMD_LIST_CHECK_NEXT(elm, field); \
3175  QMD_LIST_CHECK_PREV(elm, field); \
3176  if (LIST_NEXT((elm), field) != NULL) \
3177  LIST_NEXT((elm), field)->field.le_prev = \
3178  (elm)->field.le_prev; \
3179  *(elm)->field.le_prev = LIST_NEXT((elm), field); \
3180  TRASHIT(*oldnext); \
3181  TRASHIT(*oldprev); \
3182 } while (0)
3183 
3184 #define LIST_SWAP(head1, head2, type, field) do { \
3185  QUEUE_TYPEOF(type) *swap_tmp = LIST_FIRST(head1); \
3186  LIST_FIRST((head1)) = LIST_FIRST((head2)); \
3187  LIST_FIRST((head2)) = swap_tmp; \
3188  if ((swap_tmp = LIST_FIRST((head1))) != NULL) \
3189  swap_tmp->field.le_prev = &LIST_FIRST((head1)); \
3190  if ((swap_tmp = LIST_FIRST((head2))) != NULL) \
3191  swap_tmp->field.le_prev = &LIST_FIRST((head2)); \
3192 } while (0)
3193 
3194 /*
3195  * Tail queue declarations.
3196  */
3197 #define TAILQ_HEAD(name, type) \
3198 struct name { \
3199  struct type *tqh_first; /* first element */ \
3200  struct type **tqh_last; /* addr of last next element */ \
3201  TRACEBUF \
3202 }
3203 
3204 #define TAILQ_CLASS_HEAD(name, type) \
3205 struct name { \
3206  class type *tqh_first; /* first element */ \
3207  class type **tqh_last; /* addr of last next element */ \
3208  TRACEBUF \
3209 }
3210 
3211 #define TAILQ_HEAD_INITIALIZER(head) \
3212  { NULL, &(head).tqh_first, TRACEBUF_INITIALIZER }
3213 
3214 #define TAILQ_ENTRY(type) \
3215 struct { \
3216  struct type *tqe_next; /* next element */ \
3217  struct type **tqe_prev; /* address of previous next element */ \
3218  TRACEBUF \
3219 }
3220 
3221 #define TAILQ_CLASS_ENTRY(type) \
3222 struct { \
3223  class type *tqe_next; /* next element */ \
3224  class type **tqe_prev; /* address of previous next element */ \
3225  TRACEBUF \
3226 }
3227 
3228 /*
3229  * Tail queue functions.
3230  */
3231 #if (defined(_KERNEL) && defined(INVARIANTS))
3232 #define QMD_TAILQ_CHECK_HEAD(head, field) do { \
3233  if (!TAILQ_EMPTY(head) && \
3234  TAILQ_FIRST((head))->field.tqe_prev != \
3235  &TAILQ_FIRST((head))) \
3236  panic("Bad tailq head %p first->prev != head", (head)); \
3237 } while (0)
3238 
3239 #define QMD_TAILQ_CHECK_TAIL(head, field) do { \
3240  if (*(head)->tqh_last != NULL) \
3241  panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head)); \
3242 } while (0)
3243 
3244 #define QMD_TAILQ_CHECK_NEXT(elm, field) do { \
3245  if (TAILQ_NEXT((elm), field) != NULL && \
3246  TAILQ_NEXT((elm), field)->field.tqe_prev != \
3247  &((elm)->field.tqe_next)) \
3248  panic("Bad link elm %p next->prev != elm", (elm)); \
3249 } while (0)
3250 
3251 #define QMD_TAILQ_CHECK_PREV(elm, field) do { \
3252  if (*(elm)->field.tqe_prev != (elm)) \
3253  panic("Bad link elm %p prev->next != elm", (elm)); \
3254 } while (0)
3255 #else
3256 #define QMD_TAILQ_CHECK_HEAD(head, field)
3257 #define QMD_TAILQ_CHECK_TAIL(head, headname)
3258 #define QMD_TAILQ_CHECK_NEXT(elm, field)
3259 #define QMD_TAILQ_CHECK_PREV(elm, field)
3260 #endif /* (_KERNEL && INVARIANTS) */
3261 
3262 #define TAILQ_CONCAT(head1, head2, field) do { \
3263  if (!TAILQ_EMPTY(head2)) { \
3264  *(head1)->tqh_last = (head2)->tqh_first; \
3265  (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
3266  (head1)->tqh_last = (head2)->tqh_last; \
3267  TAILQ_INIT((head2)); \
3268  QMD_TRACE_HEAD(head1); \
3269  QMD_TRACE_HEAD(head2); \
3270  } \
3271 } while (0)
3272 
3273 #define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
3274 
3275 #define TAILQ_FIRST(head) ((head)->tqh_first)
3276 
3277 #define TAILQ_FOREACH(var, head, field) \
3278  for ((var) = TAILQ_FIRST((head)); \
3279  (var); \
3280  (var) = TAILQ_NEXT((var), field))
3281 
3282 #define TAILQ_FOREACH_FROM(var, head, field) \
3283  for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \
3284  (var); \
3285  (var) = TAILQ_NEXT((var), field))
3286 
3287 #define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
3288  for ((var) = TAILQ_FIRST((head)); \
3289  (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
3290  (var) = (tvar))
3291 
3292 #define TAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \
3293  for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \
3294  (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
3295  (var) = (tvar))
3296 
3297 #define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
3298  for ((var) = TAILQ_LAST((head), headname); \
3299  (var); \
3300  (var) = TAILQ_PREV((var), headname, field))
3301 
3302 #define TAILQ_FOREACH_REVERSE_FROM(var, head, headname, field) \
3303  for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \
3304  (var); \
3305  (var) = TAILQ_PREV((var), headname, field))
3306 
3307 #define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
3308  for ((var) = TAILQ_LAST((head), headname); \
3309  (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \
3310  (var) = (tvar))
3311 
3312 #define TAILQ_FOREACH_REVERSE_FROM_SAFE(var, head, headname, field, tvar) \
3313  for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \
3314  (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \
3315  (var) = (tvar))
3316 
3317 #define TAILQ_INIT(head) do { \
3318  TAILQ_FIRST((head)) = NULL; \
3319  (head)->tqh_last = &TAILQ_FIRST((head)); \
3320  QMD_TRACE_HEAD(head); \
3321 } while (0)
3322 
3323 #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
3324  QMD_TAILQ_CHECK_NEXT(listelm, field); \
3325  if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
3326  TAILQ_NEXT((elm), field)->field.tqe_prev = \
3327  &TAILQ_NEXT((elm), field); \
3328  else { \
3329  (head)->tqh_last = &TAILQ_NEXT((elm), field); \
3330  QMD_TRACE_HEAD(head); \
3331  } \
3332  TAILQ_NEXT((listelm), field) = (elm); \
3333  (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \
3334  QMD_TRACE_ELEM(&(elm)->field); \
3335  QMD_TRACE_ELEM(&(listelm)->field); \
3336 } while (0)
3337 
3338 #define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
3339  QMD_TAILQ_CHECK_PREV(listelm, field); \
3340  (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
3341  TAILQ_NEXT((elm), field) = (listelm); \
3342  *(listelm)->field.tqe_prev = (elm); \
3343  (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
3344  QMD_TRACE_ELEM(&(elm)->field); \
3345  QMD_TRACE_ELEM(&(listelm)->field); \
3346 } while (0)
3347 
3348 #define TAILQ_INSERT_HEAD(head, elm, field) do { \
3349  QMD_TAILQ_CHECK_HEAD(head, field); \
3350  if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \
3351  TAILQ_FIRST((head))->field.tqe_prev = \
3352  &TAILQ_NEXT((elm), field); \
3353  else \
3354  (head)->tqh_last = &TAILQ_NEXT((elm), field); \
3355  TAILQ_FIRST((head)) = (elm); \
3356  (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
3357  QMD_TRACE_HEAD(head); \
3358  QMD_TRACE_ELEM(&(elm)->field); \
3359 } while (0)
3360 
3361 #define TAILQ_INSERT_TAIL(head, elm, field) do { \
3362  QMD_TAILQ_CHECK_TAIL(head, field); \
3363  TAILQ_NEXT((elm), field) = NULL; \
3364  (elm)->field.tqe_prev = (head)->tqh_last; \
3365  *(head)->tqh_last = (elm); \
3366  (head)->tqh_last = &TAILQ_NEXT((elm), field); \
3367  QMD_TRACE_HEAD(head); \
3368  QMD_TRACE_ELEM(&(elm)->field); \
3369 } while (0)
3370 
3371 #define TAILQ_LAST(head, headname) \
3372  (*(((struct headname *)((head)->tqh_last))->tqh_last))
3373 
3374 #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
3375 
3376 #define TAILQ_PREV(elm, headname, field) \
3377  (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
3378 
3379 #define TAILQ_REMOVE(head, elm, field) do { \
3380  QMD_SAVELINK(oldnext, (elm)->field.tqe_next); \
3381  QMD_SAVELINK(oldprev, (elm)->field.tqe_prev); \
3382  QMD_TAILQ_CHECK_NEXT(elm, field); \
3383  QMD_TAILQ_CHECK_PREV(elm, field); \
3384  if ((TAILQ_NEXT((elm), field)) != NULL) \
3385  TAILQ_NEXT((elm), field)->field.tqe_prev = \
3386  (elm)->field.tqe_prev; \
3387  else { \
3388  (head)->tqh_last = (elm)->field.tqe_prev; \
3389  QMD_TRACE_HEAD(head); \
3390  } \
3391  *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \
3392  TRASHIT(*oldnext); \
3393  TRASHIT(*oldprev); \
3394  QMD_TRACE_ELEM(&(elm)->field); \
3395 } while (0)
3396 
3397 #define TAILQ_SWAP(head1, head2, type, field) do { \
3398  QUEUE_TYPEOF(type) *swap_first = (head1)->tqh_first; \
3399  QUEUE_TYPEOF(type) **swap_last = (head1)->tqh_last; \
3400  (head1)->tqh_first = (head2)->tqh_first; \
3401  (head1)->tqh_last = (head2)->tqh_last; \
3402  (head2)->tqh_first = swap_first; \
3403  (head2)->tqh_last = swap_last; \
3404  if ((swap_first = (head1)->tqh_first) != NULL) \
3405  swap_first->field.tqe_prev = &(head1)->tqh_first; \
3406  else \
3407  (head1)->tqh_last = &(head1)->tqh_first; \
3408  if ((swap_first = (head2)->tqh_first) != NULL) \
3409  swap_first->field.tqe_prev = &(head2)->tqh_first; \
3410  else \
3411  (head2)->tqh_last = &(head2)->tqh_first; \
3412 } while (0)
3413 
3414 #endif /* !_SYS_QUEUE_H_ */
3415 #ifdef MG_MODULE_LINES
3416 #line 1 "mongoose/src/mg_features.h"
3417 #endif
3418 /*
3419  * Copyright (c) 2014-2016 Cesanta Software Limited
3420  * All rights reserved
3421  */
3422 
3423 #ifndef CS_MONGOOSE_SRC_FEATURES_H_
3424 #define CS_MONGOOSE_SRC_FEATURES_H_
3425 
3426 #ifndef MG_DISABLE_HTTP_DIGEST_AUTH
3427 #define MG_DISABLE_HTTP_DIGEST_AUTH 0
3428 #endif
3429 
3430 #ifndef MG_DISABLE_HTTP_KEEP_ALIVE
3431 #define MG_DISABLE_HTTP_KEEP_ALIVE 0
3432 #endif
3433 
3434 #ifndef MG_DISABLE_PFS
3435 #define MG_DISABLE_PFS 0
3436 #endif
3437 
3438 #ifndef MG_DISABLE_WS_RANDOM_MASK
3439 #define MG_DISABLE_WS_RANDOM_MASK 0
3440 #endif
3441 
3442 #ifndef MG_ENABLE_ASYNC_RESOLVER
3443 #define MG_ENABLE_ASYNC_RESOLVER 1
3444 #endif
3445 
3446 #ifndef MG_ENABLE_BROADCAST
3447 #define MG_ENABLE_BROADCAST 0
3448 #endif
3449 
3450 #ifndef MG_ENABLE_COAP
3451 #define MG_ENABLE_COAP 0
3452 #endif
3453 
3454 #ifndef MG_ENABLE_DEBUG
3455 #define MG_ENABLE_DEBUG 0
3456 #endif
3457 
3458 #ifndef MG_ENABLE_DIRECTORY_LISTING
3459 #define MG_ENABLE_DIRECTORY_LISTING 0
3460 #endif
3461 
3462 #ifndef MG_ENABLE_DNS
3463 #define MG_ENABLE_DNS 1
3464 #endif
3465 
3466 #ifndef MG_ENABLE_DNS_SERVER
3467 #define MG_ENABLE_DNS_SERVER 0
3468 #endif
3469 
3470 #ifndef MG_ENABLE_FAKE_DAVLOCK
3471 #define MG_ENABLE_FAKE_DAVLOCK 0
3472 #endif
3473 
3474 #ifndef MG_ENABLE_FILESYSTEM
3475 #define MG_ENABLE_FILESYSTEM 0
3476 #endif
3477 
3478 #ifndef MG_ENABLE_GETADDRINFO
3479 #define MG_ENABLE_GETADDRINFO 0
3480 #endif
3481 
3482 #ifndef MG_ENABLE_HEXDUMP
3483 #define MG_ENABLE_HEXDUMP CS_ENABLE_STDIO
3484 #endif
3485 
3486 #ifndef MG_ENABLE_HTTP
3487 #define MG_ENABLE_HTTP 1
3488 #endif
3489 
3490 #ifndef MG_ENABLE_HTTP_CGI
3491 #define MG_ENABLE_HTTP_CGI 0
3492 #endif
3493 
3494 #ifndef MG_ENABLE_HTTP_SSI
3495 #define MG_ENABLE_HTTP_SSI MG_ENABLE_FILESYSTEM
3496 #endif
3497 
3498 #ifndef MG_ENABLE_HTTP_SSI_EXEC
3499 #define MG_ENABLE_HTTP_SSI_EXEC 0
3500 #endif
3501 
3502 #ifndef MG_ENABLE_HTTP_STREAMING_MULTIPART
3503 #define MG_ENABLE_HTTP_STREAMING_MULTIPART 0
3504 #endif
3505 
3506 #ifndef MG_ENABLE_HTTP_WEBDAV
3507 #define MG_ENABLE_HTTP_WEBDAV 0
3508 #endif
3509 
3510 #ifndef MG_ENABLE_HTTP_WEBSOCKET
3511 #define MG_ENABLE_HTTP_WEBSOCKET MG_ENABLE_HTTP
3512 #endif
3513 
3514 #ifndef MG_ENABLE_IPV6
3515 #define MG_ENABLE_IPV6 0
3516 #endif
3517 
3518 #ifndef MG_ENABLE_MQTT
3519 #define MG_ENABLE_MQTT 1
3520 #endif
3521 
3522 #ifndef MG_ENABLE_SOCKS
3523 #define MG_ENABLE_SOCKS 0
3524 #endif
3525 
3526 #ifndef MG_ENABLE_MQTT_BROKER
3527 #define MG_ENABLE_MQTT_BROKER 0
3528 #endif
3529 
3530 #ifndef MG_ENABLE_SSL
3531 #define MG_ENABLE_SSL 0
3532 #endif
3533 
3534 #ifndef MG_ENABLE_SYNC_RESOLVER
3535 #define MG_ENABLE_SYNC_RESOLVER 0
3536 #endif
3537 
3538 #ifndef MG_ENABLE_STDIO
3539 #define MG_ENABLE_STDIO CS_ENABLE_STDIO
3540 #endif
3541 
3542 #ifndef MG_NET_IF
3543 #define MG_NET_IF MG_NET_IF_SOCKET
3544 #endif
3545 
3546 #ifndef MG_SSL_IF
3547 #define MG_SSL_IF MG_SSL_IF_OPENSSL
3548 #endif
3549 
3550 #ifndef MG_ENABLE_THREADS /* ifdef-ok */
3551 #ifdef _WIN32
3552 #define MG_ENABLE_THREADS 1
3553 #else
3554 #define MG_ENABLE_THREADS 0
3555 #endif
3556 #endif
3557 
3558 #if MG_ENABLE_DEBUG && !defined(CS_ENABLE_DEBUG)
3559 #define CS_ENABLE_DEBUG 1
3560 #endif
3561 
3562 /* MQTT broker requires MQTT */
3563 #if MG_ENABLE_MQTT_BROKER && !MG_ENABLE_MQTT
3564 #undef MG_ENABLE_MQTT
3565 #define MG_ENABLE_MQTT 1
3566 #endif
3567 
3568 #ifndef MG_ENABLE_HTTP_URL_REWRITES
3569 #define MG_ENABLE_HTTP_URL_REWRITES \
3570  (CS_PLATFORM == CS_P_WINDOWS || CS_PLATFORM == CS_P_UNIX)
3571 #endif
3572 
3573 #ifndef MG_ENABLE_SNTP
3574 #define MG_ENABLE_SNTP 0
3575 #endif
3576 
3577 #ifndef MG_ENABLE_EXTRA_ERRORS_DESC
3578 #define MG_ENABLE_EXTRA_ERRORS_DESC 0
3579 #endif
3580 
3581 #ifndef MG_ENABLE_CALLBACK_USERDATA
3582 #define MG_ENABLE_CALLBACK_USERDATA 0
3583 #endif
3584 
3585 #if MG_ENABLE_CALLBACK_USERDATA
3586 #define MG_UD_ARG(ud) , ud
3587 #define MG_CB(cb, ud) cb, ud
3588 #else
3589 #define MG_UD_ARG(ud)
3590 #define MG_CB(cb, ud) cb
3591 #endif
3592 
3593 #endif /* CS_MONGOOSE_SRC_FEATURES_H_ */
3594 #ifdef MG_MODULE_LINES
3595 #line 1 "mongoose/src/mg_net_if.h"
3596 #endif
3597 /*
3598  * Copyright (c) 2014-2016 Cesanta Software Limited
3599  * All rights reserved
3600  */
3601 
3602 #ifndef CS_MONGOOSE_SRC_NET_IF_H_
3603 #define CS_MONGOOSE_SRC_NET_IF_H_
3604 
3605 /* Amalgamated: #include "common/platform.h" */
3606 
3607 /*
3608  * Internal async networking core interface.
3609  * Consists of calls made by the core, which should not block,
3610  * and callbacks back into the core ("..._cb").
3611  * Callbacks may (will) cause methods to be invoked from within,
3612  * but methods are not allowed to invoke callbacks inline.
3613  *
3614  * Implementation must ensure that only one callback is invoked at any time.
3615  */
3616 
3617 #ifdef __cplusplus
3618 extern "C" {
3619 #endif /* __cplusplus */
3620 
3621 #define MG_MAIN_IFACE 0
3622 
3623 struct mg_mgr;
3624 struct mg_connection;
3625 union socket_address;
3626 
3627 struct mg_iface_vtable;
3628 
3629 struct mg_iface {
3630  struct mg_mgr *mgr;
3631  void *data; /* Implementation-specific data */
3632  const struct mg_iface_vtable *vtable;
3633 };
3634 
3636  void (*init)(struct mg_iface *iface);
3637  void (*free)(struct mg_iface *iface);
3638  void (*add_conn)(struct mg_connection *nc);
3639  void (*remove_conn)(struct mg_connection *nc);
3640  time_t (*poll)(struct mg_iface *iface, int timeout_ms);
3641 
3642  /* Set up a listening TCP socket on a given address. rv = 0 -> ok. */
3643  int (*listen_tcp)(struct mg_connection *nc, union socket_address *sa);
3644  /* Request that a "listening" UDP socket be created. */
3645  int (*listen_udp)(struct mg_connection *nc, union socket_address *sa);
3646 
3647  /* Request that a TCP connection is made to the specified address. */
3648  void (*connect_tcp)(struct mg_connection *nc, const union socket_address *sa);
3649  /* Open a UDP socket. Doesn't actually connect anything. */
3650  void (*connect_udp)(struct mg_connection *nc);
3651 
3652  /* Send functions for TCP and UDP. Sent data is copied before return. */
3653  int (*tcp_send)(struct mg_connection *nc, const void *buf, size_t len);
3654  int (*udp_send)(struct mg_connection *nc, const void *buf, size_t len);
3655 
3656  int (*tcp_recv)(struct mg_connection *nc, void *buf, size_t len);
3657  int (*udp_recv)(struct mg_connection *nc, void *buf, size_t len,
3658  union socket_address *sa, size_t *sa_len);
3659 
3660  /* Perform interface-related connection initialization. Return 1 on ok. */
3661  int (*create_conn)(struct mg_connection *nc);
3662  /* Perform interface-related cleanup on connection before destruction. */
3663  void (*destroy_conn)(struct mg_connection *nc);
3664 
3665  /* Associate a socket to a connection. */
3666  void (*sock_set)(struct mg_connection *nc, sock_t sock);
3667 
3668  /* Put connection's address into *sa, local (remote = 0) or remote. */
3669  void (*get_conn_addr)(struct mg_connection *nc, int remote,
3670  union socket_address *sa);
3671 };
3672 
3673 extern const struct mg_iface_vtable *mg_ifaces[];
3674 extern int mg_num_ifaces;
3675 
3676 /* Creates a new interface instance. */
3677 struct mg_iface *mg_if_create_iface(const struct mg_iface_vtable *vtable,
3678  struct mg_mgr *mgr);
3679 
3680 /*
3681  * Find an interface with a given implementation. The search is started from
3682  * interface `from`, exclusive. Returns NULL if none is found.
3683  */
3684 struct mg_iface *mg_find_iface(struct mg_mgr *mgr,
3685  const struct mg_iface_vtable *vtable,
3686  struct mg_iface *from);
3687 /*
3688  * Deliver a new TCP connection. Returns NULL in case on error (unable to
3689  * create connection, in which case interface state should be discarded.
3690  * This is phase 1 of the two-phase process - MG_EV_ACCEPT will be delivered
3691  * when mg_if_accept_tcp_cb is invoked.
3692  */
3694 void mg_if_accept_tcp_cb(struct mg_connection *nc, union socket_address *sa,
3695  size_t sa_len);
3696 
3697 /* Callback invoked by connect methods. err = 0 -> ok, != 0 -> error. */
3698 void mg_if_connect_cb(struct mg_connection *nc, int err);
3699 /*
3700  * Callback that tells the core that data can be received.
3701  * Core will use tcp/udp_recv to retrieve the data.
3702  */
3703 void mg_if_can_recv_cb(struct mg_connection *nc);
3704 void mg_if_can_send_cb(struct mg_connection *nc);
3705 /*
3706  * Receive callback.
3707  * buf must be heap-allocated and ownership is transferred to the core.
3708  */
3709 void mg_if_recv_udp_cb(struct mg_connection *nc, void *buf, int len,
3710  union socket_address *sa, size_t sa_len);
3711 
3712 /* void mg_if_close_conn(struct mg_connection *nc); */
3713 
3714 /* Deliver a POLL event to the connection. */
3715 int mg_if_poll(struct mg_connection *nc, double now);
3716 
3717 /*
3718  * Return minimal timer value amoung connections in the manager.
3719  * Returns 0 if there aren't any timers.
3720  */
3721 double mg_mgr_min_timer(const struct mg_mgr *mgr);
3722 
3723 #ifdef __cplusplus
3724 }
3725 #endif /* __cplusplus */
3726 
3727 #endif /* CS_MONGOOSE_SRC_NET_IF_H_ */
3728 #ifdef MG_MODULE_LINES
3729 #line 1 "mongoose/src/mg_ssl_if.h"
3730 #endif
3731 /*
3732  * Copyright (c) 2014-2016 Cesanta Software Limited
3733  * All rights reserved
3734  */
3735 
3736 #ifndef CS_MONGOOSE_SRC_SSL_IF_H_
3737 #define CS_MONGOOSE_SRC_SSL_IF_H_
3738 
3739 #if MG_ENABLE_SSL
3740 
3741 #ifdef __cplusplus
3742 extern "C" {
3743 #endif /* __cplusplus */
3744 
3745 struct mg_ssl_if_ctx;
3746 struct mg_connection;
3747 
3748 void mg_ssl_if_init();
3749 
3755 };
3756 
3758  const char *cert;
3759  const char *key;
3760  const char *ca_cert;
3761  const char *server_name;
3762  const char *cipher_suites;
3763  const char *psk_identity;
3764  const char *psk_key;
3765 };
3766 
3768  struct mg_connection *nc, const struct mg_ssl_if_conn_params *params,
3769  const char **err_msg);
3771  struct mg_connection *lc);
3773 void mg_ssl_if_conn_free(struct mg_connection *nc);
3774 
3776 int mg_ssl_if_read(struct mg_connection *nc, void *buf, size_t buf_size);
3777 int mg_ssl_if_write(struct mg_connection *nc, const void *data, size_t len);
3778 
3779 #ifdef __cplusplus
3780 }
3781 #endif /* __cplusplus */
3782 
3783 #endif /* MG_ENABLE_SSL */
3784 
3785 #endif /* CS_MONGOOSE_SRC_SSL_IF_H_ */
3786 #ifdef MG_MODULE_LINES
3787 #line 1 "mongoose/src/mg_net.h"
3788 #endif
3789 /*
3790  * Copyright (c) 2014 Cesanta Software Limited
3791  * All rights reserved
3792  * This software is dual-licensed: you can redistribute it and/or modify
3793  * it under the terms of the GNU General Public License version 2 as
3794  * published by the Free Software Foundation. For the terms of this
3795  * license, see <http://www.gnu.org/licenses/>.
3796  *
3797  * You are free to use this software under the terms of the GNU General
3798  * Public License, but WITHOUT ANY WARRANTY; without even the implied
3799  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
3800  * See the GNU General Public License for more details.
3801  *
3802  * Alternatively, you can license this software under a commercial
3803  * license, as set out in <https://www.cesanta.com/license>.
3804  */
3805 
3806 /*
3807  * === Core API: TCP/UDP/SSL
3808  *
3809  * NOTE: Mongoose manager is single threaded. It does not protect
3810  * its data structures by mutexes, therefore all functions that are dealing
3811  * with a particular event manager should be called from the same thread,
3812  * with exception of the `mg_broadcast()` function. It is fine to have different
3813  * event managers handled by different threads.
3814  */
3815 
3816 #ifndef CS_MONGOOSE_SRC_NET_H_
3817 #define CS_MONGOOSE_SRC_NET_H_
3818 
3819 /* Amalgamated: #include "mg_common.h" */
3820 /* Amalgamated: #include "mg_net_if.h" */
3821 /* Amalgamated: #include "common/mbuf.h" */
3822 
3823 #ifndef MG_VPRINTF_BUFFER_SIZE
3824 #define MG_VPRINTF_BUFFER_SIZE 100
3825 #endif
3826 
3827 #ifdef MG_USE_READ_WRITE
3828 #define MG_RECV_FUNC(s, b, l, f) read(s, b, l)
3829 #define MG_SEND_FUNC(s, b, l, f) write(s, b, l)
3830 #else
3831 #define MG_RECV_FUNC(s, b, l, f) recv(s, b, l, f)
3832 #define MG_SEND_FUNC(s, b, l, f) send(s, b, l, f)
3833 #endif
3834 
3835 #ifdef __cplusplus
3836 extern "C" {
3837 #endif /* __cplusplus */
3838 
3840  struct sockaddr sa;
3841  struct sockaddr_in sin;
3842 #if MG_ENABLE_IPV6
3843  struct sockaddr_in6 sin6;
3844 #else
3845  struct sockaddr sin6;
3846 #endif
3847 };
3848 
3849 struct mg_connection;
3850 
3851 /*
3852  * Callback function (event handler) prototype. Must be defined by the user.
3853  * Mongoose calls the event handler, passing the events defined below.
3854  */
3855 typedef void (*mg_event_handler_t)(struct mg_connection *nc, int ev,
3856  void *ev_data MG_UD_ARG(void *user_data));
3857 
3858 /* Events. Meaning of event parameter (evp) is given in the comment. */
3859 #define MG_EV_POLL 0 /* Sent to each connection on each mg_mgr_poll() call */
3860 #define MG_EV_ACCEPT 1 /* New connection accepted. union socket_address * */
3861 #define MG_EV_CONNECT 2 /* connect() succeeded or failed. int * */
3862 #define MG_EV_RECV 3 /* Data has been received. int *num_bytes */
3863 #define MG_EV_SEND 4 /* Data has been written to a socket. int *num_bytes */
3864 #define MG_EV_CLOSE 5 /* Connection is closed. NULL */
3865 #define MG_EV_TIMER 6 /* now >= conn->ev_timer_time. double * */
3866 
3867 /*
3868  * Mongoose event manager.
3869  */
3870 struct mg_mgr {
3872 #if MG_ENABLE_HEXDUMP
3873  const char *hexdump_file; /* Debug hexdump file path */
3874 #endif
3875 #if MG_ENABLE_BROADCAST
3876  sock_t ctl[2]; /* Socketpair for mg_broadcast() */
3877 #endif
3878  void *user_data; /* User data */
3881  struct mg_iface **ifaces; /* network interfaces */
3882  const char *nameserver; /* DNS server to use */
3883 };
3884 
3885 /*
3886  * Mongoose connection.
3887  */
3889  struct mg_connection *next, *prev; /* mg_mgr::active_connections linkage */
3890  struct mg_connection *listener; /* Set only for accept()-ed connections */
3891  struct mg_mgr *mgr; /* Pointer to containing manager */
3892 
3893  sock_t sock; /* Socket to the remote peer */
3894  int err;
3895  union socket_address sa; /* Remote peer address */
3896  size_t recv_mbuf_limit; /* Max size of recv buffer */
3897  struct mbuf recv_mbuf; /* Received data */
3898  struct mbuf send_mbuf; /* Data scheduled for sending */
3899  time_t last_io_time; /* Timestamp of the last socket IO */
3900  double ev_timer_time; /* Timestamp of the future MG_EV_TIMER */
3901 #if MG_ENABLE_SSL
3902  void *ssl_if_data; /* SSL library data. */
3903 #endif
3904  mg_event_handler_t proto_handler; /* Protocol-specific event handler */
3905  void *proto_data; /* Protocol-specific data */
3906  void (*proto_data_destructor)(void *proto_data);
3907  mg_event_handler_t handler; /* Event handler function */
3908  void *user_data; /* User-specific data */
3909  union {
3910  void *v;
3911  /*
3912  * the C standard is fussy about fitting function pointers into
3913  * void pointers, since some archs might have fat pointers for functions.
3914  */
3916  } priv_1;
3917  void *priv_2;
3918  void *mgr_data; /* Implementation-specific event manager's data. */
3919  struct mg_iface *iface;
3920  unsigned long flags;
3921 /* Flags set by Mongoose */
3922 #define MG_F_LISTENING (1 << 0) /* This connection is listening */
3923 #define MG_F_UDP (1 << 1) /* This connection is UDP */
3924 #define MG_F_RESOLVING (1 << 2) /* Waiting for async resolver */
3925 #define MG_F_CONNECTING (1 << 3) /* connect() call in progress */
3926 #define MG_F_SSL (1 << 4) /* SSL is enabled on the connection */
3927 #define MG_F_SSL_HANDSHAKE_DONE (1 << 5) /* SSL hanshake has completed */
3928 #define MG_F_WANT_READ (1 << 6) /* SSL specific */
3929 #define MG_F_WANT_WRITE (1 << 7) /* SSL specific */
3930 #define MG_F_IS_WEBSOCKET (1 << 8) /* Websocket specific */
3931 
3932 /* Flags that are settable by user */
3933 #define MG_F_SEND_AND_CLOSE (1 << 10) /* Push remaining data and close */
3934 #define MG_F_CLOSE_IMMEDIATELY (1 << 11) /* Disconnect */
3935 #define MG_F_WEBSOCKET_NO_DEFRAG (1 << 12) /* Websocket specific */
3936 #define MG_F_DELETE_CHUNK (1 << 13) /* HTTP specific */
3937 #define MG_F_ENABLE_BROADCAST (1 << 14) /* Allow broadcast address usage */
3938 
3939 #define MG_F_USER_1 (1 << 20) /* Flags left for application */
3940 #define MG_F_USER_2 (1 << 21)
3941 #define MG_F_USER_3 (1 << 22)
3942 #define MG_F_USER_4 (1 << 23)
3943 #define MG_F_USER_5 (1 << 24)
3944 #define MG_F_USER_6 (1 << 25)
3945 };
3946 
3947 /*
3948  * Initialise Mongoose manager. Side effect: ignores SIGPIPE signal.
3949  * `mgr->user_data` field will be initialised with a `user_data` parameter.
3950  * That is an arbitrary pointer, where the user code can associate some data
3951  * with the particular Mongoose manager. For example, a C++ wrapper class
3952  * could be written in which case `user_data` can hold a pointer to the
3953  * class instance.
3954  */
3955 void mg_mgr_init(struct mg_mgr *mgr, void *user_data);
3956 
3957 /*
3958  * Optional parameters to `mg_mgr_init_opt()`.
3959  *
3960  * If `main_iface` is not NULL, it will be used as the main interface in the
3961  * default interface set. The pointer will be free'd by `mg_mgr_free`.
3962  * Otherwise, the main interface will be autodetected based on the current
3963  * platform.
3964  *
3965  * If `num_ifaces` is 0 and `ifaces` is NULL, the default interface set will be
3966  * used.
3967  * This is an advanced option, as it requires you to construct a full interface
3968  * set, including special networking interfaces required by some optional
3969  * features such as TCP tunneling. Memory backing `ifaces` and each of the
3970  * `num_ifaces` pointers it contains will be reclaimed by `mg_mgr_free`.
3971  */
3975  const struct mg_iface_vtable **ifaces;
3976  const char *nameserver;
3977 };
3978 
3979 /*
3980  * Like `mg_mgr_init` but with more options.
3981  *
3982  * Notably, this allows you to create a manger and choose
3983  * dynamically which networking interface implementation to use.
3984  */
3985 void mg_mgr_init_opt(struct mg_mgr *mgr, void *user_data,
3986  struct mg_mgr_init_opts opts);
3987 
3988 /*
3989  * De-initialises Mongoose manager.
3990  *
3991  * Closes and deallocates all active connections.
3992  */
3993 void mg_mgr_free(struct mg_mgr *mgr);
3994 
3995 /*
3996  * This function performs the actual IO and must be called in a loop
3997  * (an event loop). It returns number of user events generated (except POLLs).
3998  * `milli` is the maximum number of milliseconds to sleep.
3999  * `mg_mgr_poll()` checks all connections for IO readiness. If at least one
4000  * of the connections is IO-ready, `mg_mgr_poll()` triggers the respective
4001  * event handlers and returns.
4002  */
4003 int mg_mgr_poll(struct mg_mgr *mgr, int milli);
4004 
4005 #if MG_ENABLE_BROADCAST
4006 /*
4007  * Passes a message of a given length to all connections.
4008  *
4009  * Must be called from a thread that does NOT call `mg_mgr_poll()`.
4010  * Note that `mg_broadcast()` is the only function
4011  * that can be, and must be, called from a different (non-IO) thread.
4012  *
4013  * `func` callback function will be called by the IO thread for each
4014  * connection. When called, the event will be `MG_EV_POLL`, and a message will
4015  * be passed as the `ev_data` pointer. Maximum message size is capped
4016  * by `MG_CTL_MSG_MESSAGE_SIZE` which is set to 8192 bytes.
4017  */
4018 void mg_broadcast(struct mg_mgr *mgr, mg_event_handler_t cb, void *data,
4019  size_t len);
4020 #endif
4021 
4022 /*
4023  * Iterates over all active connections.
4024  *
4025  * Returns the next connection from the list
4026  * of active connections or `NULL` if there are no more connections. Below
4027  * is the iteration idiom:
4028  *
4029  * ```c
4030  * for (c = mg_next(srv, NULL); c != NULL; c = mg_next(srv, c)) {
4031  * // Do something with connection `c`
4032  * }
4033  * ```
4034  */
4035 struct mg_connection *mg_next(struct mg_mgr *mgr, struct mg_connection *c);
4036 
4037 /*
4038  * Optional parameters to `mg_add_sock_opt()`.
4039  *
4040  * `flags` is an initial `struct mg_connection::flags` bitmask to set,
4041  * see `MG_F_*` flags definitions.
4042  */
4044  void *user_data; /* Initial value for connection's user_data */
4045  unsigned int flags; /* Initial connection flags */
4046  const char **error_string; /* Placeholder for the error string */
4047  struct mg_iface *iface; /* Interface instance */
4048 };
4049 
4050 /*
4051  * Creates a connection, associates it with the given socket and event handler
4052  * and adds it to the manager.
4053  *
4054  * For more options see the `mg_add_sock_opt` variant.
4055  */
4056 struct mg_connection *mg_add_sock(struct mg_mgr *mgr, sock_t sock,
4058  void *user_data));
4059 
4060 /*
4061  * Creates a connection, associates it with the given socket and event handler
4062  * and adds to the manager.
4063  *
4064  * See the `mg_add_sock_opts` structure for a description of the options.
4065  */
4066 struct mg_connection *mg_add_sock_opt(struct mg_mgr *mgr, sock_t sock,
4068  void *user_data),
4069  struct mg_add_sock_opts opts);
4070 
4071 /*
4072  * Optional parameters to `mg_bind_opt()`.
4073  *
4074  * `flags` is an initial `struct mg_connection::flags` bitmask to set,
4075  * see `MG_F_*` flags definitions.
4076  */
4078  void *user_data; /* Initial value for connection's user_data */
4079  unsigned int flags; /* Extra connection flags */
4080  const char **error_string; /* Placeholder for the error string */
4081  struct mg_iface *iface; /* Interface instance */
4082 #if MG_ENABLE_SSL
4083  /*
4084  * SSL settings.
4085  *
4086  * Server certificate to present to clients or client certificate to
4087  * present to tunnel dispatcher (for tunneled connections).
4088  */
4089  const char *ssl_cert;
4090  /* Private key corresponding to the certificate. If ssl_cert is set but
4091  * ssl_key is not, ssl_cert is used. */
4092  const char *ssl_key;
4093  /* CA bundle used to verify client certificates or tunnel dispatchers. */
4094  const char *ssl_ca_cert;
4095  /* Colon-delimited list of acceptable cipher suites.
4096  * Names depend on the library used, for example:
4097  *
4098  * ECDH-ECDSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256 (OpenSSL)
4099  * TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256
4100  * (mbedTLS)
4101  *
4102  * For OpenSSL the list can be obtained by running "openssl ciphers".
4103  * For mbedTLS, names can be found in library/ssl_ciphersuites.c
4104  * If NULL, a reasonable default is used.
4105  */
4106  const char *ssl_cipher_suites;
4107 #endif
4108 };
4109 
4110 /*
4111  * Creates a listening connection.
4112  *
4113  * See `mg_bind_opt` for full documentation.
4114  */
4115 struct mg_connection *mg_bind(struct mg_mgr *mgr, const char *address,
4117  void *user_data));
4118 /*
4119  * Creates a listening connection.
4120  *
4121  * The `address` parameter specifies which address to bind to. It's format is
4122  * the same as for the `mg_connect()` call, where `HOST` part is optional.
4123  * `address` can be just a port number, e.g. `:8000`. To bind to a specific
4124  * interface, an IP address can be specified, e.g. `1.2.3.4:8000`. By default,
4125  * a TCP connection is created. To create UDP connection, prepend `udp://`
4126  * prefix, e.g. `udp://:8000`. To summarize, `address` parameter has following
4127  * format: `[PROTO://][IP_ADDRESS]:PORT`, where `PROTO` could be `tcp` or
4128  * `udp`.
4129  *
4130  * See the `mg_bind_opts` structure for a description of the optional
4131  * parameters.
4132  *
4133  * Returns a new listening connection or `NULL` on error.
4134  * NOTE: The connection remains owned by the manager, do not free().
4135  */
4136 struct mg_connection *mg_bind_opt(struct mg_mgr *mgr, const char *address,
4138  void *user_data),
4139  struct mg_bind_opts opts);
4140 
4141 /* Optional parameters to `mg_connect_opt()` */
4143  void *user_data; /* Initial value for connection's user_data */
4144  unsigned int flags; /* Extra connection flags */
4145  const char **error_string; /* Placeholder for the error string */
4146  struct mg_iface *iface; /* Interface instance */
4147  const char *nameserver; /* DNS server to use, NULL for default */
4148 #if MG_ENABLE_SSL
4149  /*
4150  * SSL settings.
4151  * Client certificate to present to the server.
4152  */
4153  const char *ssl_cert;
4154  /*
4155  * Private key corresponding to the certificate.
4156  * If ssl_cert is set but ssl_key is not, ssl_cert is used.
4157  */
4158  const char *ssl_key;
4159  /*
4160  * Verify server certificate using this CA bundle. If set to "*", then SSL
4161  * is enabled but no cert verification is performed.
4162  */
4163  const char *ssl_ca_cert;
4164  /* Colon-delimited list of acceptable cipher suites.
4165  * Names depend on the library used, for example:
4166  *
4167  * ECDH-ECDSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256 (OpenSSL)
4168  * TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256
4169  * (mbedTLS)
4170  *
4171  * For OpenSSL the list can be obtained by running "openssl ciphers".
4172  * For mbedTLS, names can be found in library/ssl_ciphersuites.c
4173  * If NULL, a reasonable default is used.
4174  */
4175  const char *ssl_cipher_suites;
4176  /*
4177  * Server name verification. If ssl_ca_cert is set and the certificate has
4178  * passed verification, its subject will be verified against this string.
4179  * By default (if ssl_server_name is NULL) hostname part of the address will
4180  * be used. Wildcard matching is supported. A special value of "*" disables
4181  * name verification.
4182  */
4183  const char *ssl_server_name;
4184  /*
4185  * PSK identity and key. Identity is a NUL-terminated string and key is a hex
4186  * string. Key must be either 16 or 32 bytes (32 or 64 hex digits) for AES-128
4187  * or AES-256 respectively.
4188  * Note: Default list of cipher suites does not include PSK suites, if you
4189  * want to use PSK you will need to set ssl_cipher_suites as well.
4190  */
4191  const char *ssl_psk_identity;
4192  const char *ssl_psk_key;
4193 #endif
4194 };
4195 
4196 /*
4197  * Connects to a remote host.
4198  *
4199  * See `mg_connect_opt()` for full documentation.
4200  */
4201 struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *address,
4203  void *user_data));
4204 
4205 /*
4206  * Connects to a remote host.
4207  *
4208  * The `address` format is `[PROTO://]HOST:PORT`. `PROTO` could be `tcp` or
4209  * `udp`. `HOST` could be an IP address,
4210  * IPv6 address (if Mongoose is compiled with `-DMG_ENABLE_IPV6`) or a host
4211  * name. If `HOST` is a name, Mongoose will resolve it asynchronously. Examples
4212  * of valid addresses: `google.com:80`, `udp://1.2.3.4:53`, `10.0.0.1:443`,
4213  * `[::1]:80`
4214  *
4215  * See the `mg_connect_opts` structure for a description of the optional
4216  * parameters.
4217  *
4218  * Returns a new outbound connection or `NULL` on error.
4219  *
4220  * NOTE: The connection remains owned by the manager, do not free().
4221  *
4222  * NOTE: To enable IPv6 addresses `-DMG_ENABLE_IPV6` should be specified
4223  * in the compilation flags.
4224  *
4225  * NOTE: The new connection will receive `MG_EV_CONNECT` as its first event
4226  * which will report the connect success status.
4227  * If the asynchronous resolution fails or the `connect()` syscall fails for
4228  * whatever reason (e.g. with `ECONNREFUSED` or `ENETUNREACH`), then
4229  * `MG_EV_CONNECT` event will report failure. Code example below:
4230  *
4231  * ```c
4232  * static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
4233  * int connect_status;
4234  *
4235  * switch (ev) {
4236  * case MG_EV_CONNECT:
4237  * connect_status = * (int *) ev_data;
4238  * if (connect_status == 0) {
4239  * // Success
4240  * } else {
4241  * // Error
4242  * printf("connect() error: %s\n", strerror(connect_status));
4243  * }
4244  * break;
4245  * ...
4246  * }
4247  * }
4248  *
4249  * ...
4250  * mg_connect(mgr, "my_site.com:80", ev_handler);
4251  * ```
4252  */
4253 struct mg_connection *mg_connect_opt(struct mg_mgr *mgr, const char *address,
4255  void *user_data),
4256  struct mg_connect_opts opts);
4257 
4258 #if MG_ENABLE_SSL && MG_NET_IF != MG_NET_IF_SIMPLELINK
4259 /*
4260  * Note: This function is deprecated. Please, use SSL options in
4261  * mg_connect_opt.
4262  *
4263  * Enables SSL for a given connection.
4264  * `cert` is a server certificate file name for a listening connection
4265  * or a client certificate file name for an outgoing connection.
4266  * The certificate files must be in PEM format. The server certificate file
4267  * must contain a certificate, concatenated with a private key, optionally
4268  * concatenated with DH parameters.
4269  * `ca_cert` is a CA certificate or NULL if peer verification is not
4270  * required.
4271  * Return: NULL on success or error message on error.
4272  */
4273 const char *mg_set_ssl(struct mg_connection *nc, const char *cert,
4274  const char *ca_cert);
4275 #endif
4276 
4277 /*
4278  * Sends data to the connection.
4279  *
4280  * Note that sending functions do not actually push data to the socket.
4281  * They just append data to the output buffer. MG_EV_SEND will be delivered when
4282  * the data has actually been pushed out.
4283  */
4284 void mg_send(struct mg_connection *, const void *buf, int len);
4285 
4286 /* Enables format string warnings for mg_printf */
4287 #if defined(__GNUC__)
4288 __attribute__((format(printf, 2, 3)))
4289 #endif
4290 /* don't separate from mg_printf declaration */
4291 
4292 /*
4293  * Sends `printf`-style formatted data to the connection.
4294  *
4295  * See `mg_send` for more details on send semantics.
4296  */
4297 int mg_printf(struct mg_connection *, const char *fmt, ...);
4298 
4299 /* Same as `mg_printf()`, but takes `va_list ap` as an argument. */
4300 int mg_vprintf(struct mg_connection *, const char *fmt, va_list ap);
4301 
4302 /*
4303  * Creates a socket pair.
4304  * `sock_type` can be either `SOCK_STREAM` or `SOCK_DGRAM`.
4305  * Returns 0 on failure and 1 on success.
4306  */
4307 int mg_socketpair(sock_t[2], int sock_type);
4308 
4309 #if MG_ENABLE_SYNC_RESOLVER
4310 /*
4311  * Convert domain name into IP address.
4312  *
4313  * This is a utility function. If compilation flags have
4314  * `-DMG_ENABLE_GETADDRINFO`, then `getaddrinfo()` call is used for name
4315  * resolution. Otherwise, `gethostbyname()` is used.
4316  *
4317  * CAUTION: this function can block.
4318  * Return 1 on success, 0 on failure.
4319  */
4320 int mg_resolve(const char *domain_name, char *ip_addr_buf, size_t buf_len);
4321 #endif
4322 
4323 /*
4324  * Verify given IP address against the ACL.
4325  *
4326  * `remote_ip` - an IPv4 address to check, in host byte order
4327  * `acl` - a comma separated list of IP subnets: `x.x.x.x/x` or `x.x.x.x`.
4328  * Each subnet is
4329  * prepended by either a - or a + sign. A plus sign means allow, where a
4330  * minus sign means deny. If a subnet mask is omitted, such as `-1.2.3.4`,
4331  * it means that only that single IP address is denied.
4332  * Subnet masks may vary from 0 to 32, inclusive. The default setting
4333  * is to allow all access. On each request the full list is traversed,
4334  * and the last match wins. Example:
4335  *
4336  * `-0.0.0.0/0,+192.168/16` - deny all accesses, only allow 192.168/16 subnet
4337  *
4338  * To learn more about subnet masks, see this
4339  * link:https://en.wikipedia.org/wiki/Subnetwork[Wikipedia page on Subnetwork].
4340  *
4341  * Returns -1 if ACL is malformed, 0 if address is disallowed, 1 if allowed.
4342  */
4343 int mg_check_ip_acl(const char *acl, uint32_t remote_ip);
4344 
4345 /*
4346  * Schedules an MG_EV_TIMER event to be delivered at `timestamp` time.
4347  * `timestamp` is UNIX time (the number of seconds since Epoch). It is
4348  * `double` instead of `time_t` to allow for sub-second precision.
4349  * Returns the old timer value.
4350  *
4351  * Example: set the connect timeout to 1.5 seconds:
4352  *
4353  * ```
4354  * c = mg_connect(&mgr, "cesanta.com", ev_handler);
4355  * mg_set_timer(c, mg_time() + 1.5);
4356  * ...
4357  *
4358  * void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
4359  * switch (ev) {
4360  * case MG_EV_CONNECT:
4361  * mg_set_timer(c, 0); // Clear connect timer
4362  * break;
4363  * case MG_EV_TIMER:
4364  * log("Connect timeout");
4365  * c->flags |= MG_F_CLOSE_IMMEDIATELY;
4366  * break;
4367  * ```
4368  */
4369 double mg_set_timer(struct mg_connection *c, double timestamp);
4370 
4371 /*
4372  * A sub-second precision version of time().
4373  */
4374 double mg_time(void);
4375 
4376 #ifdef __cplusplus
4377 }
4378 #endif /* __cplusplus */
4379 
4380 #endif /* CS_MONGOOSE_SRC_NET_H_ */
4381 #ifdef MG_MODULE_LINES
4382 #line 1 "mongoose/src/mg_uri.h"
4383 #endif
4384 /*
4385  * Copyright (c) 2014 Cesanta Software Limited
4386  * All rights reserved
4387  */
4388 
4389 /*
4390  * === URI
4391  */
4392 
4393 #ifndef CS_MONGOOSE_SRC_URI_H_
4394 #define CS_MONGOOSE_SRC_URI_H_
4395 
4396 /* Amalgamated: #include "mg_net.h" */
4397 
4398 #ifdef __cplusplus
4399 extern "C" {
4400 #endif /* __cplusplus */
4401 
4402 /*
4403  * Parses an URI and fills string chunks with locations of the respective
4404  * uri components within the input uri string. NULL pointers will be
4405  * ignored.
4406  *
4407  * General syntax:
4408  *
4409  * [scheme://[user_info@]]host[:port][/path][?query][#fragment]
4410  *
4411  * Example:
4412  *
4413  * foo.com:80
4414  * tcp://foo.com:1234
4415  * http://foo.com:80/bar?baz=1
4416  * https://user:pw@foo.com:443/blah
4417  *
4418  * `path` will include the leading slash. `query` won't include the leading `?`.
4419  * `host` can contain embedded colons if surrounded by square brackets in order
4420  * to support IPv6 literal addresses.
4421  *
4422  *
4423  * Returns 0 on success, -1 on error.
4424  */
4425 int mg_parse_uri(const struct mg_str uri, struct mg_str *scheme,
4426  struct mg_str *user_info, struct mg_str *host,
4427  unsigned int *port, struct mg_str *path, struct mg_str *query,
4428  struct mg_str *fragment);
4429 
4430 /*
4431  * Assemble URI from parts. Any of the inputs can be NULL or zero-length mg_str.
4432  *
4433  * If normalize_path is true, path is normalized by resolving relative refs.
4434  *
4435  * Result is a heap-allocated string (uri->p must be free()d after use).
4436  *
4437  * Returns 0 on success, -1 on error.
4438  */
4439 int mg_assemble_uri(const struct mg_str *scheme, const struct mg_str *user_info,
4440  const struct mg_str *host, unsigned int port,
4441  const struct mg_str *path, const struct mg_str *query,
4442  const struct mg_str *fragment, int normalize_path,
4443  struct mg_str *uri);
4444 
4445 int mg_normalize_uri_path(const struct mg_str *in, struct mg_str *out);
4446 
4447 #ifdef __cplusplus
4448 }
4449 #endif /* __cplusplus */
4450 #endif /* CS_MONGOOSE_SRC_URI_H_ */
4451 #ifdef MG_MODULE_LINES
4452 #line 1 "mongoose/src/mg_util.h"
4453 #endif
4454 /*
4455  * Copyright (c) 2014 Cesanta Software Limited
4456  * All rights reserved
4457  */
4458 
4459 /*
4460  * === Utility API
4461  */
4462 
4463 #ifndef CS_MONGOOSE_SRC_UTIL_H_
4464 #define CS_MONGOOSE_SRC_UTIL_H_
4465 
4466 #include <stdio.h>
4467 
4468 /* Amalgamated: #include "mg_common.h" */
4469 /* Amalgamated: #include "mg_net_if.h" */
4470 
4471 #ifdef __cplusplus
4472 extern "C" {
4473 #endif /* __cplusplus */
4474 
4475 #ifndef MG_MAX_PATH
4476 #ifdef PATH_MAX
4477 #define MG_MAX_PATH PATH_MAX
4478 #else
4479 #define MG_MAX_PATH 256
4480 #endif
4481 #endif
4482 
4483 /*
4484  * Fetches substring from input string `s`, `end` into `v`.
4485  * Skips initial delimiter characters. Records first non-delimiter character
4486  * at the beginning of substring `v`. Then scans the rest of the string
4487  * until a delimiter character or end-of-string is found.
4488  * `delimiters` is a 0-terminated string containing delimiter characters.
4489  * Either one of `delimiters` or `end_string` terminates the search.
4490  * Returns an `s` pointer, advanced forward where parsing has stopped.
4491  */
4492 const char *mg_skip(const char *s, const char *end_string,
4493  const char *delimiters, struct mg_str *v);
4494 
4495 /*
4496  * Decodes base64-encoded string `s`, `len` into the destination `dst`.
4497  * The destination has to have enough space to hold the decoded buffer.
4498  * Decoding stops either when all strings have been decoded or invalid an
4499  * character appeared.
4500  * Destination is '\0'-terminated.
4501  * Returns the number of decoded characters. On success, that should be equal
4502  * to `len`. On error (invalid character) the return value is smaller then
4503  * `len`.
4504  */
4505 int mg_base64_decode(const unsigned char *s, int len, char *dst);
4506 
4507 /*
4508  * Base64-encode chunk of memory `src`, `src_len` into the destination `dst`.
4509  * Destination has to have enough space to hold encoded buffer.
4510  * Destination is '\0'-terminated.
4511  */
4512 void mg_base64_encode(const unsigned char *src, int src_len, char *dst);
4513 
4514 #if MG_ENABLE_FILESYSTEM
4515 /*
4516  * Performs a 64-bit `stat()` call against a given file.
4517  *
4518  * `path` should be UTF8 encoded.
4519  *
4520  * Return value is the same as for `stat()` syscall.
4521  */
4522 int mg_stat(const char *path, cs_stat_t *st);
4523 
4524 /*
4525  * Opens the given file and returns a file stream.
4526  *
4527  * `path` and `mode` should be UTF8 encoded.
4528  *
4529  * Return value is the same as for the `fopen()` call.
4530  */
4531 FILE *mg_fopen(const char *path, const char *mode);
4532 
4533 /*
4534  * Opens the given file and returns a file stream.
4535  *
4536  * `path` should be UTF8 encoded.
4537  *
4538  * Return value is the same as for the `open()` syscall.
4539  */
4540 int mg_open(const char *path, int flag, int mode);
4541 
4542 /*
4543  * Reads data from the given file stream.
4544  *
4545  * Return value is a number of bytes readen.
4546  */
4547 size_t mg_fread(void *ptr, size_t size, size_t count, FILE *f);
4548 
4549 /*
4550  * Writes data to the given file stream.
4551  *
4552  * Return value is a number of bytes wtitten.
4553  */
4554 size_t mg_fwrite(const void *ptr, size_t size, size_t count, FILE *f);
4555 
4556 #endif /* MG_ENABLE_FILESYSTEM */
4557 
4558 #if MG_ENABLE_THREADS
4559 /*
4560  * Starts a new detached thread.
4561  * Arguments and semantics are the same as pthead's `pthread_create()`.
4562  * `thread_func` is a thread function, `thread_func_param` is a parameter
4563  * that is passed to the thread function.
4564  */
4565 void *mg_start_thread(void *(*thread_func)(void *), void *thread_func_param);
4566 #endif
4567 
4568 void mg_set_close_on_exec(sock_t);
4569 
4570 #define MG_SOCK_STRINGIFY_IP 1
4571 #define MG_SOCK_STRINGIFY_PORT 2
4572 #define MG_SOCK_STRINGIFY_REMOTE 4
4573 /*
4574  * Converts a connection's local or remote address into string.
4575  *
4576  * The `flags` parameter is a bit mask that controls the behaviour,
4577  * see `MG_SOCK_STRINGIFY_*` definitions.
4578  *
4579  * - MG_SOCK_STRINGIFY_IP - print IP address
4580  * - MG_SOCK_STRINGIFY_PORT - print port number
4581  * - MG_SOCK_STRINGIFY_REMOTE - print remote peer's IP/port, not local address
4582  *
4583  * If both port number and IP address are printed, they are separated by `:`.
4584  * If compiled with `-DMG_ENABLE_IPV6`, IPv6 addresses are supported.
4585  * Return length of the stringified address.
4586  */
4587 int mg_conn_addr_to_str(struct mg_connection *c, char *buf, size_t len,
4588  int flags);
4589 #if MG_NET_IF == MG_NET_IF_SOCKET
4590 /* Legacy interface. */
4591 void mg_sock_to_str(sock_t sock, char *buf, size_t len, int flags);
4592 #endif
4593 
4594 /*
4595  * Convert the socket's address into string.
4596  *
4597  * `flags` is MG_SOCK_STRINGIFY_IP and/or MG_SOCK_STRINGIFY_PORT.
4598  */
4599 int mg_sock_addr_to_str(const union socket_address *sa, char *buf, size_t len,
4600  int flags);
4601 
4602 #if MG_ENABLE_HEXDUMP
4603 /*
4604  * Generates a human-readable hexdump of memory chunk.
4605  *
4606  * Takes a memory buffer `buf` of length `len` and creates a hex dump of that
4607  * buffer in `dst`. The generated output is a-la hexdump(1).
4608  * Returns the length of generated string, excluding terminating `\0`. If
4609  * returned length is bigger than `dst_len`, the overflow bytes are discarded.
4610  */
4611 int mg_hexdump(const void *buf, int len, char *dst, int dst_len);
4612 
4613 /* Same as mg_hexdump, but with output going to file instead of a buffer. */
4614 void mg_hexdumpf(FILE *fp, const void *buf, int len);
4615 
4616 /*
4617  * Generates human-readable hexdump of the data sent or received by the
4618  * connection. `path` is a file name where hexdump should be written.
4619  * `num_bytes` is a number of bytes sent/received. `ev` is one of the `MG_*`
4620  * events sent to an event handler. This function is supposed to be called from
4621  * the event handler.
4622  */
4623 void mg_hexdump_connection(struct mg_connection *nc, const char *path,
4624  const void *buf, int num_bytes, int ev);
4625 #endif
4626 
4627 /*
4628  * Returns true if target platform is big endian.
4629  */
4630 int mg_is_big_endian(void);
4631 
4632 /*
4633  * Use with cs_base64_init/update/finish in order to write out base64 in chunks.
4634  */
4635 void mg_mbuf_append_base64_putc(char ch, void *user_data);
4636 
4637 /*
4638  * Encode `len` bytes starting at `data` as base64 and append them to an mbuf.
4639  */
4640 void mg_mbuf_append_base64(struct mbuf *mbuf, const void *data, size_t len);
4641 
4642 /*
4643  * Generate a Basic Auth header and appends it to buf.
4644  * If pass is NULL, then user is expected to contain the credentials pair
4645  * already encoded as `user:pass`.
4646  */
4647 void mg_basic_auth_header(const struct mg_str user, const struct mg_str pass,
4648  struct mbuf *buf);
4649 
4650 /*
4651  * URL-escape the specified string.
4652  * All characters acept letters, numbers and characters listed in
4653  * `safe` are escaped. If `hex_upper`is true, `A-F` are used for hex digits.
4654  * Input need not be NUL-terminated, but the returned string is.
4655  * Returned string is heap-allocated and must be free()'d.
4656  */
4657 #define MG_URL_ENCODE_F_SPACE_AS_PLUS (1 << 0)
4658 #define MG_URL_ENCODE_F_UPPERCASE_HEX (1 << 1)
4659 struct mg_str mg_url_encode_opt(const struct mg_str src,
4660  const struct mg_str safe, unsigned int flags);
4661 
4662 /* Same as `mg_url_encode_opt(src, "._-$,;~()/", 0)`. */
4663 struct mg_str mg_url_encode(const struct mg_str src);
4664 
4665 #ifdef __cplusplus
4666 }
4667 #endif /* __cplusplus */
4668 #endif /* CS_MONGOOSE_SRC_UTIL_H_ */
4669 #ifdef MG_MODULE_LINES
4670 #line 1 "mongoose/src/mg_http.h"
4671 #endif
4672 /*
4673  * Copyright (c) 2014 Cesanta Software Limited
4674  * All rights reserved
4675  */
4676 
4677 /*
4678  * === Common API reference
4679  */
4680 
4681 #ifndef CS_MONGOOSE_SRC_HTTP_H_
4682 #define CS_MONGOOSE_SRC_HTTP_H_
4683 
4684 #if MG_ENABLE_HTTP
4685 
4686 /* Amalgamated: #include "mg_net.h" */
4687 /* Amalgamated: #include "common/mg_str.h" */
4688 
4689 #ifdef __cplusplus
4690 extern "C" {
4691 #endif /* __cplusplus */
4692 
4693 #ifndef MG_MAX_HTTP_HEADERS
4694 #define MG_MAX_HTTP_HEADERS 20
4695 #endif
4696 
4697 #ifndef MG_MAX_HTTP_REQUEST_SIZE
4698 #define MG_MAX_HTTP_REQUEST_SIZE 1024
4699 #endif
4700 
4701 #ifndef MG_MAX_HTTP_SEND_MBUF
4702 #define MG_MAX_HTTP_SEND_MBUF 1024
4703 #endif
4704 
4705 #ifndef MG_CGI_ENVIRONMENT_SIZE
4706 #define MG_CGI_ENVIRONMENT_SIZE 8192
4707 #endif
4708 
4709 /* HTTP message */
4711  struct mg_str message; /* Whole message: request line + headers + body */
4712  struct mg_str body; /* Message body. 0-length for requests with no body */
4713 
4714  /* HTTP Request line (or HTTP response line) */
4715  struct mg_str method; /* "GET" */
4716  struct mg_str uri; /* "/my_file.html" */
4717  struct mg_str proto; /* "HTTP/1.1" -- for both request and response */
4718 
4719  /* For responses, code and response status message are set */
4721  struct mg_str resp_status_msg;
4722 
4723  /*
4724  * Query-string part of the URI. For example, for HTTP request
4725  * GET /foo/bar?param1=val1&param2=val2
4726  * | uri | query_string |
4727  *
4728  * Note that question mark character doesn't belong neither to the uri,
4729  * nor to the query_string
4730  */
4731  struct mg_str query_string;
4732 
4733  /* Headers */
4734  struct mg_str header_names[MG_MAX_HTTP_HEADERS];
4735  struct mg_str header_values[MG_MAX_HTTP_HEADERS];
4736 };
4737 
4738 #if MG_ENABLE_HTTP_WEBSOCKET
4739 /* WebSocket message */
4741  unsigned char *data;
4742  size_t size;
4743  unsigned char flags;
4744 };
4745 #endif
4746 
4747 /* HTTP multipart part */
4749  const char *file_name;
4750  const char *var_name;
4751  struct mg_str data;
4752  int status; /* <0 on error */
4753  void *user_data;
4754 };
4755 
4756 /* SSI call context */
4758  struct http_message *req; /* The request being processed. */
4759  struct mg_str file; /* Filesystem path of the file being processed. */
4760  struct mg_str arg; /* The argument passed to the tag: <!-- call arg -->. */
4761 };
4762 
4763 /* HTTP and websocket events. void *ev_data is described in a comment. */
4764 #define MG_EV_HTTP_REQUEST 100 /* struct http_message * */
4765 #define MG_EV_HTTP_REPLY 101 /* struct http_message * */
4766 #define MG_EV_HTTP_CHUNK 102 /* struct http_message * */
4767 #define MG_EV_SSI_CALL 105 /* char * */
4768 #define MG_EV_SSI_CALL_CTX 106 /* struct mg_ssi_call_ctx * */
4769 
4770 #if MG_ENABLE_HTTP_WEBSOCKET
4771 #define MG_EV_WEBSOCKET_HANDSHAKE_REQUEST 111 /* struct http_message * */
4772 #define MG_EV_WEBSOCKET_HANDSHAKE_DONE 112 /* NULL */
4773 #define MG_EV_WEBSOCKET_FRAME 113 /* struct websocket_message * */
4774 #define MG_EV_WEBSOCKET_CONTROL_FRAME 114 /* struct websocket_message * */
4775 #endif
4776 
4777 #if MG_ENABLE_HTTP_STREAMING_MULTIPART
4778 #define MG_EV_HTTP_MULTIPART_REQUEST 121 /* struct http_message */
4779 #define MG_EV_HTTP_PART_BEGIN 122 /* struct mg_http_multipart_part */
4780 #define MG_EV_HTTP_PART_DATA 123 /* struct mg_http_multipart_part */
4781 #define MG_EV_HTTP_PART_END 124 /* struct mg_http_multipart_part */
4782 /* struct mg_http_multipart_part */
4783 #define MG_EV_HTTP_MULTIPART_REQUEST_END 125
4784 #endif
4785 
4786 /*
4787  * Attaches a built-in HTTP event handler to the given connection.
4788  * The user-defined event handler will receive following extra events:
4789  *
4790  * - MG_EV_HTTP_REQUEST: HTTP request has arrived. Parsed HTTP request
4791  * is passed as
4792  * `struct http_message` through the handler's `void *ev_data` pointer.
4793  * - MG_EV_HTTP_REPLY: The HTTP reply has arrived. The parsed HTTP reply is
4794  * passed as `struct http_message` through the handler's `void *ev_data`
4795  * pointer.
4796  * - MG_EV_HTTP_CHUNK: The HTTP chunked-encoding chunk has arrived.
4797  * The parsed HTTP reply is passed as `struct http_message` through the
4798  * handler's `void *ev_data` pointer. `http_message::body` would contain
4799  * incomplete, reassembled HTTP body.
4800  * It will grow with every new chunk that arrives, and it can
4801  * potentially consume a lot of memory. An event handler may process
4802  * the body as chunks are coming, and signal Mongoose to delete processed
4803  * body by setting `MG_F_DELETE_CHUNK` in `mg_connection::flags`. When
4804  * the last zero chunk is received,
4805  * Mongoose sends `MG_EV_HTTP_REPLY` event with
4806  * full reassembled body (if handler did not signal to delete chunks) or
4807  * with empty body (if handler did signal to delete chunks).
4808  * - MG_EV_WEBSOCKET_HANDSHAKE_REQUEST: server has received the WebSocket
4809  * handshake request. `ev_data` contains parsed HTTP request.
4810  * - MG_EV_WEBSOCKET_HANDSHAKE_DONE: server has completed the WebSocket
4811  * handshake. `ev_data` is `NULL`.
4812  * - MG_EV_WEBSOCKET_FRAME: new WebSocket frame has arrived. `ev_data` is
4813  * `struct websocket_message *`
4814  *
4815  * When compiled with MG_ENABLE_HTTP_STREAMING_MULTIPART, Mongoose parses
4816  * multipart requests and splits them into separate events:
4817  * - MG_EV_HTTP_MULTIPART_REQUEST: Start of the request.
4818  * This event is sent before body is parsed. After this, the user
4819  * should expect a sequence of PART_BEGIN/DATA/END requests.
4820  * This is also the last time when headers and other request fields are
4821  * accessible.
4822  * - MG_EV_HTTP_PART_BEGIN: Start of a part of a multipart message.
4823  * Argument: mg_http_multipart_part with var_name and file_name set
4824  * (if present). No data is passed in this message.
4825  * - MG_EV_HTTP_PART_DATA: new portion of data from the multipart message.
4826  * Argument: mg_http_multipart_part. var_name and file_name are preserved,
4827  * data is available in mg_http_multipart_part.data.
4828  * - MG_EV_HTTP_PART_END: End of the current part. var_name, file_name are
4829  * the same, no data in the message. If status is 0, then the part is
4830  * properly terminated with a boundary, status < 0 means that connection
4831  * was terminated.
4832  * - MG_EV_HTTP_MULTIPART_REQUEST_END: End of the multipart request.
4833  * Argument: mg_http_multipart_part, var_name and file_name are NULL,
4834  * status = 0 means request was properly closed, < 0 means connection
4835  * was terminated (note: in this case both PART_END and REQUEST_END are
4836  * delivered).
4837  */
4839 
4840 #if MG_ENABLE_HTTP_WEBSOCKET
4841 /*
4842  * Send websocket handshake to the server.
4843  *
4844  * `nc` must be a valid connection, connected to a server. `uri` is an URI
4845  * to fetch, extra_headers` is extra HTTP headers to send or `NULL`.
4846  *
4847  * This function is intended to be used by websocket client.
4848  *
4849  * Note that the Host header is mandatory in HTTP/1.1 and must be
4850  * included in `extra_headers`. `mg_send_websocket_handshake2` offers
4851  * a better API for that.
4852  *
4853  * Deprecated in favour of `mg_send_websocket_handshake2`
4854  */
4855 void mg_send_websocket_handshake(struct mg_connection *nc, const char *uri,
4856  const char *extra_headers);
4857 
4858 /*
4859  * Send websocket handshake to the server.
4860  *
4861  * `nc` must be a valid connection, connected to a server. `uri` is an URI
4862  * to fetch, `host` goes into the `Host` header, `protocol` goes into the
4863  * `Sec-WebSocket-Proto` header (NULL to omit), extra_headers` is extra HTTP
4864  * headers to send or `NULL`.
4865  *
4866  * This function is intended to be used by websocket client.
4867  */
4868 void mg_send_websocket_handshake2(struct mg_connection *nc, const char *path,
4869  const char *host, const char *protocol,
4870  const char *extra_headers);
4871 
4872 /* Like mg_send_websocket_handshake2 but also passes basic auth header */
4873 void mg_send_websocket_handshake3(struct mg_connection *nc, const char *path,
4874  const char *host, const char *protocol,
4875  const char *extra_headers, const char *user,
4876  const char *pass);
4877 
4878 /* Same as mg_send_websocket_handshake3 but with strings not necessarily
4879  * NUL-temrinated */
4881  const struct mg_str path,
4882  const struct mg_str host,
4883  const struct mg_str protocol,
4884  const struct mg_str extra_headers,
4885  const struct mg_str user,
4886  const struct mg_str pass);
4887 
4888 /*
4889  * Helper function that creates an outbound WebSocket connection.
4890  *
4891  * `url` is a URL to connect to. It must be properly URL-encoded, e.g. have
4892  * no spaces, etc. By default, `mg_connect_ws()` sends Connection and
4893  * Host headers. `extra_headers` is an extra HTTP header to send, e.g.
4894  * `"User-Agent: my-app\r\n"`.
4895  * If `protocol` is not NULL, then a `Sec-WebSocket-Protocol` header is sent.
4896  *
4897  * Examples:
4898  *
4899  * ```c
4900  * nc1 = mg_connect_ws(mgr, ev_handler_1, "ws://echo.websocket.org", NULL,
4901  * NULL);
4902  * nc2 = mg_connect_ws(mgr, ev_handler_1, "wss://echo.websocket.org", NULL,
4903  * NULL);
4904  * nc3 = mg_connect_ws(mgr, ev_handler_1, "ws://api.cesanta.com",
4905  * "clubby.cesanta.com", NULL);
4906  * ```
4907  */
4908 struct mg_connection *mg_connect_ws(struct mg_mgr *mgr,
4909  MG_CB(mg_event_handler_t event_handler,
4910  void *user_data),
4911  const char *url, const char *protocol,
4912  const char *extra_headers);
4913 
4914 /*
4915  * Helper function that creates an outbound WebSocket connection
4916  *
4917  * Mostly identical to `mg_connect_ws`, but allows to provide extra parameters
4918  * (for example, SSL parameters)
4919  */
4921  struct mg_mgr *mgr, MG_CB(mg_event_handler_t ev_handler, void *user_data),
4922  struct mg_connect_opts opts, const char *url, const char *protocol,
4923  const char *extra_headers);
4924 
4925 /*
4926  * Send WebSocket frame to the remote end.
4927  *
4928  * `op_and_flags` specifies the frame's type. It's one of:
4929  *
4930  * - WEBSOCKET_OP_CONTINUE
4931  * - WEBSOCKET_OP_TEXT
4932  * - WEBSOCKET_OP_BINARY
4933  * - WEBSOCKET_OP_CLOSE
4934  * - WEBSOCKET_OP_PING
4935  * - WEBSOCKET_OP_PONG
4936  *
4937  * Orred with one of the flags:
4938  *
4939  * - WEBSOCKET_DONT_FIN: Don't set the FIN flag on the frame to be sent.
4940  *
4941  * `data` and `data_len` contain frame data.
4942  */
4943 void mg_send_websocket_frame(struct mg_connection *nc, int op_and_flags,
4944  const void *data, size_t data_len);
4945 
4946 /*
4947  * Like `mg_send_websocket_frame()`, but composes a single frame from multiple
4948  * buffers.
4949  */
4950 void mg_send_websocket_framev(struct mg_connection *nc, int op_and_flags,
4951  const struct mg_str *strings, int num_strings);
4952 
4953 /*
4954  * Sends WebSocket frame to the remote end.
4955  *
4956  * Like `mg_send_websocket_frame()`, but allows to create formatted messages
4957  * with `printf()`-like semantics.
4958  */
4959 void mg_printf_websocket_frame(struct mg_connection *nc, int op_and_flags,
4960  const char *fmt, ...);
4961 
4962 /* Websocket opcodes, from http://tools.ietf.org/html/rfc6455 */
4963 #define WEBSOCKET_OP_CONTINUE 0
4964 #define WEBSOCKET_OP_TEXT 1
4965 #define WEBSOCKET_OP_BINARY 2
4966 #define WEBSOCKET_OP_CLOSE 8
4967 #define WEBSOCKET_OP_PING 9
4968 #define WEBSOCKET_OP_PONG 10
4969 
4970 /*
4971  * If set causes the FIN flag to not be set on outbound
4972  * frames. This enables sending multiple fragments of a single
4973  * logical message.
4974  *
4975  * The WebSocket protocol mandates that if the FIN flag of a data
4976  * frame is not set, the next frame must be a WEBSOCKET_OP_CONTINUE.
4977  * The last frame must have the FIN bit set.
4978  *
4979  * Note that mongoose will automatically defragment incoming messages,
4980  * so this flag is used only on outbound messages.
4981  */
4982 #define WEBSOCKET_DONT_FIN 0x100
4983 
4984 #endif /* MG_ENABLE_HTTP_WEBSOCKET */
4985 
4986 /*
4987  * Decodes a URL-encoded string.
4988  *
4989  * Source string is specified by (`src`, `src_len`), and destination is
4990  * (`dst`, `dst_len`). If `is_form_url_encoded` is non-zero, then
4991  * `+` character is decoded as a blank space character. This function
4992  * guarantees to NUL-terminate the destination. If destination is too small,
4993  * then the source string is partially decoded and `-1` is returned.
4994  *Otherwise,
4995  * a length of the decoded string is returned, not counting final NUL.
4996  */
4997 int mg_url_decode(const char *src, int src_len, char *dst, int dst_len,
4998  int is_form_url_encoded);
4999 
5000 extern void mg_hash_md5_v(size_t num_msgs, const uint8_t *msgs[],
5001  const size_t *msg_lens, uint8_t *digest);
5002 extern void mg_hash_sha1_v(size_t num_msgs, const uint8_t *msgs[],
5003  const size_t *msg_lens, uint8_t *digest);
5004 
5005 /*
5006  * Flags for `mg_http_is_authorized()`.
5007  */
5008 #define MG_AUTH_FLAG_IS_DIRECTORY (1 << 0)
5009 #define MG_AUTH_FLAG_IS_GLOBAL_PASS_FILE (1 << 1)
5010 #define MG_AUTH_FLAG_ALLOW_MISSING_FILE (1 << 2)
5011 
5012 /*
5013  * Checks whether an http request is authorized. `domain` is the authentication
5014  * realm, `passwords_file` is a htdigest file (can be created e.g. with
5015  * `htdigest` utility). If either `domain` or `passwords_file` is NULL, this
5016  * function always returns 1; otherwise checks the authentication in the
5017  * http request and returns 1 only if there is a match; 0 otherwise.
5018  */
5019 int mg_http_is_authorized(struct http_message *hm, struct mg_str path,
5020  const char *domain, const char *passwords_file,
5021  int flags);
5022 
5023 /*
5024  * Sends 401 Unauthorized response.
5025  */
5027  const char *domain);
5028 
5029 #ifdef __cplusplus
5030 }
5031 #endif /* __cplusplus */
5032 
5033 #endif /* MG_ENABLE_HTTP */
5034 
5035 #endif /* CS_MONGOOSE_SRC_HTTP_H_ */
5036 #ifdef MG_MODULE_LINES
5037 #line 1 "mongoose/src/mg_http_server.h"
5038 #endif
5039 /*
5040  * === Server API reference
5041  */
5042 
5043 #ifndef CS_MONGOOSE_SRC_HTTP_SERVER_H_
5044 #define CS_MONGOOSE_SRC_HTTP_SERVER_H_
5045 
5046 #if MG_ENABLE_HTTP
5047 
5048 #ifdef __cplusplus
5049 extern "C" {
5050 #endif /* __cplusplus */
5051 
5052 /*
5053  * Parses a HTTP message.
5054  *
5055  * `is_req` should be set to 1 if parsing a request, 0 if reply.
5056  *
5057  * Returns the number of bytes parsed. If HTTP message is
5058  * incomplete `0` is returned. On parse error, a negative number is returned.
5059  */
5060 int mg_parse_http(const char *s, int n, struct http_message *hm, int is_req);
5061 
5062 /*
5063  * Searches and returns the header `name` in parsed HTTP message `hm`.
5064  * If header is not found, NULL is returned. Example:
5065  *
5066  * struct mg_str *host_hdr = mg_get_http_header(hm, "Host");
5067  */
5068 struct mg_str *mg_get_http_header(struct http_message *hm, const char *name);
5069 
5070 /*
5071  * Parses the HTTP header `hdr`. Finds variable `var_name` and stores its value
5072  * in the buffer `*buf`, `buf_size`. If the buffer size is not enough,
5073  * allocates a buffer of required size and writes it to `*buf`, similar to
5074  * asprintf(). The caller should always check whether the buffer was updated,
5075  * and free it if so.
5076  *
5077  * This function is supposed to parse cookies, authentication headers, etc.
5078  * Example (error handling omitted):
5079  *
5080  * char user_buf[20];
5081  * char *user = user_buf;
5082  * struct mg_str *hdr = mg_get_http_header(hm, "Authorization");
5083  * mg_http_parse_header2(hdr, "username", &user, sizeof(user_buf));
5084  * // ... do something useful with user
5085  * if (user != user_buf) {
5086  * free(user);
5087  * }
5088  *
5089  * Returns the length of the variable's value. If variable is not found, 0 is
5090  * returned.
5091  */
5092 int mg_http_parse_header2(struct mg_str *hdr, const char *var_name, char **buf,
5093  size_t buf_size);
5094 
5095 /*
5096  * DEPRECATED: use mg_http_parse_header2() instead.
5097  *
5098  * Same as mg_http_parse_header2(), but takes buffer as a `char *` (instead of
5099  * `char **`), and thus it cannot allocate a new buffer if the provided one
5100  * is not enough, and just returns 0 in that case.
5101  */
5102 int mg_http_parse_header(struct mg_str *hdr, const char *var_name, char *buf,
5103  size_t buf_size)
5104 #ifdef __GNUC__
5105  __attribute__((deprecated))
5106 #endif
5107  ;
5108 
5109 /*
5110  * Gets and parses the Authorization: Basic header
5111  * Returns -1 if no Authorization header is found, or if
5112  * mg_parse_http_basic_auth
5113  * fails parsing the resulting header.
5114  */
5115 int mg_get_http_basic_auth(struct http_message *hm, char *user, size_t user_len,
5116  char *pass, size_t pass_len);
5117 
5118 /*
5119  * Parses the Authorization: Basic header
5120  * Returns -1 iif the authorization type is not "Basic" or any other error such
5121  * as incorrectly encoded base64 user password pair.
5122  */
5123 int mg_parse_http_basic_auth(struct mg_str *hdr, char *user, size_t user_len,
5124  char *pass, size_t pass_len);
5125 
5126 /*
5127  * Parses the buffer `buf`, `buf_len` that contains multipart form data chunks.
5128  * Stores the chunk name in a `var_name`, `var_name_len` buffer.
5129  * If a chunk is an uploaded file, then `file_name`, `file_name_len` is
5130  * filled with an uploaded file name. `chunk`, `chunk_len`
5131  * points to the chunk data.
5132  *
5133  * Return: number of bytes to skip to the next chunk or 0 if there are
5134  * no more chunks.
5135  *
5136  * Usage example:
5137  *
5138  * ```c
5139  * static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
5140  * switch(ev) {
5141  * case MG_EV_HTTP_REQUEST: {
5142  * struct http_message *hm = (struct http_message *) ev_data;
5143  * char var_name[100], file_name[100];
5144  * const char *chunk;
5145  * size_t chunk_len, n1, n2;
5146  *
5147  * n1 = n2 = 0;
5148  * while ((n2 = mg_parse_multipart(hm->body.p + n1,
5149  * hm->body.len - n1,
5150  * var_name, sizeof(var_name),
5151  * file_name, sizeof(file_name),
5152  * &chunk, &chunk_len)) > 0) {
5153  * printf("var: %s, file_name: %s, size: %d, chunk: [%.*s]\n",
5154  * var_name, file_name, (int) chunk_len,
5155  * (int) chunk_len, chunk);
5156  * n1 += n2;
5157  * }
5158  * }
5159  * break;
5160  * ```
5161  */
5162 size_t mg_parse_multipart(const char *buf, size_t buf_len, char *var_name,
5163  size_t var_name_len, char *file_name,
5164  size_t file_name_len, const char **chunk,
5165  size_t *chunk_len);
5166 
5167 /*
5168  * Fetches a HTTP form variable.
5169  *
5170  * Fetches a variable `name` from a `buf` into a buffer specified by `dst`,
5171  * `dst_len`. The destination is always zero-terminated. Returns the length of
5172  * a fetched variable. If not found, 0 is returned. `buf` must be valid
5173  * url-encoded buffer. If destination is too small or an error occured,
5174  * negative number is returned.
5175  */
5176 int mg_get_http_var(const struct mg_str *buf, const char *name, char *dst,
5177  size_t dst_len);
5178 
5179 #if MG_ENABLE_FILESYSTEM
5180 /*
5181  * This structure defines how `mg_serve_http()` works.
5182  * Best practice is to set only required settings, and leave the rest as NULL.
5183  */
5185  /* Path to web root directory */
5186  const char *document_root;
5187 
5188  /* List of index files. Default is "" */
5189  const char *index_files;
5190 
5191  /*
5192  * Leave as NULL to disable authentication.
5193  * To enable directory protection with authentication, set this to ".htpasswd"
5194  * Then, creating ".htpasswd" file in any directory automatically protects
5195  * it with digest authentication.
5196  * Use `mongoose` web server binary, or `htdigest` Apache utility to
5197  * create/manipulate passwords file.
5198  * Make sure `auth_domain` is set to a valid domain name.
5199  */
5201 
5202  /* Authorization domain (domain name of this web server) */
5203  const char *auth_domain;
5204 
5205  /*
5206  * Leave as NULL to disable authentication.
5207  * Normally, only selected directories in the document root are protected.
5208  * If absolutely every access to the web server needs to be authenticated,
5209  * regardless of the URI, set this option to the path to the passwords file.
5210  * Format of that file is the same as ".htpasswd" file. Make sure that file
5211  * is located outside document root to prevent people fetching it.
5212  */
5213  const char *global_auth_file;
5214 
5215  /* Set to "no" to disable directory listing. Enabled by default. */
5217 
5218  /*
5219  * SSI files pattern. If not set, "**.shtml$|**.shtm$" is used.
5220  *
5221  * All files that match ssi_pattern are treated as SSI.
5222  *
5223  * Server Side Includes (SSI) is a simple interpreted server-side scripting
5224  * language which is most commonly used to include the contents of a file
5225  * into a web page. It can be useful when it is desirable to include a common
5226  * piece of code throughout a website, for example, headers and footers.
5227  *
5228  * In order for a webpage to recognize an SSI-enabled HTML file, the
5229  * filename should end with a special extension, by default the extension
5230  * should be either .shtml or .shtm
5231  *
5232  * Unknown SSI directives are silently ignored by Mongoose. Currently,
5233  * the following SSI directives are supported:
5234  * &lt;!--#include FILE_TO_INCLUDE --&gt;
5235  * &lt;!--#exec "COMMAND_TO_EXECUTE" --&gt;
5236  * &lt;!--#call COMMAND --&gt;
5237  *
5238  * Note that &lt;!--#include ...> directive supports three path
5239  *specifications:
5240  *
5241  * &lt;!--#include virtual="path" --&gt; Path is relative to web server root
5242  * &lt;!--#include abspath="path" --&gt; Path is absolute or relative to the
5243  * web server working dir
5244  * &lt;!--#include file="path" --&gt;, Path is relative to current document
5245  * &lt;!--#include "path" --&gt;
5246  *
5247  * The include directive may be used to include the contents of a file or
5248  * the result of running a CGI script.
5249  *
5250  * The exec directive is used to execute
5251  * a command on a server, and show command's output. Example:
5252  *
5253  * &lt;!--#exec "ls -l" --&gt;
5254  *
5255  * The call directive is a way to invoke a C handler from the HTML page.
5256  * On each occurence of &lt;!--#call COMMAND OPTIONAL_PARAMS> directive,
5257  * Mongoose calls a registered event handler with MG_EV_SSI_CALL event,
5258  * and event parameter will point to the COMMAND OPTIONAL_PARAMS string.
5259  * An event handler can output any text, for example by calling
5260  * `mg_printf()`. This is a flexible way of generating a web page on
5261  * server side by calling a C event handler. Example:
5262  *
5263  * &lt;!--#call foo --&gt; ... &lt;!--#call bar --&gt;
5264  *
5265  * In the event handler:
5266  * case MG_EV_SSI_CALL: {
5267  * const char *param = (const char *) ev_data;
5268  * if (strcmp(param, "foo") == 0) {
5269  * mg_printf(c, "hello from foo");
5270  * } else if (strcmp(param, "bar") == 0) {
5271  * mg_printf(c, "hello from bar");
5272  * }
5273  * break;
5274  * }
5275  */
5276  const char *ssi_pattern;
5277 
5278  /* IP ACL. By default, NULL, meaning all IPs are allowed to connect */
5279  const char *ip_acl;
5280 
5281 #if MG_ENABLE_HTTP_URL_REWRITES
5282  /* URL rewrites.
5283  *
5284  * Comma-separated list of `uri_pattern=url_file_or_directory_path` rewrites.
5285  * When HTTP request is received, Mongoose constructs a file name from the
5286  * requested URI by combining `document_root` and the URI. However, if the
5287  * rewrite option is used and `uri_pattern` matches requested URI, then
5288  * `document_root` is ignored. Instead, `url_file_or_directory_path` is used,
5289  * which should be a full path name or a path relative to the web server's
5290  * current working directory. It can also be an URI (http:// or https://)
5291  * in which case mongoose will behave as a reverse proxy for that destination.
5292  *
5293  * Note that `uri_pattern`, as all Mongoose patterns, is a prefix pattern.
5294  *
5295  * If uri_pattern starts with `@` symbol, then Mongoose compares it with the
5296  * HOST header of the request. If they are equal, Mongoose sets document root
5297  * to `file_or_directory_path`, implementing virtual hosts support.
5298  * Example: `@foo.com=/document/root/for/foo.com`
5299  *
5300  * If `uri_pattern` starts with `%` symbol, then Mongoose compares it with
5301  * the listening port. If they match, then Mongoose issues a 301 redirect.
5302  * For example, to redirect all HTTP requests to the
5303  * HTTPS port, do `%80=https://my.site.com`. Note that the request URI is
5304  * automatically appended to the redirect location.
5305  */
5306  const char *url_rewrites;
5307 #endif
5308 
5309  /* DAV document root. If NULL, DAV requests are going to fail. */
5310  const char *dav_document_root;
5311 
5312  /*
5313  * DAV passwords file. If NULL, DAV requests are going to fail.
5314  * If passwords file is set to "-", then DAV auth is disabled.
5315  */
5316  const char *dav_auth_file;
5317 
5318  /* Glob pattern for the files to hide. */
5319  const char *hidden_file_pattern;
5320 
5321  /* Set to non-NULL to enable CGI, e.g. **.cgi$|**.php$" */
5322  const char *cgi_file_pattern;
5323 
5324  /* If not NULL, ignore CGI script hashbang and use this interpreter */
5325  const char *cgi_interpreter;
5326 
5327  /*
5328  * Comma-separated list of Content-Type overrides for path suffixes, e.g.
5329  * ".txt=text/plain; charset=utf-8,.c=text/plain"
5330  */
5331  const char *custom_mime_types;
5332 
5333  /*
5334  * Extra HTTP headers to add to each server response.
5335  * Example: to enable CORS, set this to "Access-Control-Allow-Origin: *".
5336  */
5337  const char *extra_headers;
5338 };
5339 
5340 /*
5341  * Serves given HTTP request according to the `options`.
5342  *
5343  * Example code snippet:
5344  *
5345  * ```c
5346  * static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
5347  * struct http_message *hm = (struct http_message *) ev_data;
5348  * struct mg_serve_http_opts opts = { .document_root = "/var/www" }; // C99
5349  *
5350  * switch (ev) {
5351  * case MG_EV_HTTP_REQUEST:
5352  * mg_serve_http(nc, hm, opts);
5353  * break;
5354  * default:
5355  * break;
5356  * }
5357  * }
5358  * ```
5359  */
5360 void mg_serve_http(struct mg_connection *nc, struct http_message *hm,
5361  struct mg_serve_http_opts opts);
5362 
5363 /*
5364  * Serves a specific file with a given MIME type and optional extra headers.
5365  *
5366  * Example code snippet:
5367  *
5368  * ```c
5369  * static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
5370  * switch (ev) {
5371  * case MG_EV_HTTP_REQUEST: {
5372  * struct http_message *hm = (struct http_message *) ev_data;
5373  * mg_http_serve_file(nc, hm, "file.txt",
5374  * mg_mk_str("text/plain"), mg_mk_str(""));
5375  * break;
5376  * }
5377  * ...
5378  * }
5379  * }
5380  * ```
5381  */
5382 void mg_http_serve_file(struct mg_connection *nc, struct http_message *hm,
5383  const char *path, const struct mg_str mime_type,
5384  const struct mg_str extra_headers);
5385 
5386 #if MG_ENABLE_HTTP_STREAMING_MULTIPART
5387 
5388 /* Callback prototype for `mg_file_upload_handler()`. */
5389 typedef struct mg_str (*mg_fu_fname_fn)(struct mg_connection *nc,
5390  struct mg_str fname);
5391 
5392 /*
5393  * File upload handler.
5394  * This handler can be used to implement file uploads with minimum code.
5395  * This handler will process MG_EV_HTTP_PART_* events and store file data into
5396  * a local file.
5397  * `local_name_fn` will be invoked with whatever name was provided by the client
5398  * and will expect the name of the local file to open. A return value of NULL
5399  * will abort file upload (client will get a "403 Forbidden" response). If
5400  * non-null, the returned string must be heap-allocated and will be freed by
5401  * the caller.
5402  * Exception: it is ok to return the same string verbatim.
5403  *
5404  * Example:
5405  *
5406  * ```c
5407  * struct mg_str upload_fname(struct mg_connection *nc, struct mg_str fname) {
5408  * // Just return the same filename. Do not actually do this except in test!
5409  * // fname is user-controlled and needs to be sanitized.
5410  * return fname;
5411  * }
5412  * void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
5413  * switch (ev) {
5414  * ...
5415  * case MG_EV_HTTP_PART_BEGIN:
5416  * case MG_EV_HTTP_PART_DATA:
5417  * case MG_EV_HTTP_PART_END:
5418  * mg_file_upload_handler(nc, ev, ev_data, upload_fname);
5419  * break;
5420  * }
5421  * }
5422  * ```
5423  */
5424 void mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data,
5425  mg_fu_fname_fn local_name_fn
5426  MG_UD_ARG(void *user_data));
5427 #endif /* MG_ENABLE_HTTP_STREAMING_MULTIPART */
5428 #endif /* MG_ENABLE_FILESYSTEM */
5429 
5430 /*
5431  * Registers a callback for a specified http endpoint
5432  * Note: if callback is registered it is called instead of the
5433  * callback provided in mg_bind
5434  *
5435  * Example code snippet:
5436  *
5437  * ```c
5438  * static void handle_hello1(struct mg_connection *nc, int ev, void *ev_data) {
5439  * (void) ev; (void) ev_data;
5440  * mg_printf(nc, "HTTP/1.0 200 OK\r\n\r\n[I am Hello1]");
5441  * nc->flags |= MG_F_SEND_AND_CLOSE;
5442  * }
5443  *
5444  * static void handle_hello2(struct mg_connection *nc, int ev, void *ev_data) {
5445  * (void) ev; (void) ev_data;
5446  * mg_printf(nc, "HTTP/1.0 200 OK\r\n\r\n[I am Hello2]");
5447  * nc->flags |= MG_F_SEND_AND_CLOSE;
5448  * }
5449  *
5450  * void init() {
5451  * nc = mg_bind(&mgr, local_addr, cb1);
5452  * mg_register_http_endpoint(nc, "/hello1", handle_hello1);
5453  * mg_register_http_endpoint(nc, "/hello1/hello2", handle_hello2);
5454  * }
5455  * ```
5456  */
5457 void mg_register_http_endpoint(struct mg_connection *nc, const char *uri_path,
5458  MG_CB(mg_event_handler_t handler,
5459  void *user_data));
5460 
5462  void *user_data;
5463  /* Authorization domain (realm) */
5464  const char *auth_domain;
5465  const char *auth_file;
5466 };
5467 
5469  const char *uri_path,
5470  mg_event_handler_t handler,
5471  struct mg_http_endpoint_opts opts);
5472 
5473 /*
5474  * Authenticates a HTTP request against an opened password file.
5475  * Returns 1 if authenticated, 0 otherwise.
5476  */
5477 int mg_http_check_digest_auth(struct http_message *hm, const char *auth_domain,
5478  FILE *fp);
5479 
5480 /*
5481  * Authenticates given response params against an opened password file.
5482  * Returns 1 if authenticated, 0 otherwise.
5483  *
5484  * It's used by mg_http_check_digest_auth().
5485  */
5486 int mg_check_digest_auth(struct mg_str method, struct mg_str uri,
5487  struct mg_str username, struct mg_str cnonce,
5488  struct mg_str response, struct mg_str qop,
5489  struct mg_str nc, struct mg_str nonce,
5490  struct mg_str auth_domain, FILE *fp);
5491 
5492 /*
5493  * Sends buffer `buf` of size `len` to the client using chunked HTTP encoding.
5494  * This function sends the buffer size as hex number + newline first, then
5495  * the buffer itself, then the newline. For example,
5496  * `mg_send_http_chunk(nc, "foo", 3)` will append the `3\r\nfoo\r\n` string
5497  * to the `nc->send_mbuf` output IO buffer.
5498  *
5499  * NOTE: The HTTP header "Transfer-Encoding: chunked" should be sent prior to
5500  * using this function.
5501  *
5502  * NOTE: do not forget to send an empty chunk at the end of the response,
5503  * to tell the client that everything was sent. Example:
5504  *
5505  * ```
5506  * mg_printf_http_chunk(nc, "%s", "my response!");
5507  * mg_send_http_chunk(nc, "", 0); // Tell the client we're finished
5508  * ```
5509  */
5510 void mg_send_http_chunk(struct mg_connection *nc, const char *buf, size_t len);
5511 
5512 /*
5513  * Sends a printf-formatted HTTP chunk.
5514  * Functionality is similar to `mg_send_http_chunk()`.
5515  */
5516 void mg_printf_http_chunk(struct mg_connection *nc, const char *fmt, ...);
5517 
5518 /*
5519  * Sends the response status line.
5520  * If `extra_headers` is not NULL, then `extra_headers` are also sent
5521  * after the response line. `extra_headers` must NOT end end with new line.
5522  * Example:
5523  *
5524  * mg_send_response_line(nc, 200, "Access-Control-Allow-Origin: *");
5525  *
5526  * Will result in:
5527  *
5528  * HTTP/1.1 200 OK\r\n
5529  * Access-Control-Allow-Origin: *\r\n
5530  */
5531 void mg_send_response_line(struct mg_connection *nc, int status_code,
5532  const char *extra_headers);
5533 
5534 /*
5535  * Sends an error response. If reason is NULL, the message will be inferred
5536  * from the error code (if supported).
5537  */
5538 void mg_http_send_error(struct mg_connection *nc, int code, const char *reason);
5539 
5540 /*
5541  * Sends a redirect response.
5542  * `status_code` should be either 301 or 302 and `location` point to the
5543  * new location.
5544  * If `extra_headers` is not empty, then `extra_headers` are also sent
5545  * after the response line. `extra_headers` must NOT end end with new line.
5546  *
5547  * Example:
5548  *
5549  * mg_http_send_redirect(nc, 302, mg_mk_str("/login"), mg_mk_str(NULL));
5550  */
5551 void mg_http_send_redirect(struct mg_connection *nc, int status_code,
5552  const struct mg_str location,
5553  const struct mg_str extra_headers);
5554 
5555 /*
5556  * Sends the response line and headers.
5557  * This function sends the response line with the `status_code`, and
5558  * automatically
5559  * sends one header: either "Content-Length" or "Transfer-Encoding".
5560  * If `content_length` is negative, then "Transfer-Encoding: chunked" header
5561  * is sent, otherwise, "Content-Length" header is sent.
5562  *
5563  * NOTE: If `Transfer-Encoding` is `chunked`, then message body must be sent
5564  * using `mg_send_http_chunk()` or `mg_printf_http_chunk()` functions.
5565  * Otherwise, `mg_send()` or `mg_printf()` must be used.
5566  * Extra headers could be set through `extra_headers`. Note `extra_headers`
5567  * must NOT be terminated by a new line.
5568  */
5569 void mg_send_head(struct mg_connection *n, int status_code,
5570  int64_t content_length, const char *extra_headers);
5571 
5572 /*
5573  * Sends a printf-formatted HTTP chunk, escaping HTML tags.
5574  */
5575 void mg_printf_html_escape(struct mg_connection *nc, const char *fmt, ...);
5576 
5577 #if MG_ENABLE_HTTP_URL_REWRITES
5578 /*
5579  * Proxies a given request to a given upstream http server. The path prefix
5580  * in `mount` will be stripped of the path requested to the upstream server,
5581  * e.g. if mount is /api and upstream is http://localhost:8001/foo
5582  * then an incoming request to /api/bar will cause a request to
5583  * http://localhost:8001/foo/bar
5584  *
5585  * EXPERIMENTAL API. Please use http_serve_http + url_rewrites if a static
5586  * mapping is good enough.
5587  */
5588 void mg_http_reverse_proxy(struct mg_connection *nc,
5589  const struct http_message *hm, struct mg_str mount,
5590  struct mg_str upstream);
5591 #endif
5592 
5593 #ifdef __cplusplus
5594 }
5595 #endif /* __cplusplus */
5596 
5597 #endif /* MG_ENABLE_HTTP */
5598 
5599 #endif /* CS_MONGOOSE_SRC_HTTP_SERVER_H_ */
5600 #ifdef MG_MODULE_LINES
5601 #line 1 "mongoose/src/mg_http_client.h"
5602 #endif
5603 /*
5604  * === Client API reference
5605  */
5606 
5607 #ifndef CS_MONGOOSE_SRC_HTTP_CLIENT_H_
5608 #define CS_MONGOOSE_SRC_HTTP_CLIENT_H_
5609 
5610 #ifdef __cplusplus
5611 extern "C" {
5612 #endif /* __cplusplus */
5613 
5614 /*
5615  * Helper function that creates an outbound HTTP connection.
5616  *
5617  * `url` is the URL to fetch. It must be properly URL-encoded, e.g. have
5618  * no spaces, etc. By default, `mg_connect_http()` sends the Connection and
5619  * Host headers. `extra_headers` is an extra HTTP header to send, e.g.
5620  * `"User-Agent: my-app\r\n"`.
5621  * If `post_data` is NULL, then a GET request is created. Otherwise, a POST
5622  * request is created with the specified POST data. Note that if the data being
5623  * posted is a form submission, the `Content-Type` header should be set
5624  * accordingly (see example below).
5625  *
5626  * Examples:
5627  *
5628  * ```c
5629  * nc1 = mg_connect_http(mgr, ev_handler_1, "http://www.google.com", NULL,
5630  * NULL);
5631  * nc2 = mg_connect_http(mgr, ev_handler_1, "https://github.com", NULL, NULL);
5632  * nc3 = mg_connect_http(
5633  * mgr, ev_handler_1, "my_server:8000/form_submit/",
5634  * "Content-Type: application/x-www-form-urlencoded\r\n",
5635  * "var_1=value_1&var_2=value_2");
5636  * ```
5637  */
5639  struct mg_mgr *mgr,
5640  MG_CB(mg_event_handler_t event_handler, void *user_data), const char *url,
5641  const char *extra_headers, const char *post_data);
5642 
5643 /*
5644  * Helper function that creates an outbound HTTP connection.
5645  *
5646  * Mostly identical to mg_connect_http, but allows you to provide extra
5647  *parameters
5648  * (for example, SSL parameters)
5649  */
5651  struct mg_mgr *mgr, MG_CB(mg_event_handler_t ev_handler, void *user_data),
5652  struct mg_connect_opts opts, const char *url, const char *extra_headers,
5653  const char *post_data);
5654 
5655 /* Creates digest authentication header for a client request. */
5656 int mg_http_create_digest_auth_header(char *buf, size_t buf_len,
5657  const char *method, const char *uri,
5658  const char *auth_domain, const char *user,
5659  const char *passwd, const char *nonce);
5660 
5661 #ifdef __cplusplus
5662 }
5663 #endif /* __cplusplus */
5664 #endif /* CS_MONGOOSE_SRC_HTTP_CLIENT_H_ */
5665 #ifdef MG_MODULE_LINES
5666 #line 1 "mongoose/src/mg_mqtt.h"
5667 #endif
5668 /*
5669  * Copyright (c) 2014 Cesanta Software Limited
5670  * All rights reserved
5671  * This software is dual-licensed: you can redistribute it and/or modify
5672  * it under the terms of the GNU General Public License version 2 as
5673  * published by the Free Software Foundation. For the terms of this
5674  * license, see <http://www.gnu.org/licenses/>.
5675  *
5676  * You are free to use this software under the terms of the GNU General
5677  * Public License, but WITHOUT ANY WARRANTY; without even the implied
5678  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5679  * See the GNU General Public License for more details.
5680  *
5681  * Alternatively, you can license this software under a commercial
5682  * license, as set out in <https://www.cesanta.com/license>.
5683  */
5684 
5685 /*
5686  * === MQTT API reference
5687  */
5688 
5689 #ifndef CS_MONGOOSE_SRC_MQTT_H_
5690 #define CS_MONGOOSE_SRC_MQTT_H_
5691 
5692 /* Amalgamated: #include "mg_net.h" */
5693 
5695  int cmd;
5696  int qos;
5697  int len; /* message length in the IO buffer */
5698  struct mg_str topic;
5699  struct mg_str payload;
5700 
5701  uint8_t connack_ret_code; /* connack */
5702  uint16_t message_id; /* puback */
5703 
5704  /* connect */
5706  uint8_t connect_flags;
5708  struct mg_str protocol_name;
5709  struct mg_str client_id;
5710  struct mg_str will_topic;
5711  struct mg_str will_message;
5712  struct mg_str user_name;
5713  struct mg_str password;
5714 };
5715 
5717  const char *topic;
5718  uint8_t qos;
5719 };
5720 
5722  unsigned char flags; /* connection flags */
5723  uint16_t keep_alive;
5724  const char *will_topic;
5725  const char *will_message;
5726  const char *user_name;
5727  const char *password;
5728 };
5729 
5730 /* mg_mqtt_proto_data should be in header to allow external access to it */
5732  uint16_t keep_alive;
5734 };
5735 
5736 /* Message types */
5737 #define MG_MQTT_CMD_CONNECT 1
5738 #define MG_MQTT_CMD_CONNACK 2
5739 #define MG_MQTT_CMD_PUBLISH 3
5740 #define MG_MQTT_CMD_PUBACK 4
5741 #define MG_MQTT_CMD_PUBREC 5
5742 #define MG_MQTT_CMD_PUBREL 6
5743 #define MG_MQTT_CMD_PUBCOMP 7
5744 #define MG_MQTT_CMD_SUBSCRIBE 8
5745 #define MG_MQTT_CMD_SUBACK 9
5746 #define MG_MQTT_CMD_UNSUBSCRIBE 10
5747 #define MG_MQTT_CMD_UNSUBACK 11
5748 #define MG_MQTT_CMD_PINGREQ 12
5749 #define MG_MQTT_CMD_PINGRESP 13
5750 #define MG_MQTT_CMD_DISCONNECT 14
5751 
5752 /* MQTT event types */
5753 #define MG_MQTT_EVENT_BASE 200
5754 #define MG_EV_MQTT_CONNECT (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_CONNECT)
5755 #define MG_EV_MQTT_CONNACK (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_CONNACK)
5756 #define MG_EV_MQTT_PUBLISH (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PUBLISH)
5757 #define MG_EV_MQTT_PUBACK (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PUBACK)
5758 #define MG_EV_MQTT_PUBREC (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PUBREC)
5759 #define MG_EV_MQTT_PUBREL (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PUBREL)
5760 #define MG_EV_MQTT_PUBCOMP (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PUBCOMP)
5761 #define MG_EV_MQTT_SUBSCRIBE (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_SUBSCRIBE)
5762 #define MG_EV_MQTT_SUBACK (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_SUBACK)
5763 #define MG_EV_MQTT_UNSUBSCRIBE (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_UNSUBSCRIBE)
5764 #define MG_EV_MQTT_UNSUBACK (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_UNSUBACK)
5765 #define MG_EV_MQTT_PINGREQ (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PINGREQ)
5766 #define MG_EV_MQTT_PINGRESP (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PINGRESP)
5767 #define MG_EV_MQTT_DISCONNECT (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_DISCONNECT)
5768 
5769 /* Message flags */
5770 #define MG_MQTT_RETAIN 0x1
5771 #define MG_MQTT_DUP 0x4
5772 #define MG_MQTT_QOS(qos) ((qos) << 1)
5773 #define MG_MQTT_GET_QOS(flags) (((flags) &0x6) >> 1)
5774 #define MG_MQTT_SET_QOS(flags, qos) (flags) = ((flags) & ~0x6) | ((qos) << 1)
5775 
5776 /* Connection flags */
5777 #define MG_MQTT_CLEAN_SESSION 0x02
5778 #define MG_MQTT_HAS_WILL 0x04
5779 #define MG_MQTT_WILL_RETAIN 0x20
5780 #define MG_MQTT_HAS_PASSWORD 0x40
5781 #define MG_MQTT_HAS_USER_NAME 0x80
5782 #define MG_MQTT_GET_WILL_QOS(flags) (((flags) &0x18) >> 3)
5783 #define MG_MQTT_SET_WILL_QOS(flags, qos) \
5784  (flags) = ((flags) & ~0x18) | ((qos) << 3)
5785 
5786 /* CONNACK return codes */
5787 #define MG_EV_MQTT_CONNACK_ACCEPTED 0
5788 #define MG_EV_MQTT_CONNACK_UNACCEPTABLE_VERSION 1
5789 #define MG_EV_MQTT_CONNACK_IDENTIFIER_REJECTED 2
5790 #define MG_EV_MQTT_CONNACK_SERVER_UNAVAILABLE 3
5791 #define MG_EV_MQTT_CONNACK_BAD_AUTH 4
5792 #define MG_EV_MQTT_CONNACK_NOT_AUTHORIZED 5
5793 
5794 #ifdef __cplusplus
5795 extern "C" {
5796 #endif /* __cplusplus */
5797 
5798 /*
5799  * Attaches a built-in MQTT event handler to the given connection.
5800  *
5801  * The user-defined event handler will receive following extra events:
5802  *
5803  * - MG_EV_MQTT_CONNACK
5804  * - MG_EV_MQTT_PUBLISH
5805  * - MG_EV_MQTT_PUBACK
5806  * - MG_EV_MQTT_PUBREC
5807  * - MG_EV_MQTT_PUBREL
5808  * - MG_EV_MQTT_PUBCOMP
5809  * - MG_EV_MQTT_SUBACK
5810  */
5811 void mg_set_protocol_mqtt(struct mg_connection *nc);
5812 
5813 /* Sends an MQTT handshake. */
5814 void mg_send_mqtt_handshake(struct mg_connection *nc, const char *client_id);
5815 
5816 /* Sends an MQTT handshake with optional parameters. */
5817 void mg_send_mqtt_handshake_opt(struct mg_connection *nc, const char *client_id,
5819 
5820 /* Publishes a message to a given topic. */
5821 void mg_mqtt_publish(struct mg_connection *nc, const char *topic,
5822  uint16_t message_id, int flags, const void *data,
5823  size_t len);
5824 
5825 /* Subscribes to a bunch of topics. */
5826 void mg_mqtt_subscribe(struct mg_connection *nc,
5827  const struct mg_mqtt_topic_expression *topics,
5828  size_t topics_len, uint16_t message_id);
5829 
5830 /* Unsubscribes from a bunch of topics. */
5831 void mg_mqtt_unsubscribe(struct mg_connection *nc, char **topics,
5832  size_t topics_len, uint16_t message_id);
5833 
5834 /* Sends a DISCONNECT command. */
5835 void mg_mqtt_disconnect(struct mg_connection *nc);
5836 
5837 /* Sends a CONNACK command with a given `return_code`. */
5838 void mg_mqtt_connack(struct mg_connection *nc, uint8_t return_code);
5839 
5840 /* Sends a PUBACK command with a given `message_id`. */
5841 void mg_mqtt_puback(struct mg_connection *nc, uint16_t message_id);
5842 
5843 /* Sends a PUBREC command with a given `message_id`. */
5844 void mg_mqtt_pubrec(struct mg_connection *nc, uint16_t message_id);
5845 
5846 /* Sends a PUBREL command with a given `message_id`. */
5847 void mg_mqtt_pubrel(struct mg_connection *nc, uint16_t message_id);
5848 
5849 /* Sends a PUBCOMP command with a given `message_id`. */
5850 void mg_mqtt_pubcomp(struct mg_connection *nc, uint16_t message_id);
5851 
5852 /*
5853  * Sends a SUBACK command with a given `message_id`
5854  * and a sequence of granted QoSs.
5855  */
5856 void mg_mqtt_suback(struct mg_connection *nc, uint8_t *qoss, size_t qoss_len,
5857  uint16_t message_id);
5858 
5859 /* Sends a UNSUBACK command with a given `message_id`. */
5860 void mg_mqtt_unsuback(struct mg_connection *nc, uint16_t message_id);
5861 
5862 /* Sends a PINGREQ command. */
5863 void mg_mqtt_ping(struct mg_connection *nc);
5864 
5865 /* Sends a PINGRESP command. */
5866 void mg_mqtt_pong(struct mg_connection *nc);
5867 
5868 /*
5869  * Extracts the next topic expression from a SUBSCRIBE command payload.
5870  *
5871  * The topic expression name will point to a string in the payload buffer.
5872  * Returns the pos of the next topic expression or -1 when the list
5873  * of topics is exhausted.
5874  */
5876  struct mg_str *topic, uint8_t *qos, int pos);
5877 
5878 /*
5879  * Matches a topic against a topic expression
5880  *
5881  * Returns 1 if it matches; 0 otherwise.
5882  */
5883 int mg_mqtt_match_topic_expression(struct mg_str exp, struct mg_str topic);
5884 
5885 /*
5886  * Same as `mg_mqtt_match_topic_expression()`, but takes `exp` as a
5887  * NULL-terminated string.
5888  */
5889 int mg_mqtt_vmatch_topic_expression(const char *exp, struct mg_str topic);
5890 
5891 #ifdef __cplusplus
5892 }
5893 #endif /* __cplusplus */
5894 
5895 #endif /* CS_MONGOOSE_SRC_MQTT_H_ */
5896 #ifdef MG_MODULE_LINES
5897 #line 1 "mongoose/src/mg_mqtt_server.h"
5898 #endif
5899 /*
5900  * Copyright (c) 2014 Cesanta Software Limited
5901  * All rights reserved
5902  * This software is dual-licensed: you can redistribute it and/or modify
5903  * it under the terms of the GNU General Public License version 2 as
5904  * published by the Free Software Foundation. For the terms of this
5905  * license, see <http://www.gnu.org/licenses/>.
5906  *
5907  * You are free to use this software under the terms of the GNU General
5908  * Public License, but WITHOUT ANY WARRANTY; without even the implied
5909  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5910  * See the GNU General Public License for more details.
5911  *
5912  * Alternatively, you can license this software under a commercial
5913  * license, as set out in <https://www.cesanta.com/license>.
5914  */
5915 
5916 /*
5917  * === MQTT Server API reference
5918  */
5919 
5920 #ifndef CS_MONGOOSE_SRC_MQTT_BROKER_H_
5921 #define CS_MONGOOSE_SRC_MQTT_BROKER_H_
5922 
5923 #if MG_ENABLE_MQTT_BROKER
5924 
5925 /* Amalgamated: #include "common/queue.h" */
5926 /* Amalgamated: #include "mg_mqtt.h" */
5927 
5928 #ifdef __cplusplus
5929 extern "C" {
5930 #endif /* __cplusplus */
5931 
5932 #ifndef MG_MQTT_MAX_SESSION_SUBSCRIPTIONS
5933 #define MG_MQTT_MAX_SESSION_SUBSCRIPTIONS 512
5934 #endif
5935 
5936 struct mg_mqtt_broker;
5937 
5938 /* MQTT session (Broker side). */
5940  struct mg_mqtt_broker *brk; /* Broker */
5941  LIST_ENTRY(mg_mqtt_session) link; /* mg_mqtt_broker::sessions linkage */
5942  struct mg_connection *nc; /* Connection with the client */
5943  size_t num_subscriptions; /* Size of `subscriptions` array */
5944  void *user_data; /* User data */
5946 };
5947 
5948 /* MQTT broker. */
5950  LIST_HEAD(_mg_sesshead, mg_mqtt_session) sessions; /* Session list */
5951  void *user_data; /* User data */
5952 };
5953 
5954 /* Initialises a MQTT broker. */
5955 void mg_mqtt_broker_init(struct mg_mqtt_broker *brk, void *user_data);
5956 
5957 /*
5958  * Processes a MQTT broker message.
5959  *
5960  * The listening connection expects a pointer to an initialised
5961  * `mg_mqtt_broker` structure in the `user_data` field.
5962  *
5963  * Basic usage:
5964  *
5965  * ```c
5966  * mg_mqtt_broker_init(&brk, NULL);
5967  *
5968  * if ((nc = mg_bind(&mgr, address, mg_mqtt_broker)) == NULL) {
5969  * // fail;
5970  * }
5971  * nc->user_data = &brk;
5972  * ```
5973  *
5974  * New incoming connections will receive a `mg_mqtt_session` structure
5975  * in the connection `user_data`. The original `user_data` will be stored
5976  * in the `user_data` field of the session structure. This allows the user
5977  * handler to store user data before `mg_mqtt_broker` creates the session.
5978  *
5979  * Since only the MG_EV_ACCEPT message is processed by the listening socket,
5980  * for most events the `user_data` will thus point to a `mg_mqtt_session`.
5981  */
5982 void mg_mqtt_broker(struct mg_connection *brk, int ev, void *data);
5983 
5984 /*
5985  * Iterates over all MQTT session connections. Example:
5986  *
5987  * ```c
5988  * struct mg_mqtt_session *s;
5989  * for (s = mg_mqtt_next(brk, NULL); s != NULL; s = mg_mqtt_next(brk, s)) {
5990  * // Do something
5991  * }
5992  * ```
5993  */
5995  struct mg_mqtt_session *s);
5996 
5997 #ifdef __cplusplus
5998 }
5999 #endif /* __cplusplus */
6000 
6001 #endif /* MG_ENABLE_MQTT_BROKER */
6002 #endif /* CS_MONGOOSE_SRC_MQTT_BROKER_H_ */
6003 #ifdef MG_MODULE_LINES
6004 #line 1 "mongoose/src/mg_dns.h"
6005 #endif
6006 /*
6007  * Copyright (c) 2014 Cesanta Software Limited
6008  * All rights reserved
6009  */
6010 
6011 /*
6012  * === DNS API reference
6013  */
6014 
6015 #ifndef CS_MONGOOSE_SRC_DNS_H_
6016 #define CS_MONGOOSE_SRC_DNS_H_
6017 
6018 /* Amalgamated: #include "mg_net.h" */
6019 
6020 #ifdef __cplusplus
6021 extern "C" {
6022 #endif /* __cplusplus */
6023 
6024 #define MG_DNS_A_RECORD 0x01 /* Lookup IP address */
6025 #define MG_DNS_CNAME_RECORD 0x05 /* Lookup CNAME */
6026 #define MG_DNS_PTR_RECORD 0x0c /* Lookup PTR */
6027 #define MG_DNS_TXT_RECORD 0x10 /* Lookup TXT */
6028 #define MG_DNS_AAAA_RECORD 0x1c /* Lookup IPv6 address */
6029 #define MG_DNS_SRV_RECORD 0x21 /* Lookup SRV */
6030 #define MG_DNS_MX_RECORD 0x0f /* Lookup mail server for domain */
6031 #define MG_DNS_ANY_RECORD 0xff
6032 #define MG_DNS_NSEC_RECORD 0x2f
6033 
6034 #define MG_MAX_DNS_QUESTIONS 32
6035 #define MG_MAX_DNS_ANSWERS 32
6036 
6037 #define MG_DNS_MESSAGE 100 /* High-level DNS message event */
6038 
6043 };
6044 
6045 /* DNS resource record. */
6047  struct mg_str name; /* buffer with compressed name */
6048  int rtype;
6049  int rclass;
6050  int ttl;
6052  struct mg_str rdata; /* protocol data (can be a compressed name) */
6053 };
6054 
6055 /* DNS message (request and response). */
6057  struct mg_str pkt; /* packet body */
6058  uint16_t flags;
6059  uint16_t transaction_id;
6062  struct mg_dns_resource_record questions[MG_MAX_DNS_QUESTIONS];
6063  struct mg_dns_resource_record answers[MG_MAX_DNS_ANSWERS];
6064 };
6065 
6067  struct mg_dns_message *msg, int query, struct mg_dns_resource_record *prev);
6068 
6069 /*
6070  * Parses the record data from a DNS resource record.
6071  *
6072  * - A: struct in_addr *ina
6073  * - AAAA: struct in6_addr *ina
6074  * - CNAME: char buffer
6075  *
6076  * Returns -1 on error.
6077  *
6078  * TODO(mkm): MX
6079  */
6081  struct mg_dns_resource_record *rr, void *data,
6082  size_t data_len);
6083 
6084 /*
6085  * Sends a DNS query to the remote end.
6086  */
6087 void mg_send_dns_query(struct mg_connection *nc, const char *name,
6088  int query_type);
6089 
6090 /*
6091  * Inserts a DNS header to an IO buffer.
6092  *
6093  * Returns the number of bytes inserted.
6094  */
6095 int mg_dns_insert_header(struct mbuf *io, size_t pos,
6096  struct mg_dns_message *msg);
6097 
6098 /*
6099  * Appends already encoded questions from an existing message.
6100  *
6101  * This is useful when generating a DNS reply message which includes
6102  * all question records.
6103  *
6104  * Returns the number of appended bytes.
6105  */
6106 int mg_dns_copy_questions(struct mbuf *io, struct mg_dns_message *msg);
6107 
6108 /*
6109  * Encodes and appends a DNS resource record to an IO buffer.
6110  *
6111  * The record metadata is taken from the `rr` parameter, while the name and data
6112  * are taken from the parameters, encoded in the appropriate format depending on
6113  * record type and stored in the IO buffer. The encoded values might contain
6114  * offsets within the IO buffer. It's thus important that the IO buffer doesn't
6115  * get trimmed while a sequence of records are encoded while preparing a DNS
6116  * reply.
6117  *
6118  * This function doesn't update the `name` and `rdata` pointers in the `rr`
6119  * struct because they might be invalidated as soon as the IO buffer grows
6120  * again.
6121  *
6122  * Returns the number of bytes appended or -1 in case of error.
6123  */
6124 int mg_dns_encode_record(struct mbuf *io, struct mg_dns_resource_record *rr,
6125  const char *name, size_t nlen, const void *rdata,
6126  size_t rlen);
6127 
6128 /*
6129  * Encodes a DNS name.
6130  */
6131 int mg_dns_encode_name(struct mbuf *io, const char *name, size_t len);
6132 
6133 /* Low-level: parses a DNS response. */
6134 int mg_parse_dns(const char *buf, int len, struct mg_dns_message *msg);
6135 
6136 /*
6137  * Uncompresses a DNS compressed name.
6138  *
6139  * The containing DNS message is required because of the compressed encoding
6140  * and reference suffixes present elsewhere in the packet.
6141  *
6142  * If the name is less than `dst_len` characters long, the remainder
6143  * of `dst` is terminated with `\0` characters. Otherwise, `dst` is not
6144  * terminated.
6145  *
6146  * If `dst_len` is 0 `dst` can be NULL.
6147  * Returns the uncompressed name length.
6148  */
6149 size_t mg_dns_uncompress_name(struct mg_dns_message *msg, struct mg_str *name,
6150  char *dst, int dst_len);
6151 
6152 /*
6153  * Attaches a built-in DNS event handler to the given listening connection.
6154  *
6155  * The DNS event handler parses the incoming UDP packets, treating them as DNS
6156  * requests. If an incoming packet gets successfully parsed by the DNS event
6157  * handler, a user event handler will receive an `MG_DNS_REQUEST` event, with
6158  * `ev_data` pointing to the parsed `struct mg_dns_message`.
6159  *
6160  * See
6161  * [captive_dns_server](https://github.com/cesanta/mongoose/tree/master/examples/captive_dns_server)
6162  * example on how to handle DNS request and send DNS reply.
6163  */
6164 void mg_set_protocol_dns(struct mg_connection *nc);
6165 
6166 #ifdef __cplusplus
6167 }
6168 #endif /* __cplusplus */
6169 #endif /* CS_MONGOOSE_SRC_DNS_H_ */
6170 #ifdef MG_MODULE_LINES
6171 #line 1 "mongoose/src/mg_dns_server.h"
6172 #endif
6173 /*
6174  * Copyright (c) 2014 Cesanta Software Limited
6175  * All rights reserved
6176  */
6177 
6178 /*
6179  * === DNS server API reference
6180  *
6181  * Disabled by default; enable with `-DMG_ENABLE_DNS_SERVER`.
6182  */
6183 
6184 #ifndef CS_MONGOOSE_SRC_DNS_SERVER_H_
6185 #define CS_MONGOOSE_SRC_DNS_SERVER_H_
6186 
6187 #if MG_ENABLE_DNS_SERVER
6188 
6189 /* Amalgamated: #include "mg_dns.h" */
6190 
6191 #ifdef __cplusplus
6192 extern "C" {
6193 #endif /* __cplusplus */
6194 
6195 #define MG_DNS_SERVER_DEFAULT_TTL 3600
6196 
6199  struct mbuf *io;
6200  size_t start;
6201 };
6202 
6203 /*
6204  * Creates a DNS reply.
6205  *
6206  * The reply will be based on an existing query message `msg`.
6207  * The query body will be appended to the output buffer.
6208  * "reply + recursion allowed" will be added to the message flags and the
6209  * message's num_answers will be set to 0.
6210  *
6211  * Answer records can be appended with `mg_dns_send_reply` or by lower
6212  * level function defined in the DNS API.
6213  *
6214  * In order to send a reply use `mg_dns_send_reply`.
6215  * It's possible to use a connection's send buffer as reply buffer,
6216  * and it will work for both UDP and TCP connections.
6217  *
6218  * Example:
6219  *
6220  * ```c
6221  * reply = mg_dns_create_reply(&nc->send_mbuf, msg);
6222  * for (i = 0; i < msg->num_questions; i++) {
6223  * rr = &msg->questions[i];
6224  * if (rr->rtype == MG_DNS_A_RECORD) {
6225  * mg_dns_reply_record(&reply, rr, 3600, &dummy_ip_addr, 4);
6226  * }
6227  * }
6228  * mg_dns_send_reply(nc, &reply);
6229  * ```
6230  */
6231 struct mg_dns_reply mg_dns_create_reply(struct mbuf *io,
6232  struct mg_dns_message *msg);
6233 
6234 /*
6235  * Appends a DNS reply record to the IO buffer and to the DNS message.
6236  *
6237  * The message's num_answers field will be incremented. It's the caller's duty
6238  * to ensure num_answers is properly initialised.
6239  *
6240  * Returns -1 on error.
6241  */
6242 int mg_dns_reply_record(struct mg_dns_reply *reply,
6243  struct mg_dns_resource_record *question,
6244  const char *name, int rtype, int ttl, const void *rdata,
6245  size_t rdata_len);
6246 
6247 /*
6248  * Sends a DNS reply through a connection.
6249  *
6250  * The DNS data is stored in an IO buffer pointed by reply structure in `r`.
6251  * This function mutates the content of that buffer in order to ensure that
6252  * the DNS header reflects the size and flags of the message, that might have
6253  * been updated either with `mg_dns_reply_record` or by direct manipulation of
6254  * `r->message`.
6255  *
6256  * Once sent, the IO buffer will be trimmed unless the reply IO buffer
6257  * is the connection's send buffer and the connection is not in UDP mode.
6258  */
6259 void mg_dns_send_reply(struct mg_connection *nc, struct mg_dns_reply *r);
6260 
6261 #ifdef __cplusplus
6262 }
6263 #endif /* __cplusplus */
6264 
6265 #endif /* MG_ENABLE_DNS_SERVER */
6266 #endif /* CS_MONGOOSE_SRC_DNS_SERVER_H_ */
6267 #ifdef MG_MODULE_LINES
6268 #line 1 "mongoose/src/mg_resolv.h"
6269 #endif
6270 /*
6271  * Copyright (c) 2014 Cesanta Software Limited
6272  * All rights reserved
6273  */
6274 
6275 /*
6276  * === API reference
6277  */
6278 
6279 #ifndef CS_MONGOOSE_SRC_RESOLV_H_
6280 #define CS_MONGOOSE_SRC_RESOLV_H_
6281 
6282 /* Amalgamated: #include "mg_dns.h" */
6283 
6284 #ifdef __cplusplus
6285 extern "C" {
6286 #endif /* __cplusplus */
6287 
6293 };
6294 
6295 typedef void (*mg_resolve_callback_t)(struct mg_dns_message *dns_message,
6296  void *user_data, enum mg_resolve_err);
6297 
6298 /* Options for `mg_resolve_async_opt`. */
6300  const char *nameserver;
6301  int max_retries; /* defaults to 2 if zero */
6302  int timeout; /* in seconds; defaults to 5 if zero */
6303  int accept_literal; /* pseudo-resolve literal ipv4 and ipv6 addrs */
6304  int only_literal; /* only resolves literal addrs; sync cb invocation */
6305  struct mg_connection **dns_conn; /* return DNS connection */
6306 };
6307 
6308 /* See `mg_resolve_async_opt()` */
6309 int mg_resolve_async(struct mg_mgr *mgr, const char *name, int query,
6310  mg_resolve_callback_t cb, void *data);
6311 
6312 /* Set default DNS server */
6313 void mg_set_nameserver(struct mg_mgr *mgr, const char *nameserver);
6314 
6315 /*
6316  * Resolved a DNS name asynchronously.
6317  *
6318  * Upon successful resolution, the user callback will be invoked
6319  * with the full DNS response message and a pointer to the user's
6320  * context `data`.
6321  *
6322  * In case of timeout while performing the resolution the callback
6323  * will receive a NULL `msg`.
6324  *
6325  * The DNS answers can be extracted with `mg_next_record` and
6326  * `mg_dns_parse_record_data`:
6327  *
6328  * [source,c]
6329  * ----
6330  * struct in_addr ina;
6331  * struct mg_dns_resource_record *rr = mg_next_record(msg, MG_DNS_A_RECORD,
6332  * NULL);
6333  * mg_dns_parse_record_data(msg, rr, &ina, sizeof(ina));
6334  * ----
6335  */
6336 int mg_resolve_async_opt(struct mg_mgr *mgr, const char *name, int query,
6337  mg_resolve_callback_t cb, void *data,
6338  struct mg_resolve_async_opts opts);
6339 
6340 /*
6341  * Resolve a name from `/etc/hosts`.
6342  *
6343  * Returns 0 on success, -1 on failure.
6344  */
6345 int mg_resolve_from_hosts_file(const char *host, union socket_address *usa);
6346 
6347 #ifdef __cplusplus
6348 }
6349 #endif /* __cplusplus */
6350 #endif /* CS_MONGOOSE_SRC_RESOLV_H_ */
6351 #ifdef MG_MODULE_LINES
6352 #line 1 "mongoose/src/mg_coap.h"
6353 #endif
6354 /*
6355  * Copyright (c) 2015 Cesanta Software Limited
6356  * All rights reserved
6357  * This software is dual-licensed: you can redistribute it and/or modify
6358  * it under the terms of the GNU General Public License version 2 as
6359  * published by the Free Software Foundation. For the terms of this
6360  * license, see <http://www.gnu.org/licenses/>.
6361  *
6362  * You are free to use this software under the terms of the GNU General
6363  * Public License, but WITHOUT ANY WARRANTY; without even the implied
6364  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
6365  * See the GNU General Public License for more details.
6366  *
6367  * Alternatively, you can license this software under a commercial
6368  * license, as set out in <https://www.cesanta.com/license>.
6369  */
6370 
6371 /*
6372  * === CoAP API reference
6373  *
6374  * CoAP message format:
6375  *
6376  * ```
6377  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
6378  * |Ver| T | TKL | Code | Message ID | Token (if any, TKL bytes) ...
6379  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
6380  * | Options (if any) ... |1 1 1 1 1 1 1 1| Payload (if any) ...
6381  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
6382  * ```
6383  */
6384 
6385 #ifndef CS_MONGOOSE_SRC_COAP_H_
6386 #define CS_MONGOOSE_SRC_COAP_H_
6387 
6388 #if MG_ENABLE_COAP
6389 
6390 #define MG_COAP_MSG_TYPE_FIELD 0x2
6391 #define MG_COAP_CODE_CLASS_FIELD 0x4
6392 #define MG_COAP_CODE_DETAIL_FIELD 0x8
6393 #define MG_COAP_MSG_ID_FIELD 0x10
6394 #define MG_COAP_TOKEN_FIELD 0x20
6395 #define MG_COAP_OPTIOMG_FIELD 0x40
6396 #define MG_COAP_PAYLOAD_FIELD 0x80
6397 
6398 #define MG_COAP_ERROR 0x10000
6399 #define MG_COAP_FORMAT_ERROR (MG_COAP_ERROR | 0x20000)
6400 #define MG_COAP_IGNORE (MG_COAP_ERROR | 0x40000)
6401 #define MG_COAP_NOT_ENOUGH_DATA (MG_COAP_ERROR | 0x80000)
6402 #define MG_COAP_NETWORK_ERROR (MG_COAP_ERROR | 0x100000)
6403 
6404 #define MG_COAP_MSG_CON 0
6405 #define MG_COAP_MSG_NOC 1
6406 #define MG_COAP_MSG_ACK 2
6407 #define MG_COAP_MSG_RST 3
6408 #define MG_COAP_MSG_MAX 3
6409 
6410 #define MG_COAP_CODECLASS_REQUEST 0
6411 #define MG_COAP_CODECLASS_RESP_OK 2
6412 #define MG_COAP_CODECLASS_CLIENT_ERR 4
6413 #define MG_COAP_CODECLASS_SRV_ERR 5
6414 
6415 #define MG_COAP_EVENT_BASE 300
6416 #define MG_EV_COAP_CON (MG_COAP_EVENT_BASE + MG_COAP_MSG_CON)
6417 #define MG_EV_COAP_NOC (MG_COAP_EVENT_BASE + MG_COAP_MSG_NOC)
6418 #define MG_EV_COAP_ACK (MG_COAP_EVENT_BASE + MG_COAP_MSG_ACK)
6419 #define MG_EV_COAP_RST (MG_COAP_EVENT_BASE + MG_COAP_MSG_RST)
6420 
6421 /*
6422  * CoAP options.
6423  * Use mg_coap_add_option and mg_coap_free_options
6424  * for creation and destruction.
6425  */
6428  uint32_t number;
6429  struct mg_str value;
6430 };
6431 
6432 /* CoAP message. See RFC 7252 for details. */
6434  uint32_t flags;
6435  uint8_t msg_type;
6436  uint8_t code_class;
6437  uint8_t code_detail;
6438  uint16_t msg_id;
6439  struct mg_str token;
6441  struct mg_str payload;
6443 };
6444 
6445 #ifdef __cplusplus
6446 extern "C" {
6447 #endif /* __cplusplus */
6448 
6449 /* Sets CoAP protocol handler - triggers CoAP specific events. */
6450 int mg_set_protocol_coap(struct mg_connection *nc);
6451 
6452 /*
6453  * Adds a new option to mg_coap_message structure.
6454  * Returns pointer to the newly created option.
6455  * Note: options must be freed by using mg_coap_free_options
6456  */
6458  uint32_t number, char *value,
6459  size_t len);
6460 
6461 /*
6462  * Frees the memory allocated for options.
6463  * If the cm parameter doesn't contain any option it does nothing.
6464  */
6465 void mg_coap_free_options(struct mg_coap_message *cm);
6466 
6467 /*
6468  * Composes a CoAP message from `mg_coap_message`
6469  * and sends it into `nc` connection.
6470  * Returns 0 on success. On error, it is a bitmask:
6471  *
6472  * - `#define MG_COAP_ERROR 0x10000`
6473  * - `#define MG_COAP_FORMAT_ERROR (MG_COAP_ERROR | 0x20000)`
6474  * - `#define MG_COAP_IGNORE (MG_COAP_ERROR | 0x40000)`
6475  * - `#define MG_COAP_NOT_ENOUGH_DATA (MG_COAP_ERROR | 0x80000)`
6476  * - `#define MG_COAP_NETWORK_ERROR (MG_COAP_ERROR | 0x100000)`
6477  */
6478 uint32_t mg_coap_send_message(struct mg_connection *nc,
6479  struct mg_coap_message *cm);
6480 
6481 /*
6482  * Composes CoAP acknowledgement from `mg_coap_message`
6483  * and sends it into `nc` connection.
6484  * Return value: see `mg_coap_send_message()`
6485  */
6486 uint32_t mg_coap_send_ack(struct mg_connection *nc, uint16_t msg_id);
6487 
6488 /*
6489  * Parses CoAP message and fills mg_coap_message and returns cm->flags.
6490  * This is a helper function.
6491  *
6492  * NOTE: usually CoAP works over UDP, so lack of data means format error.
6493  * But, in theory, it is possible to use CoAP over TCP (according to RFC)
6494  *
6495  * The caller has to check results and treat COAP_NOT_ENOUGH_DATA according to
6496  * underlying protocol:
6497  *
6498  * - in case of UDP COAP_NOT_ENOUGH_DATA means COAP_FORMAT_ERROR,
6499  * - in case of TCP client can try to receive more data
6500  *
6501  * Return value: see `mg_coap_send_message()`
6502  */
6503 uint32_t mg_coap_parse(struct mbuf *io, struct mg_coap_message *cm);
6504 
6505 /*
6506  * Composes CoAP message from mg_coap_message structure.
6507  * This is a helper function.
6508  * Return value: see `mg_coap_send_message()`
6509  */
6510 uint32_t mg_coap_compose(struct mg_coap_message *cm, struct mbuf *io);
6511 
6512 #ifdef __cplusplus
6513 }
6514 #endif /* __cplusplus */
6515 
6516 #endif /* MG_ENABLE_COAP */
6517 
6518 #endif /* CS_MONGOOSE_SRC_COAP_H_ */
6519 #ifdef MG_MODULE_LINES
6520 #line 1 "mongoose/src/mg_sntp.h"
6521 #endif
6522 /*
6523  * Copyright (c) 2016 Cesanta Software Limited
6524  * All rights reserved
6525  */
6526 
6527 #ifndef CS_MONGOOSE_SRC_SNTP_H_
6528 #define CS_MONGOOSE_SRC_SNTP_H_
6529 
6530 #if MG_ENABLE_SNTP
6531 
6532 #define MG_SNTP_EVENT_BASE 500
6533 
6534 /*
6535  * Received reply from time server. Event handler parameter contains
6536  * pointer to mg_sntp_message structure
6537  */
6538 #define MG_SNTP_REPLY (MG_SNTP_EVENT_BASE + 1)
6539 
6540 /* Received malformed SNTP packet */
6541 #define MG_SNTP_MALFORMED_REPLY (MG_SNTP_EVENT_BASE + 2)
6542 
6543 /* Failed to get time from server (timeout etc) */
6544 #define MG_SNTP_FAILED (MG_SNTP_EVENT_BASE + 3)
6545 
6547  /* if server sends this flags, user should not send requests to it */
6549  /* usual mg_time */
6550  double time;
6551 };
6552 
6553 /* Establishes connection to given sntp server */
6554 struct mg_connection *mg_sntp_connect(struct mg_mgr *mgr,
6555  MG_CB(mg_event_handler_t event_handler,
6556  void *user_data),
6557  const char *sntp_server_name);
6558 
6559 /* Sends time request to given connection */
6560 void mg_sntp_send_request(struct mg_connection *c);
6561 
6562 /*
6563  * Helper function
6564  * Establishes connection to time server, tries to send request
6565  * repeats sending SNTP_ATTEMPTS times every SNTP_TIMEOUT sec
6566  * (if needed)
6567  * See sntp_client example
6568  */
6569 struct mg_connection *mg_sntp_get_time(struct mg_mgr *mgr,
6570  mg_event_handler_t event_handler,
6571  const char *sntp_server_name);
6572 
6573 #endif
6574 
6575 #endif /* CS_MONGOOSE_SRC_SNTP_H_ */
6576 #ifdef MG_MODULE_LINES
6577 #line 1 "mongoose/src/mg_socks.h"
6578 #endif
6579 /*
6580  * Copyright (c) 2017 Cesanta Software Limited
6581  * All rights reserved
6582  */
6583 
6584 #ifndef CS_MONGOOSE_SRC_SOCKS_H_
6585 #define CS_MONGOOSE_SRC_SOCKS_H_
6586 
6587 #if MG_ENABLE_SOCKS
6588 
6589 #define MG_SOCKS_VERSION 5
6590 
6591 #define MG_SOCKS_HANDSHAKE_DONE MG_F_USER_1
6592 #define MG_SOCKS_CONNECT_DONE MG_F_USER_2
6593 
6594 /* SOCKS5 handshake methods */
6596  MG_SOCKS_HANDSHAKE_NOAUTH = 0, /* Handshake method - no authentication */
6597  MG_SOCKS_HANDSHAKE_GSSAPI = 1, /* Handshake method - GSSAPI auth */
6598  MG_SOCKS_HANDSHAKE_USERPASS = 2, /* Handshake method - user/password auth */
6599  MG_SOCKS_HANDSHAKE_FAILURE = 0xff, /* Handshake method - failure */
6600 };
6601 
6602 /* SOCKS5 commands */
6604  MG_SOCKS_CMD_CONNECT = 1, /* Command: CONNECT */
6605  MG_SOCKS_CMD_BIND = 2, /* Command: BIND */
6606  MG_SOCKS_CMD_UDP_ASSOCIATE = 3, /* Command: UDP ASSOCIATE */
6607 };
6608 
6609 /* SOCKS5 address types */
6611  MG_SOCKS_ADDR_IPV4 = 1, /* Address type: IPv4 */
6612  MG_SOCKS_ADDR_DOMAIN = 3, /* Address type: Domain name */
6613  MG_SOCKS_ADDR_IPV6 = 4, /* Address type: IPv6 */
6614 };
6615 
6616 /* SOCKS5 response codes */
6618  MG_SOCKS_SUCCESS = 0, /* Response: success */
6619  MG_SOCKS_FAILURE = 1, /* Response: failure */
6620  MG_SOCKS_NOT_ALLOWED = 2, /* Response: connection not allowed */
6621  MG_SOCKS_NET_UNREACHABLE = 3, /* Response: network unreachable */
6622  MG_SOCKS_HOST_UNREACHABLE = 4, /* Response: network unreachable */
6623  MG_SOCKS_CONN_REFUSED = 5, /* Response: network unreachable */
6624  MG_SOCKS_TTL_EXPIRED = 6, /* Response: network unreachable */
6625  MG_SOCKS_CMD_NOT_SUPPORTED = 7, /* Response: network unreachable */
6626  MG_SOCKS_ADDR_NOT_SUPPORTED = 8, /* Response: network unreachable */
6627 };
6628 
6629 #ifdef __cplusplus
6630 extern "C" {
6631 #endif /* __cplusplus */
6632 
6633 /* Turn the connection into the SOCKS server */
6634 void mg_set_protocol_socks(struct mg_connection *c);
6635 
6636 /* Create socks tunnel for the client connection */
6637 struct mg_iface *mg_socks_mk_iface(struct mg_mgr *, const char *proxy_addr);
6638 
6639 #ifdef __cplusplus
6640 }
6641 #endif /* __cplusplus */
6642 
6643 #endif
6644 #endif
int mg_resolve(const char *domain_name, char *ip_addr_buf, size_t buf_len)
Definition: mongoose.c:2654
struct mg_connection * nc
Definition: mongoose.h:5942
int inet_pton(int af, const char *src, void *dst)
void * data
Definition: mongoose.h:3631
const char * ssl_ca_cert
Definition: mongoose.h:4163
Definition: mongoose.h:6056
const char * cgi_file_pattern
Definition: mongoose.h:5322
int sl_set_ssl_opts(int sock, struct mg_connection *nc)
void mg_hash_md5_v(size_t num_msgs, const uint8_t *msgs[], const size_t *msg_lens, uint8_t *digest)
struct mg_iface * mg_if_create_iface(const struct mg_iface_vtable *vtable, struct mg_mgr *mgr)
Definition: mongoose.c:3556
Definition: mongoose.h:6046
struct mg_connection * mg_sntp_get_time(struct mg_mgr *mgr, mg_event_handler_t event_handler, const char *sntp_server_name)
int mg_set_protocol_coap(struct mg_connection *nc)
void mg_mbuf_append_base64_putc(char ch, void *user_data)
struct mg_str mg_strdup(const struct mg_str s)
Definition: mongoose.c:1702
Definition: mongoose.h:4740
struct mg_dns_message * msg
Definition: mongoose.h:6198
struct mg_connection * mg_next(struct mg_mgr *mgr, struct mg_connection *c)
Definition: mongoose.c:3354
void mg_set_protocol_http_websocket(struct mg_connection *nc)
void mg_http_reverse_proxy(struct mg_connection *nc, const struct http_message *hm, struct mg_str mount, struct mg_str upstream)
const char * mg_strchr(const struct mg_str s, int c)
Definition: mongoose.c:1712
int accept_literal
Definition: mongoose.h:6303
void mg_http_serve_file(struct mg_connection *nc, struct http_message *hm, const char *path, const struct mg_str mime_type, const struct mg_str extra_headers)
Definition: mongoose.h:5461
unsigned __int64 uint64_t
Definition: mongoose.h:273
int _stat(const char *pathname, struct stat *st)
struct mg_connection * mg_connect_ws(struct mg_mgr *mgr, MG_CB(mg_event_handler_t event_handler, void *user_data), const char *url, const char *protocol, const char *extra_headers)
void mg_if_connect_cb(struct mg_connection *nc, int err)
Definition: mongoose.c:3093
union socket_address sa
Definition: mongoose.h:3895
mg_event_handler_t handler
Definition: mongoose.h:3907
const char * custom_mime_types
Definition: mongoose.h:5331
const char * server_name
Definition: mongoose.h:3761
void cs_sha1_init(cs_sha1_ctx *)
Definition: mongoose.c:1408
void mg_send_websocket_handshake(struct mg_connection *nc, const char *uri, const char *extra_headers)
void mbuf_free(struct mbuf *)
Definition: mongoose.c:1539
mg_event_handler_t proto_handler
Definition: mongoose.h:3904
double ev_timer_time
Definition: mongoose.h:3900
SOCKET sock_t
Definition: mongoose.h:275
unsigned char flags
Definition: mongoose.h:5722
Definition: mongoose.h:5721
int mg_resolve_async(struct mg_mgr *mgr, const char *name, int query, mg_resolve_callback_t cb, void *data)
struct mg_iface * mg_find_iface(struct mg_mgr *mgr, const struct mg_iface_vtable *vtable, struct mg_iface *from)
Definition: mongoose.c:3565
Definition: mongoose.h:2774
const char * topic
Definition: mongoose.h:5717
struct mg_mqtt_session * mg_mqtt_next(struct mg_mqtt_broker *brk, struct mg_mqtt_session *s)
int mg_dns_parse_record_data(struct mg_dns_message *msg, struct mg_dns_resource_record *rr, void *data, size_t data_len)
void cs_base64_finish(struct cs_base64_ctx *ctx)
Definition: mongoose.c:298
Definition: mongoose.h:6289
long ssize_t
Definition: mongoose.h:775
Definition: mongoose.h:6042
void * mg_start_thread(void *(*thread_func)(void *), void *thread_func_param)
const char * ssl_cipher_suites
Definition: mongoose.h:4106
const char * cipher_suites
Definition: mongoose.h:3762
struct mg_iface * iface
Definition: mongoose.h:4146
size_t mbuf_insert(struct mbuf *, size_t, const void *, size_t)
Definition: mongoose.c:1567
Definition: mongoose.h:5184
uint8_t code_detail
Definition: mongoose.h:6437
void mg_mqtt_unsubscribe(struct mg_connection *nc, char **topics, size_t topics_len, uint16_t message_id)
int only_literal
Definition: mongoose.h:6304
int cs_base64_decode(const unsigned char *s, int len, char *dst, int *dec_len)
Definition: mongoose.c:408
Definition: mongoose.h:3754
void mbuf_init(struct mbuf *, size_t initial_capacity)
Definition: mongoose.c:1532
in_addr_t inet_addr(const char *cp)
void cs_base64_update(struct cs_base64_ctx *ctx, const char *str, size_t len)
Definition: mongoose.c:286
mg_socks_handshake_method
Definition: mongoose.h:6595
void mg_mqtt_connack(struct mg_connection *nc, uint8_t return_code)
const char * mime_type
Definition: mongoose.c:6015
Definition: mongoose.h:3635
Definition: mongoose.h:6605
Definition: mongoose.h:6426
const char * nameserver
Definition: mongoose.h:3882
Definition: mongoose.h:6621
struct mg_str mg_url_encode_opt(const struct mg_str src, const struct mg_str safe, unsigned int flags)
uint32_t mg_coap_parse(struct mbuf *io, struct mg_coap_message *cm)
uint32_t mg_coap_send_ack(struct mg_connection *nc, uint16_t msg_id)
int mg_hexdump(const void *buf, int len, char *dst, int dst_len)
uint8_t msg_type
Definition: mongoose.h:6435
int mg_dns_encode_name(struct mbuf *io, const char *name, size_t len)
struct mg_connection * mg_add_sock(struct mg_mgr *mgr, sock_t sock, MG_CB(mg_event_handler_t handler, void *user_data))
struct mg_connection * mg_connect_http(struct mg_mgr *mgr, MG_CB(mg_event_handler_t event_handler, void *user_data), const char *url, const char *extra_headers, const char *post_data)
int c_snprintf(char *buf, size_t buf_size, const char *format,...) PRINTF_LIKE(3
Definition: mongoose.c:2006
int mg_printf(struct mg_connection *conn, const char *fmt,...)
Definition: mongoose.c:2613
short int16_t
Definition: mongoose.h:270
void mg_if_recv_udp_cb(struct mg_connection *nc, void *buf, int len, union socket_address *sa, size_t sa_len)
void mg_http_send_digest_auth_request(struct mg_connection *c, const char *domain)
struct sockaddr sa
Definition: mongoose.h:3840
Definition: mongoose.h:2429
void mg_mqtt_puback(struct mg_connection *nc, uint16_t message_id)
Definition: mongoose.h:4043
const char * password
Definition: mongoose.h:5727
Definition: mongoose.h:6612
double cs_time(void)
Definition: mongoose.c:918
struct mg_str name
Definition: mongoose.h:6047
const char * ip_acl
Definition: mongoose.h:5279
int num_ifaces
Definition: mongoose.h:3879
const char ** error_string
Definition: mongoose.h:4046
double mg_time(void)
Definition: mongoose.c:3485
const char * psk_key
Definition: mongoose.h:3764
size_t start
Definition: mongoose.h:6200
struct mg_str mg_mk_str(const char *s)
Definition: mongoose.c:1654
void mg_mqtt_broker_init(struct mg_mqtt_broker *brk, void *user_data)
const char * per_directory_auth_file
Definition: mongoose.h:5200
int inet_aton(const char *cp, struct in_addr *inp)
uint32_t flags
Definition: mongoose.h:6434
Definition: mongoose.h:3972
const char * document_root
Definition: mongoose.h:5186
const char * hexdump_file
Definition: mongoose.h:3873
void mg_sntp_send_request(struct mg_connection *c)
Definition: mongoose.h:5731
Definition: mongoose.h:6620
char * strdup(const char *src)
Definition: mongoose.c:2066
void * user_data
Definition: mongoose.h:2434
int mg_if_poll(struct mg_connection *nc, double now)
Definition: mongoose.c:2439
void mg_set_protocol_socks(struct mg_connection *c)
Definition: mongoose.h:6291
struct mg_str mg_next_comma_list_entry_n(struct mg_str list, struct mg_str *val, struct mg_str *eq_val)
Definition: mongoose.c:2216
uint8_t connack_ret_code
Definition: mongoose.h:5701
struct mg_connection * mg_connect(struct mg_mgr *mgr, const char *address, MG_CB(mg_event_handler_t handler, void *user_data))
struct mg_mqtt_broker * brk
Definition: mongoose.h:5940
uint16_t keep_alive_timer
Definition: mongoose.h:5707
uint32_t mg_coap_compose(struct mg_coap_message *cm, struct mbuf *io)
Definition: mongoose.h:5939
void mg_mqtt_suback(struct mg_connection *nc, uint8_t *qoss, size_t qoss_len, uint16_t message_id)
struct mg_connection * prev
Definition: mongoose.h:3889
int rclass
Definition: mongoose.h:6049
unsigned short uint16_t
Definition: mongoose.h:271
void mg_if_accept_tcp_cb(struct mg_connection *nc, union socket_address *sa, size_t sa_len)
Definition: mongoose.c:2840
void mg_send_head(struct mg_connection *n, int status_code, int64_t content_length, const char *extra_headers)
void mg_mqtt_pong(struct mg_connection *nc)
Definition: mongoose.h:4077
struct mg_iface * iface
Definition: mongoose.h:4047
int stat(const char *pathname, struct stat *st)
struct mg_str mg_strstrip(struct mg_str s)
Definition: mongoose.c:1762
const char * nameserver
Definition: mongoose.h:3976
void cs_md5_final(unsigned char *md, cs_md5_ctx *c)
size_t mg_match_prefix(const char *pattern, int pattern_len, const char *str)
Definition: mongoose.c:2298
int num_answers
Definition: mongoose.h:6061
void mg_send_mqtt_handshake(struct mg_connection *nc, const char *client_id)
int int mg_avprintf(char **buf, size_t size, const char *fmt, va_list ap)
Definition: mongoose.c:2158
Definition: mongoose.h:2127
int kiss_of_death
Definition: mongoose.h:6548
Definition: mongoose.h:2221
const char * fmt
Definition: mongoose.h:4297
void * priv_2
Definition: mongoose.h:3917
int mg_parse_http(const char *s, int n, struct http_message *hm, int is_req)
Definition: mongoose.c:6162
time_t tv_sec
Definition: mongoose.h:1209
size_t len
Definition: mongoose.h:2344
void(* mg_event_handler_t)(struct mg_connection *nc, int ev, void *ev_data MG_UD_ARG(void *user_data))
Definition: mongoose.h:3855
void mg_send_websocket_handshake2(struct mg_connection *nc, const char *path, const char *host, const char *protocol, const char *extra_headers)
void mg_hexdump_connection(struct mg_connection *nc, const char *path, const void *buf, int num_bytes, int ev)
int mg_dns_copy_questions(struct mbuf *io, struct mg_dns_message *msg)
double mg_mgr_min_timer(const struct mg_mgr *mgr)
Definition: mongoose.c:3586
void mg_mqtt_pubcomp(struct mg_connection *nc, uint16_t message_id)
long suseconds_t
Definition: mongoose.h:1207
void mg_ssl_if_conn_close_notify(struct mg_connection *nc)
Definition: mongoose.c:5269
uint16_t msg_id
Definition: mongoose.h:6438
int asprintf(char **strp, const char *fmt,...)
Definition: mongoose.h:6597
int int c_vsnprintf(char *buf, size_t buf_size, const char *format, va_list ap)
Definition: mongoose.c:1822
void * user_data
Definition: mongoose.h:4143
void mg_printf_http_chunk(struct mg_connection *nc, const char *fmt,...)
const char * prevfile
Definition: mongoose.h:2778
const char * enable_directory_listing
Definition: mongoose.h:5216
struct mg_connection * next
Definition: mongoose.h:3889
struct mbuf * io
Definition: mongoose.h:6199
const struct mg_iface_vtable * vtable
Definition: mongoose.h:3632
int mg_stat(const char *path, cs_stat_t *st)
Definition: mongoose.h:6292
int mg_socketpair(sock_t[2], int sock_type)
Definition: mongoose.c:4227
struct mg_coap_option * options
Definition: mongoose.h:6440
const char * ssl_psk_identity
Definition: mongoose.h:4191
mg_event_handler_t f
Definition: mongoose.h:3915
bool mg_start_task(int priority, int stack_size, mg_init_cb mg_init)
const char * user_name
Definition: mongoose.h:5726
const char * p
Definition: mongoose.h:2222
Definition: mongoose.h:6040
Definition: mongoose.h:6606
void mg_printf_websocket_frame(struct mg_connection *nc, int op_and_flags, const char *fmt,...)
Definition: mongoose.h:6626
const char * lastfile
Definition: mongoose.h:2777
Definition: mongoose.h:6599
void * user_data
Definition: mongoose.h:4078
void mg_dns_send_reply(struct mg_connection *nc, struct mg_dns_reply *r)
int mg_sock_addr_to_str(const union socket_address *sa, char *buf, size_t len, int flags)
void mg_register_http_endpoint_opt(struct mg_connection *nc, const char *uri_path, mg_event_handler_t handler, struct mg_http_endpoint_opts opts)
enum mg_ssl_if_result mg_ssl_if_conn_init(struct mg_connection *nc, const struct mg_ssl_if_conn_params *params, const char **err_msg)
Definition: mongoose.c:5054
const struct mg_iface_vtable * mg_ifaces[]
Definition: mongoose.c:3550
struct mg_connection * mg_add_sock_opt(struct mg_mgr *mgr, sock_t sock, MG_CB(mg_event_handler_t handler, void *user_data), struct mg_add_sock_opts opts)
int mg_parse_uri(const struct mg_str uri, struct mg_str *scheme, struct mg_str *user_info, struct mg_str *host, unsigned int *port, struct mg_str *path, struct mg_str *query, struct mg_str *fragment)
Definition: mongoose.c:5509
const char * ssl_key
Definition: mongoose.h:4158
const char * mg_strstr(const struct mg_str haystack, const struct mg_str needle)
Definition: mongoose.c:1749
size_t _off_t
Definition: mongoose.h:774
size_t mg_parse_multipart(const char *buf, size_t buf_len, char *var_name, size_t var_name_len, char *file_name, size_t file_name_len, const char **chunk, size_t *chunk_len)
void(* cs_base64_putc_t)(char, void *)
Definition: mongoose.h:2427
void cs_base64_encode(const unsigned char *src, int src_len, char *dst)
Definition: mongoose.c:344
void mg_send_mqtt_handshake_opt(struct mg_connection *nc, const char *client_id, struct mg_send_mqtt_handshake_opts)
const char * dav_auth_file
Definition: mongoose.h:5316
struct mg_coap_option * mg_coap_add_option(struct mg_coap_message *cm, uint32_t number, char *value, size_t len)
mg_ssl_if_result
Definition: mongoose.h:3750
struct mg_str(* mg_fu_fname_fn)(struct mg_connection *nc, struct mg_str fname)
Definition: mongoose.h:5389
void mg_if_can_send_cb(struct mg_connection *nc)
Definition: mongoose.c:3013
int mg_http_parse_header(struct mg_str *hdr, const char *var_name, char *buf, size_t buf_size) __attribute__((deprecated))
void mg_mgr_free(struct mg_mgr *mgr)
Definition: mongoose.c:2558
int num_ifaces
Definition: mongoose.h:3974
mg_resolve_err
Definition: mongoose.h:6288
void * proto_data
Definition: mongoose.h:3905
time_t last_io_time
Definition: mongoose.h:3899
struct mg_connection * mg_connect_opt(struct mg_mgr *mgr, const char *address, MG_CB(mg_event_handler_t handler, void *user_data), struct mg_connect_opts opts)
unsigned long uintptr_t
Definition: mongoose.h:259
double time
Definition: mongoose.h:6550
void mbuf_trim(struct mbuf *)
Definition: mongoose.c:1562
int mg_dns_insert_header(struct mbuf *io, size_t pos, struct mg_dns_message *msg)
void cs_hmac_sha1(const unsigned char *key, size_t key_len, const unsigned char *text, size_t text_len, unsigned char out[20])
Definition: mongoose.c:1461
size_t mg_dns_uncompress_name(struct mg_dns_message *msg, struct mg_str *name, char *dst, int dst_len)
int num_questions
Definition: mongoose.h:6060
Definition: mongoose.h:6598
unsigned long flags
Definition: mongoose.h:3920
Definition: mongoose.h:6623
unsigned long lastline
Definition: mongoose.h:2775
void sl_restart_cb(struct mg_mgr *mgr)
void * user_data
Definition: mongoose.h:4753
uint32_t st_mtime
Definition: mongoose.h:1698
suseconds_t tv_usec
Definition: mongoose.h:1210
void mg_register_http_endpoint(struct mg_connection *nc, const char *uri_path, MG_CB(mg_event_handler_t handler, void *user_data))
void mg_set_protocol_mqtt(struct mg_connection *nc)
mg_dns_resource_record_kind
Definition: mongoose.h:6039
void mg_mbuf_append_base64(struct mbuf *mbuf, const void *data, size_t len)
uint8_t connect_flags
Definition: mongoose.h:5706
int mg_mqtt_vmatch_topic_expression(const char *exp, struct mg_str topic)
const char * file_name
Definition: mongoose.h:4749
struct mg_iface * mg_socks_mk_iface(struct mg_mgr *, const char *proxy_addr)
Definition: mongoose.c:4558
void mg_set_nameserver(struct mg_mgr *mgr, const char *nameserver)
void mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data, mg_fu_fname_fn local_name_fn MG_UD_ARG(void *user_data))
void mg_basic_auth_header(const struct mg_str user, const struct mg_str pass, struct mbuf *buf)
void mg_if_can_recv_cb(struct mg_connection *nc)
Definition: mongoose.c:2892
Definition: mongoose.h:3839
struct mg_connection * listener
Definition: mongoose.h:3890
void * user_data
Definition: mongoose.h:5462
const char * ssl_psk_key
Definition: mongoose.h:4192
Definition: mongoose.h:3870
struct mg_dns_resource_record * mg_dns_next_record(struct mg_dns_message *msg, int query, struct mg_dns_resource_record *prev)
const char * mg_set_ssl(struct mg_connection *nc, const char *cert, const char *ca_cert)
Definition: mongoose.c:5455
size_t mbuf_append(struct mbuf *, const void *data, size_t data_size)
Definition: mongoose.c:1611
Definition: mongoose.h:4757
const char * key
Definition: mongoose.h:3759
void cs_md5_init(cs_md5_ctx *c)
Definition: mongoose.c:1082
void * user_data
Definition: mongoose.h:3908
int rtype
Definition: mongoose.h:6048
Definition: mongoose.c:4585
int ttl
Definition: mongoose.h:6050
unsigned int mode_t
Definition: mongoose.h:773
unsigned int uint32_t
Definition: mongoose.h:269
void mg_http_send_error(struct mg_connection *nc, int code, const char *reason)
struct mg_mgr * mgr
Definition: mongoose.h:3630
int mg_conn_addr_to_str(struct mg_connection *c, char *buf, size_t len, int flags)
int mg_casecmp(const char *s1, const char *s2)
Definition: mongoose.c:2143
const char * ssl_cert
Definition: mongoose.h:4153
Definition: mongoose.h:6546
void mg_ssl_if_init()
Definition: mongoose.c:5023
void(* mg_resolve_callback_t)(struct mg_dns_message *dns_message, void *user_data, enum mg_resolve_err)
Definition: mongoose.h:6295
int mg_get_http_basic_auth(struct http_message *hm, char *user, size_t user_len, char *pass, size_t pass_len)
int cmd
Definition: mongoose.h:5695
unsigned int flags
Definition: mongoose.h:4079
int mg_http_parse_header2(struct mg_str *hdr, const char *var_name, char **buf, size_t buf_size)
const char * cgi_interpreter
Definition: mongoose.h:5325
Definition: mongoose.h:6611
const char * cert
Definition: mongoose.h:3758
const char * inet_ntop(int af, const void *src, char *dst, socklen_t size)
int mg_resolve_from_hosts_file(const char *host, union socket_address *usa)
uint16_t transaction_id
Definition: mongoose.h:6059
Definition: mongoose.h:4710
void mg_base64_encode(const unsigned char *src, int src_len, char *dst)
int mg_normalize_uri_path(const struct mg_str *in, struct mg_str *out)
Definition: mongoose.c:5639
mode_t st_mode
Definition: mongoose.h:779
int mg_dns_encode_record(struct mbuf *io, struct mg_dns_resource_record *rr, const char *name, size_t nlen, const void *rdata, size_t rlen)
unsigned int flags
Definition: mongoose.h:4144
int mg_http_check_digest_auth(struct http_message *hm, const char *auth_domain, FILE *fp)
struct mg_iface * iface
Definition: mongoose.h:3919
size_t c_strnlen(const char *s, size_t maxlen)
Definition: mongoose.c:1805
Definition: mongoose.h:4142
int mg_ncasecmp(const char *s1, const char *s2, size_t len)
Definition: mongoose.c:2132
const char * var_name
Definition: mongoose.h:4750
int mg_mqtt_next_subscribe_topic(struct mg_mqtt_message *msg, struct mg_str *topic, uint8_t *qos, int pos)
Definition: mongoose.h:1208
char * inet_ntoa(struct in_addr in)
int mg_url_decode(const char *src, int src_len, char *dst, int dst_len, int is_form_url_encoded)
unsigned char flags
Definition: mongoose.h:4743
const char * strerror()
struct _stati64 cs_stat_t
Definition: mongoose.h:289
void mg_mqtt_pubrel(struct mg_connection *nc, uint16_t message_id)
void cs_sha1_final(unsigned char digest[20], cs_sha1_ctx *)
Definition: mongoose.c:1437
void mg_mqtt_subscribe(struct mg_connection *nc, const struct mg_mqtt_topic_expression *topics, size_t topics_len, uint16_t message_id)
int open(const char *filename, int oflag, int pmode)
const char * psk_identity
Definition: mongoose.h:3763
int mg_check_digest_auth(struct mg_str method, struct mg_str uri, struct mg_str username, struct mg_str cnonce, struct mg_str response, struct mg_str qop, struct mg_str nc, struct mg_str nonce, struct mg_str auth_domain, FILE *fp)
const char * ssl_key
Definition: mongoose.h:4092
double cs_timegm(const struct tm *tm)
Definition: mongoose.c:946
int mg_parse_dns(const char *buf, int len, struct mg_dns_message *msg)
void cs_md5_update(cs_md5_ctx *c, const unsigned char *data, size_t len)
Definition: mongoose.c:1174
int max_retries
Definition: mongoose.h:6301
int mg_get_http_var(const struct mg_str *buf, const char *name, char *dst, size_t dst_len)
void mg_mqtt_broker(struct mg_connection *brk, int ev, void *data)
int socklen_t
Definition: mongoose.h:262
int mg_ssl_if_read(struct mg_connection *nc, void *buf, size_t buf_size)
Definition: mongoose.c:5237
Definition: mongoose.h:6604
int mg_base64_decode(const unsigned char *s, int len, char *dst)
const char * nameserver
Definition: mongoose.h:4147
void mg_send_websocket_frame(struct mg_connection *nc, int op_and_flags, const void *data, size_t data_len)
Definition: mongoose.h:6290
long long strtoll(const char *, char **, int)
void mg_http_send_redirect(struct mg_connection *nc, int status_code, const struct mg_str location, const struct mg_str extra_headers)
int int32_t
Definition: mongoose.h:268
Definition: mongoose.h:2342
void mg_send(struct mg_connection *, const void *buf, int len)
Definition: mongoose.c:2861
void cs_base64_init(struct cs_base64_ctx *ctx, cs_base64_putc_t putc, void *user_data)
Definition: mongoose.c:279
void mg_run_in_task(void(*cb)(struct mg_mgr *mgr, void *arg), void *cb_arg)
int qos
Definition: mongoose.h:5696
Definition: mongoose.h:3753
int settimeofday(const struct timeval *tv, const void *tz)
int mg_is_big_endian(void)
int mg_mgr_poll(struct mg_mgr *mgr, int milli)
Definition: mongoose.c:2589
const char * nameserver
Definition: mongoose.h:6300
void mg_lwip_set_keepalive_params(struct mg_connection *nc, int idle, int interval, int count)
mg_socks_command
Definition: mongoose.h:6603
int len
Definition: mongoose.h:5697
Definition: mongoose.h:6433
void cs_to_hex(char *to, const unsigned char *p, size_t len)
Definition: mongoose.c:2077
double mg_set_timer(struct mg_connection *c, double timestamp)
Definition: mongoose.c:3434
size_t size
Definition: mongoose.h:4742
Definition: mongoose.h:777
struct mg_connection * mg_connect_http_opt(struct mg_mgr *mgr, MG_CB(mg_event_handler_t ev_handler, void *user_data), struct mg_connect_opts opts, const char *url, const char *extra_headers, const char *post_data)
enum mg_ssl_if_result mg_ssl_if_handshake(struct mg_connection *nc)
Definition: mongoose.c:5205
Definition: mongoose.h:6624
int _wstati64(const wchar_t *path, cs_stat_t *st)
uint32_t mg_coap_send_message(struct mg_connection *nc, struct mg_coap_message *cm)
struct mg_str mg_mk_str_n(const char *s, size_t len)
Definition: mongoose.c:1661
const char int mg_vprintf(struct mg_connection *, const char *fmt, va_list ap)
Definition: mongoose.c:2599
size_t mg_fread(void *ptr, size_t size, size_t count, FILE *f)
struct mg_iface ** ifaces
Definition: mongoose.h:3881
void mg_ssl_if_conn_free(struct mg_connection *nc)
Definition: mongoose.c:5275
struct mg_connection ** dns_conn
Definition: mongoose.h:6305
int mg_check_ip_acl(const char *acl, uint32_t remote_ip)
Definition: mongoose.c:3404
struct mg_mqtt_topic_expression * subscriptions
Definition: mongoose.h:5945
int timeout
Definition: mongoose.h:6302
struct mg_str mg_url_encode(const struct mg_str src)
int gettimeofday(struct timeval *t, void *tz)
Definition: compat_time.c:29
void * user_data
Definition: mongoose.h:4044
struct mg_connection * mg_sntp_connect(struct mg_mgr *mgr, MG_CB(mg_event_handler_t event_handler, void *user_data), const char *sntp_server_name)
void cs_sha1_update(cs_sha1_ctx *, const unsigned char *data, uint32_t len)
Definition: mongoose.c:1417
const char * extra_headers
Definition: mongoose.h:5337
Definition: mongoose.h:6618
double last_control_time
Definition: mongoose.h:5733
struct mg_str mg_strdup_nul(const struct mg_str s)
Definition: mongoose.c:1707
void mg_set_close_on_exec(sock_t)
cs_base64_putc_t b64_putc
Definition: mongoose.h:2431
uint16_t flags
Definition: mongoose.h:6058
struct mg_str * mg_get_http_header(struct http_message *hm, const char *name)
Definition: mongoose.c:6226
uint32_t st_size
Definition: mongoose.h:1699
struct mg_connection * mg_if_accept_new_conn(struct mg_connection *lc)
Definition: mongoose.c:2823
int mg_parse_http_basic_auth(struct mg_str *hdr, char *user, size_t user_len, char *pass, size_t pass_len)
unsigned char uint8_t
Definition: mongoose.h:267
struct http_message * req
Definition: mongoose.h:4758
int sl_fs_init(void)
struct mg_coap_option * optiomg_tail
Definition: mongoose.h:6442
int chunk_size
Definition: mongoose.h:2433
void mg_mqtt_ping(struct mg_connection *nc)
Definition: mongoose.h:6197
int slfs_open(const unsigned char *fname, uint32_t flags)
void mbuf_resize(struct mbuf *, size_t new_size)
Definition: mongoose.c:1547
int mg_http_is_authorized(struct http_message *hm, struct mg_str path, const char *domain, const char *passwords_file, int flags)
Definition: mongoose.h:5694
Definition: mongoose.h:1697
int mg_vcmp(const struct mg_str *str2, const char *str1)
Definition: mongoose.c:1667
Definition: mongoose.h:6613
size_t size
Definition: mongoose.h:2345
int mg_strncmp(const struct mg_str str1, const struct mg_str str2, size_t n)
Definition: mongoose.c:1734
const char * ssl_server_name
Definition: mongoose.h:4183
Definition: mongoose.h:6622
Dynamically growing list, elems is always NULL terminated, call list_ensure_size() to alloc elems...
Definition: list.h:18
void(* mg_init_cb)(struct mg_mgr *mgr)
Definition: mongoose.h:1467
struct mg_connection * mg_bind(struct mg_mgr *mgr, const char *address, MG_CB(mg_event_handler_t handler, void *user_data))
int st_ino
Definition: mongoose.h:778
void mg_set_protocol_dns(struct mg_connection *nc)
const char * will_message
Definition: mongoose.h:5725
Definition: mongoose.h:3888
int mg_mqtt_match_topic_expression(struct mg_str exp, struct mg_str topic)
const char * ca_cert
Definition: mongoose.h:3760
struct mg_connection * mg_bind_opt(struct mg_mgr *mgr, const char *address, MG_CB(mg_event_handler_t handler, void *user_data), struct mg_bind_opts opts)
sock_t sock
Definition: mongoose.h:3893
int status
Definition: mongoose.h:4752
const char ** error_string
Definition: mongoose.h:4080
void mg_hexdumpf(FILE *fp, const void *buf, int len)
void mg_broadcast(struct mg_mgr *mgr, mg_event_handler_t cb, void *data, size_t len)
Definition: mongoose.c:3359
void mg_mgr_init_opt(struct mg_mgr *mgr, void *user_data, struct mg_mgr_init_opts opts)
Definition: mongoose.c:2506
__int64 int64_t
Definition: mongoose.h:272
const char * ssl_ca_cert
Definition: mongoose.h:4094
uint32_t st_mode
Definition: mongoose.h:1700
void mg_mgr_init(struct mg_mgr *mgr, void *user_data)
Definition: mongoose.c:2500
struct mg_connection * active_connections
Definition: mongoose.h:3871
void mg_send_http_chunk(struct mg_connection *nc, const char *buf, size_t len)
void * user_data
Definition: mongoose.h:5944
void mg_coap_free_options(struct mg_coap_message *cm)
void mg_mqtt_publish(struct mg_connection *nc, const char *topic, uint16_t message_id, int flags, const void *data, size_t len)
int mg_asprintf(char **buf, size_t size, const char *fmt,...) PRINTF_LIKE(3
Definition: mongoose.c:2148
int mg_resolve_async_opt(struct mg_mgr *mgr, const char *name, int query, mg_resolve_callback_t cb, void *data, struct mg_resolve_async_opts opts)
uint16_t message_id
Definition: mongoose.h:5702
Definition: mongoose.h:6625
void * ssl_if_data
Definition: mongoose.h:3902
void mg_printf_html_escape(struct mg_connection *nc, const char *fmt,...)
Definition: mongoose.h:6299
size_t mg_fwrite(const void *ptr, size_t size, size_t count, FILE *f)
const char * global_auth_file
Definition: mongoose.h:5213
const char * url_rewrites
Definition: mongoose.h:5306
struct mg_connection * mg_connect_ws_opt(struct mg_mgr *mgr, MG_CB(mg_event_handler_t ev_handler, void *user_data), struct mg_connect_opts opts, const char *url, const char *protocol, const char *extra_headers)
const char * mg_next_comma_list_entry(const char *list, struct mg_str *val, struct mg_str *eq_val)
Definition: mongoose.c:2206
void mg_serve_http(struct mg_connection *nc, struct http_message *hm, struct mg_serve_http_opts opts)
size_t mg_match_prefix_n(const struct mg_str pattern, const struct mg_str str)
Definition: mongoose.c:2252
uint16_t keep_alive
Definition: mongoose.h:5723
int resp_code
Definition: mongoose.h:4720
__attribute__((format(printf, 2, 3))) int mg_printf(struct mg_connection *
int mg_num_ifaces
Definition: mongoose.c:3554
void mg_mqtt_unsuback(struct mg_connection *nc, uint16_t message_id)
Definition: mongoose.h:2077
Definition: mongoose.h:4748
void cs_from_hex(char *to, const char *p, size_t len)
Definition: mongoose.c:2099
unsigned char * data
Definition: mongoose.h:4741
Definition: mongoose.h:3752
off_t st_size
Definition: mongoose.h:782
void mg_mqtt_pubrec(struct mg_connection *nc, uint16_t message_id)
Definition: mongoose.h:3629
Definition: mongoose.h:5716
const char * hidden_file_pattern
Definition: mongoose.h:5319
uint8_t qos
Definition: mongoose.h:5718
uint16_t keep_alive
Definition: mongoose.h:5732
void mg_sock_to_str(sock_t sock, char *buf, size_t len, int flags)
Definition: mongoose.c:4282
int mg_strcmp(const struct mg_str str1, const struct mg_str str2)
Definition: mongoose.c:1721
uint32_t number
Definition: mongoose.h:6428
const char * dav_document_root
Definition: mongoose.h:5310
char * buf
Definition: mongoose.h:2343
const char * ssi_pattern
Definition: mongoose.h:5276
const char * auth_domain
Definition: mongoose.h:5203
const char * auth_domain
Definition: mongoose.h:5464
enum mg_ssl_if_result mg_ssl_if_conn_accept(struct mg_connection *nc, struct mg_connection *lc)
Definition: mongoose.c:5027
signed char int8_t
Definition: mongoose.h:266
size_t num_subscriptions
Definition: mongoose.h:5943
int bool
Definition: mongoose.h:225
struct mg_dns_reply mg_dns_create_reply(struct mbuf *io, struct mg_dns_message *msg)
int st_nlink
Definition: mongoose.h:780
int mg_http_create_digest_auth_header(char *buf, size_t buf_len, const char *method, const char *uri, const char *auth_domain, const char *user, const char *passwd, const char *nonce)
int64_t cs_to64(const char *s)
Definition: mongoose.c:2110
Definition: mongoose.h:3757
void mg_send_websocket_handshake3v(struct mg_connection *nc, const struct mg_str path, const struct mg_str host, const struct mg_str protocol, const struct mg_str extra_headers, const struct mg_str user, const struct mg_str pass)
uint32_t in_addr_t
Definition: mongoose.h:276
long intptr_t
Definition: mongoose.h:260
unsigned int flags
Definition: mongoose.h:4045
int mg_open(const char *path, int flag, int mode)
const char * will_topic
Definition: mongoose.h:5724
void mg_send_websocket_framev(struct mg_connection *nc, int op_and_flags, const struct mg_str *strings, int num_strings)
FILE * mg_fopen(const char *path, const char *mode)
uint8_t code_class
Definition: mongoose.h:6436
const char * mg_skip(const char *s, const char *end_string, const char *delimiters, struct mg_str *v)
const char * index_files
Definition: mongoose.h:5189
void * user_data
Definition: mongoose.h:3878
int num_calls
Definition: mongoose.h:3880
mg_socks_address_type
Definition: mongoose.h:6610
void * user_data
Definition: mongoose.h:5951
time_t st_mtime
Definition: mongoose.h:781
int mg_dns_reply_record(struct mg_dns_reply *reply, struct mg_dns_resource_record *question, const char *name, int rtype, int ttl, const void *rdata, size_t rdata_len)
int err
Definition: mongoose.h:3894
void mg_send_dns_query(struct mg_connection *nc, const char *name, int query_type)
int mg_vcasecmp(const struct mg_str *str2, const char *str1)
Definition: mongoose.c:1677
struct mg_iface * iface
Definition: mongoose.h:4081
Definition: mongoose.h:3751
const char * ssl_cipher_suites
Definition: mongoose.h:4175
void mbuf_remove(struct mbuf *, size_t data_size)
Definition: mongoose.c:1616
Definition: mongoose.h:6596
void mg_send_response_line(struct mg_connection *nc, int status_code, const char *extra_headers)
const char * c_strnstr(const char *s, const char *find, size_t slen)
Definition: mongoose.c:2047
void mg_send_websocket_handshake3(struct mg_connection *nc, const char *path, const char *host, const char *protocol, const char *extra_headers, const char *user, const char *pass)
mg_socks_response
Definition: mongoose.h:6617
const char * ssl_cert
Definition: mongoose.h:4089
const struct mg_iface_vtable ** ifaces
Definition: mongoose.h:3975
const char * auth_file
Definition: mongoose.h:5465
size_t recv_mbuf_limit
Definition: mongoose.h:3896
Definition: data.h:58
void * mgr_data
Definition: mongoose.h:3918
void mg_mqtt_disconnect(struct mg_connection *nc)
Definition: mongoose.h:6041
unsigned long prevline
Definition: mongoose.h:2776
const char ** error_string
Definition: mongoose.h:4145
uint8_t protocol_version
Definition: mongoose.h:5705
struct mg_coap_option * next
Definition: mongoose.h:6427
void cs_fprint_base64(FILE *f, const unsigned char *src, int src_len)
Definition: mongoose.c:360
struct mg_mgr * mgr
Definition: mongoose.h:3891
const struct mg_iface_vtable * main_iface
Definition: mongoose.h:3973
int mg_assemble_uri(const struct mg_str *scheme, const struct mg_str *user_info, const struct mg_str *host, unsigned int port, const struct mg_str *path, const struct mg_str *query, const struct mg_str *fragment, int normalize_path, struct mg_str *uri)
Definition: mongoose.c:5673
Definition: mongoose.h:5949
int mg_ssl_if_write(struct mg_connection *nc, const void *data, size_t len)
Definition: mongoose.c:5246
size_t len
Definition: mongoose.h:2223
void mg_hash_sha1_v(size_t num_msgs, const uint8_t *msgs[], const size_t *msg_lens, uint8_t *digest)
void * v
Definition: mongoose.h:3910
Definition: mongoose.h:6619