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