1748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/*
2748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     This file is part of libmicrohttpd
3748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     Copyright (C) 2008 Christian Grothoff (and other contributing authors)
4748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
5748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     This library is free software; you can redistribute it and/or
6748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     modify it under the terms of the GNU Lesser General Public
7748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     License as published by the Free Software Foundation; either
8748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     version 2.1 of the License, or (at your option) any later version.
9748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
10748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     This library is distributed in the hope that it will be useful,
11748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     but WITHOUT ANY WARRANTY; without even the implied warranty of
12748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     Lesser General Public License for more details.
14748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
15748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     You should have received a copy of the GNU Lesser General Public
16748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     License along with this library; if not, write to the Free Software
17748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat*/
19748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
20748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/**
21748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @file platform.h
22748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @brief platform-specific includes for libmicrohttpd
23748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * @author Christian Grothoff
24748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat *
25748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * This file is included by the libmicrohttpd code
26748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * before "microhttpd.h"; it provides the required
27748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * standard headers (which are platform-specific).<p>
28748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat *
29748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * Note that this file depends on our configure.ac
30748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * build process and the generated config.h file.
31748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * Hence you cannot include it directly in applications
32748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * that use libmicrohttpd.
33748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat */
34748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#ifndef MHD_PLATFORM_H
35748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define MHD_PLATFORM_H
36748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
37748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include "MHD_config.h"
38748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
39748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#ifndef BUILDING_MHD_LIB
40748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#ifdef _MHD_EXTERN
41748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#undef _MHD_EXTERN
42748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif /* _MHD_EXTERN */
43748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if defined(_WIN32) && defined(MHD_W32LIB)
44748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define _MHD_EXTERN extern
45748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#elif defined (_WIN32) && defined(MHD_W32DLL)
46748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define _MHD_EXTERN __declspec(dllimport)
47748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#else
48748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define _MHD_EXTERN extern
49748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
50748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#elif !defined(_MHD_EXTERN) /* && BUILDING_MHD_LIB */
51748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if defined(_WIN32) && defined(MHD_W32LIB)
52748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define _MHD_EXTERN extern
53748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#elif defined (_WIN32) && defined(MHD_W32DLL)
54748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define _MHD_EXTERN extern __declspec(dllexport)
55748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#else
56748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define _MHD_EXTERN extern
57748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
58748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif /* BUILDING_MHD_LIB */
59748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
60748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define _XOPEN_SOURCE_EXTENDED  1
61748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if OS390
62748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define _OPEN_THREADS
63748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define _OPEN_SYS_SOCK_IPV6
64748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define _OPEN_MSGQ_EXT
65748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define _LP64
66748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
67748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
68748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if defined(_WIN32)
69748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#ifndef _WIN32_WINNT
70748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define _WIN32_WINNT 0x0501
71748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#else // _WIN32_WINNT
72748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if _WIN32_WINNT < 0x0501
73748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#error "Headers for Windows XP or later are required"
74748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif // _WIN32_WINNT < 0x0501
75748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif // _WIN32_WINNT
76748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#ifndef WIN32_LEAN_AND_MEAN
77748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define WIN32_LEAN_AND_MEAN 1
78748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif /* !WIN32_LEAN_AND_MEAN */
79748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif // _WIN32
80748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
81748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <stdio.h>
82748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <stdlib.h>
83748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <stdint.h>
84748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <string.h>
85748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#ifdef HAVE_UNISTD_H
86748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <unistd.h>
87748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
88748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <stdarg.h>
89748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <errno.h>
90748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <fcntl.h>
91748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <signal.h>
92748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <stddef.h>
93748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#ifdef MHD_USE_POSIX_THREADS
94748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#undef HAVE_CONFIG_H
95748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <pthread.h>
96748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define HAVE_CONFIG_H 1
97748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif // MHD_USE_POSIX_THREADS
98748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
99748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/* different OSes have fd_set in
100748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat   a broad range of header files;
101748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat   we just include most of them (if they
102748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat   are available) */
103748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
104748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
105748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#ifdef OS_VXWORKS
106748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <sockLib.h>
107748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <netinet/in.h>
108748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <stdarg.h>
109748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <sys/mman.h>
110748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define RESTRICT __restrict__
111748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
112748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if HAVE_MEMORY_H
113748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <memory.h>
114748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
115748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
116748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if HAVE_SYS_SELECT_H
117748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <sys/select.h>
118748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
119748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if HAVE_SYS_TYPES_H
120748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <sys/types.h>
121748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
122748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if HAVE_SYS_TIME_H
123748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <sys/time.h>
124748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
125748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if HAVE_SYS_STAT_H
126748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <sys/stat.h>
127748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
128748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if HAVE_SYS_MSG_H
129748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <sys/msg.h>
130748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
131748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if HAVE_SYS_MMAN_H
132748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <sys/mman.h>
133748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
134748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if HAVE_NETDB_H
135748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <netdb.h>
136748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
137748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if HAVE_NETINET_IN_H
138748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <netinet/in.h>
139748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
140748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if HAVE_TIME_H
141748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <time.h>
142748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
143748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if HAVE_SYS_SOCKET_H
144748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <sys/socket.h>
145748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
146748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if HAVE_ARPA_INET_H
147748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <arpa/inet.h>
148748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
149748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
150748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
151748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if defined(_WIN32) && !defined(__CYGWIN__)
152748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <ws2tcpip.h>
153748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define sleep(seconds) (SleepEx((seconds)*1000, 1)/1000)
154748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define usleep(useconds) (void)SleepEx((useconds)/1000, 1)
155748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
156748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
157748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if !defined(SHUT_WR) && defined(SD_SEND)
158748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define SHUT_WR SD_SEND
159748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
160748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if !defined(SHUT_RD) && defined(SD_RECEIVE)
161748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define SHUT_RD SD_RECEIVE
162748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
163748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if !defined(SHUT_RDWR) && defined(SD_BOTH)
164748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define SHUT_RDWR SD_BOTH
165748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
166748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
167748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if defined(_MSC_FULL_VER) && !defined (_SSIZE_T_DEFINED)
168748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define _SSIZE_T_DEFINED
169748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erattypedef intptr_t ssize_t;
170748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif // !_SSIZE_T_DEFINED */
171748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#ifndef MHD_SOCKET_DEFINED
172748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/**
173748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat * MHD_socket is type for socket FDs
174748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat */
175748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if !defined(_WIN32) || defined(_SYS_TYPES_FD_SET)
176748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define MHD_POSIX_SOCKETS 1
177748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erattypedef int MHD_socket;
178748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define MHD_INVALID_SOCKET (-1)
179748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#else /* !defined(_WIN32) || defined(_SYS_TYPES_FD_SET) */
180748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define MHD_WINSOCK_SOCKETS 1
181748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#include <winsock2.h>
182748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erattypedef SOCKET MHD_socket;
183748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define MHD_INVALID_SOCKET (INVALID_SOCKET)
184748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif /* !defined(_WIN32) || defined(_SYS_TYPES_FD_SET) */
185748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define MHD_SOCKET_DEFINED 1
186748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif /* MHD_SOCKET_DEFINED */
187748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
188748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/* Force don't use pipes on W32 */
189748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if defined(_WIN32) && !defined(MHD_DONT_USE_PIPES)
190748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define MHD_DONT_USE_PIPES 1
191748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif /* defined(_WIN32) && !defined(MHD_DONT_USE_PIPES) */
192748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
193748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/* MHD_pipe is type for pipe FDs*/
194748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#ifndef MHD_DONT_USE_PIPES
195748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erattypedef int MHD_pipe;
196748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#else /* ! MHD_DONT_USE_PIPES */
197748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erattypedef MHD_socket MHD_pipe;
198748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif /* ! MHD_DONT_USE_PIPES */
199748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
200748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#if !defined(IPPROTO_IPV6) && defined(_MSC_FULL_VER) && _WIN32_WINNT >= 0x0501
201748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat/* VC use IPPROTO_IPV6 as part of enum */
202748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#define IPPROTO_IPV6 IPPROTO_IPV6
203748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
204748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat
205748945ec6f1c67b7efc934ab0808e1d32f2fb98dDaniel Erat#endif
206