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