libmicrohttpd2

HTTP server C library (MHD 2.x, alpha)
Log | Files | Refs | README | LICENSE

lib_get_info.c (20575B)


      1 /* SPDX-License-Identifier: LGPL-2.1-or-later OR (GPL-2.0-or-later WITH eCos-exception-2.0) */
      2 /*
      3   This file is part of GNU libmicrohttpd.
      4   Copyright (C) 2024-2025 Evgeny Grin (Karlson2k)
      5 
      6   GNU libmicrohttpd is free software; you can redistribute it and/or
      7   modify it under the terms of the GNU Lesser General Public
      8   License as published by the Free Software Foundation; either
      9   version 2.1 of the License, or (at your option) any later version.
     10 
     11   GNU libmicrohttpd is distributed in the hope that it will be useful,
     12   but WITHOUT ANY WARRANTY; without even the implied warranty of
     13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14   Lesser General Public License for more details.
     15 
     16   Alternatively, you can redistribute GNU libmicrohttpd and/or
     17   modify it under the terms of the GNU General Public License as
     18   published by the Free Software Foundation; either version 2 of
     19   the License, or (at your option) any later version, together
     20   with the eCos exception, as follows:
     21 
     22     As a special exception, if other files instantiate templates or
     23     use macros or inline functions from this file, or you compile this
     24     file and link it with other works to produce a work based on this
     25     file, this file does not by itself cause the resulting work to be
     26     covered by the GNU General Public License. However the source code
     27     for this file must still be made available in accordance with
     28     section (3) of the GNU General Public License v2.
     29 
     30     This exception does not invalidate any other reasons why a work
     31     based on this file might be covered by the GNU General Public
     32     License.
     33 
     34   You should have received copies of the GNU Lesser General Public
     35   License and the GNU General Public License along with this library;
     36   if not, see <https://www.gnu.org/licenses/>.
     37 */
     38 
     39 /**
     40  * @file src/mhd2/lib_get_info.c
     41  * @brief  The implementation of MHD_lib_get_info_*() functions
     42  * @author Karlson2k (Evgeny Grin)
     43  */
     44 
     45 #include "mhd_sys_options.h"
     46 
     47 #include "sys_bool_type.h"
     48 #include "sys_base_types.h"
     49 
     50 #include "mhd_assert.h"
     51 
     52 #include "mhd_str_types.h"
     53 #include "mhd_str_macros.h"
     54 
     55 #include <string.h>
     56 
     57 #include "sys_sockets_headers.h"
     58 #include "sys_ip_headers.h"
     59 
     60 #ifdef MHD_SUPPORT_THREADS
     61 #  include "mhd_threads.h"
     62 #endif
     63 
     64 #include "mhd_itc.h"
     65 
     66 #ifndef VERSION
     67 #  include "mhd_str.h"
     68 #endif
     69 
     70 #ifdef MHD_SUPPORT_HTTPS
     71 #  include "mhd_tls_choice.h"
     72 /* Include all supported TLS backends headers */
     73 #  if defined(MHD_SUPPORT_GNUTLS)
     74 #    include "tls_gnu_funcs.h"
     75 #  endif
     76 #  if defined(MHD_SUPPORT_OPENSSL)
     77 #    include "tls_open_funcs.h"
     78 #  endif
     79 #  if defined(MHD_SUPPORT_MBEDTLS)
     80 #    include "tls_mbed_funcs.h"
     81 #  endif
     82 #endif
     83 
     84 #ifdef MHD_SUPPORT_MD5
     85 #  include "mhd_md5.h"
     86 #endif
     87 #ifdef MHD_SUPPORT_SHA256
     88 #  include "mhd_sha256.h"
     89 #endif
     90 #ifdef MHD_SUPPORT_SHA512_256
     91 #  include "mhd_sha512_256.h"
     92 #endif
     93 
     94 #include "mhd_lib_init.h"
     95 
     96 #ifdef HAVE_SYS_TYPES_H
     97 #  include <sys/types.h>
     98 #endif
     99 
    100 #include "mhd_public_api.h"
    101 
    102 
    103 MHD_EXTERN_
    104 MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_OUT_ (2) enum MHD_StatusCode
    105 MHD_lib_get_info_fixed_sz (enum MHD_LibInfoFixed info_type,
    106                            union MHD_LibInfoFixedData *MHD_RESTRICT output_buf,
    107                            size_t output_buf_size)
    108 {
    109   if (0 != output_buf_size)
    110     memset (output_buf, 0, output_buf_size); /* For forward-compatibility */
    111 
    112   switch (info_type)
    113   {
    114 
    115   /* * Basic MHD information * */
    116 
    117   case MHD_LIB_INFO_FIXED_VERSION_NUM:
    118     if (sizeof(output_buf->v_version_num_uint32) > output_buf_size)
    119       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    120 #if ! MHD_VERSION
    121 #error MHD_VERSION is not defined
    122 #endif
    123     output_buf->v_version_num_uint32 = (uint_fast32_t) MHD_VERSION;
    124     return MHD_SC_OK;
    125   case MHD_LIB_INFO_FIXED_VERSION_STRING:
    126     if (sizeof(output_buf->v_version_string) <= output_buf_size)
    127     {
    128 #ifdef VERSION
    129       static const struct MHD_String ver_str =
    130         mhd_MSTR_INIT (VERSION);
    131       output_buf->v_version_string = ver_str;
    132       return MHD_SC_OK;
    133 #else  /* ! VERSION */
    134       static char str_buf[10] =    /* Larger than needed */
    135       {0, 1, 1, 1, 1, 1, 1, 1, 1, 1};
    136       static size_t str_len = 0;
    137       if ((0 == str_len) ||
    138           (0 != str_buf[str_len]))
    139       {
    140         const uint_fast32_t ver_num = MHD_VERSION;
    141         size_t pos = 0;
    142 
    143         mhd_assert (0 == str_buf[0]);
    144 
    145         pos += mhd_uint32_to_strx ((ver_num >> 24) & 0xFFu,
    146                                    str_buf + pos,
    147                                    sizeof(str_buf) - 1 - pos);
    148         mhd_assert (1 <= pos);
    149         mhd_assert (2 >= pos);
    150 
    151         str_buf[pos++] = '.';
    152 
    153         pos += mhd_uint32_to_strx ((ver_num >> 16) & 0xFFu,
    154                                    str_buf + pos,
    155                                    sizeof(str_buf) - 1 - pos);
    156         mhd_assert (3 <= pos);
    157         mhd_assert (5 >= pos);
    158 
    159         str_buf[pos++] = '.';
    160 
    161         pos += mhd_uint32_to_strx ((ver_num >> 8) & 0xFFu,
    162                                    str_buf + pos,
    163                                    sizeof(str_buf) - 1 - pos);
    164         mhd_assert (5 <= pos);
    165         mhd_assert (8 >= pos);
    166         mhd_assert (sizeof(str_buf) > pos);
    167 
    168         str_buf[pos] = 0;
    169         str_len = pos;
    170       }
    171       output_buf->v_version_string.cstr = str_buf;
    172       output_buf->v_version_string.len = str_len;
    173       return MHD_SC_OK;
    174 #endif /* ! VERSION */
    175     }
    176     return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    177 
    178   /* * Basic MHD features, buid-time configurable * */
    179 
    180   case MHD_LIB_INFO_FIXED_SUPPORT_LOG_MESSAGES:
    181     if (sizeof(output_buf->v_support_log_messages_bool) > output_buf_size)
    182       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    183 #ifdef MHD_SUPPORT_LOG_FUNCTIONALITY
    184     output_buf->v_support_log_messages_bool = MHD_YES;
    185 #else
    186     output_buf->v_support_log_messages_bool = MHD_NO;
    187 #endif
    188     return MHD_SC_OK;
    189   case MHD_LIB_INFO_FIXED_SUPPORT_AUTO_REPLIES_BODIES:
    190     if (sizeof(output_buf->v_support_auto_replies_bodies_bool) >
    191         output_buf_size)
    192       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    193 #ifdef MHD_ENABLE_AUTO_MESSAGES_BODIES
    194     output_buf->v_support_auto_replies_bodies_bool = MHD_YES;
    195 #else
    196     output_buf->v_support_auto_replies_bodies_bool = MHD_NO;
    197 #endif
    198     return MHD_SC_OK;
    199   case MHD_LIB_INFO_FIXED_IS_NON_DEBUG:
    200     if (sizeof(output_buf->v_is_non_debug_bool) > output_buf_size)
    201       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    202 #ifdef NDEBUG
    203     output_buf->v_is_non_debug_bool = MHD_YES;
    204 #else
    205     output_buf->v_is_non_debug_bool = MHD_NO;
    206 #endif
    207     return MHD_SC_OK;
    208   case MHD_LIB_INFO_FIXED_SUPPORT_THREADS:
    209     if (sizeof(output_buf->v_support_threads_bool) > output_buf_size)
    210       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    211 #ifdef MHD_SUPPORT_THREADS
    212     output_buf->v_support_threads_bool = MHD_YES;
    213 #else
    214     output_buf->v_support_threads_bool = MHD_NO;
    215 #endif
    216     return MHD_SC_OK;
    217   case MHD_LIB_INFO_FIXED_SUPPORT_COOKIE_PARSER:
    218     if (sizeof(output_buf->v_support_cookie_parser_bool) > output_buf_size)
    219       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    220 #ifdef MHD_SUPPORT_COOKIES
    221     output_buf->v_support_cookie_parser_bool = MHD_YES;
    222 #else
    223     output_buf->v_support_cookie_parser_bool = MHD_NO;
    224 #endif
    225     return MHD_SC_OK;
    226   case MHD_LIB_INFO_FIXED_SUPPORT_POST_PARSER:
    227     if (sizeof(output_buf->v_support_post_parser_bool) > output_buf_size)
    228       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    229 #ifdef MHD_SUPPORT_POST_PARSER
    230     output_buf->v_support_post_parser_bool = MHD_YES;
    231 #else
    232     output_buf->v_support_post_parser_bool = MHD_NO;
    233 #endif
    234     return MHD_SC_OK;
    235   case MHD_LIB_INFO_FIXED_SUPPORT_UPGRADE:
    236     if (sizeof(output_buf->v_support_upgrade_bool) > output_buf_size)
    237       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    238 #ifdef MHD_SUPPORT_UPGRADE
    239     output_buf->v_support_upgrade_bool = MHD_YES;
    240 #else
    241     output_buf->v_support_upgrade_bool = MHD_NO;
    242 #endif
    243     return MHD_SC_OK;
    244   case MHD_LIB_INFO_FIXED_SUPPORT_AUTH_BASIC:
    245     if (sizeof(output_buf->v_support_auth_basic_bool) > output_buf_size)
    246       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    247 #ifdef MHD_SUPPORT_AUTH_BASIC
    248     output_buf->v_support_auth_basic_bool = MHD_YES;
    249 #else
    250     output_buf->v_support_auth_basic_bool = MHD_NO;
    251 #endif
    252     return MHD_SC_OK;
    253   case MHD_LIB_INFO_FIXED_SUPPORT_AUTH_DIGEST:
    254   case MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_RFC2069:
    255   case MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_USERHASH:
    256     /* Simplified code: values of 'v_support_auth_digest_bool',
    257        'v_support_digest_auth_rfc2069_bool' and
    258        'v_support_digest_auth_userhash_bool' are always the same.
    259        To minimise the code size, use only the first member. The application
    260        gets correct resulting values for all members. */
    261     if (sizeof(output_buf->v_support_auth_digest_bool) > output_buf_size)
    262       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    263 #ifdef MHD_SUPPORT_AUTH_DIGEST
    264     output_buf->v_support_auth_digest_bool = MHD_YES;
    265 #else
    266     output_buf->v_support_auth_digest_bool = MHD_NO;
    267 #endif
    268     return MHD_SC_OK;
    269   case MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_MD5:
    270     if (sizeof(output_buf->v_type_digest_auth_md5_algo_type) > output_buf_size)
    271       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    272 #if ! defined(MHD_SUPPORT_MD5)
    273     output_buf->v_type_digest_auth_md5_algo_type =
    274       MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_NOT_AVAILABLE;
    275 #elif ! defined(MHD_MD5_EXTR)
    276     output_buf->v_type_digest_auth_md5_algo_type =
    277       MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_BUILT_IN;
    278 #elif ! defined(mhd_MD5_HAS_EXT_ERROR)
    279     output_buf->v_type_digest_auth_md5_algo_type =
    280       MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_EXTERNAL_NEVER_FAIL;
    281 #else
    282     output_buf->v_type_digest_auth_md5_algo_type =
    283       MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_EXTERNAL_MAY_FAIL;
    284 #endif
    285     return MHD_SC_OK;
    286   case MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_SHA256:
    287     if (sizeof(output_buf->v_type_digest_auth_sha256_algo_type) >
    288         output_buf_size)
    289       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    290 #if ! defined(MHD_SUPPORT_SHA256)
    291     output_buf->v_type_digest_auth_sha256_algo_type =
    292       MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_NOT_AVAILABLE;
    293 #elif ! defined(MHD_SHA256_EXTR)
    294     output_buf->v_type_digest_auth_sha256_algo_type =
    295       MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_BUILT_IN;
    296 #elif ! defined(mhd_SHA256_HAS_EXT_ERROR)
    297     output_buf->v_type_digest_auth_sha256_algo_type =
    298       MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_EXTERNAL_NEVER_FAIL;
    299 #else
    300     output_buf->v_type_digest_auth_sha256_algo_type =
    301       MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_EXTERNAL_MAY_FAIL;
    302 #endif
    303     return MHD_SC_OK;
    304   case MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_SHA512_256:
    305     if (sizeof(output_buf->v_type_digest_auth_sha512_256_algo_type) >
    306         output_buf_size)
    307       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    308 #if ! defined(MHD_SUPPORT_SHA512_256)
    309     output_buf->v_type_digest_auth_sha512_256_algo_type =
    310       MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_NOT_AVAILABLE;
    311 #elif ! defined(MHD_SHA512_256_EXTR)
    312     output_buf->v_type_digest_auth_sha512_256_algo_type =
    313       MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_BUILT_IN;
    314 #elif ! defined(mhd_SHA512_256_HAS_EXT_ERROR)
    315     output_buf->v_type_digest_auth_sha512_256_algo_type =
    316       MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_EXTERNAL_NEVER_FAIL;
    317 #else
    318     output_buf->v_type_digest_auth_sha512_256_algo_type =
    319       MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_EXTERNAL_MAY_FAIL;
    320 #endif
    321     return MHD_SC_OK;
    322   case MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_AUTH_INT:
    323   case MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_ALGO_SESSION:
    324     /* Simplified code: values of 'v_support_digest_auth_auth_int_bool' and
    325        'v_support_digest_auth_algo_session_bool' are always the same.
    326        To minimise the code size, use only the first member. The application
    327        gets correct resulting values for all members. */
    328     if (sizeof(output_buf->v_support_digest_auth_auth_int_bool) >
    329         output_buf_size)
    330       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    331     output_buf->v_support_digest_auth_auth_int_bool = MHD_NO;
    332     return MHD_SC_OK;
    333 
    334   /* * Platform-dependent features, some are configurable at build-time * */
    335 
    336   case MHD_LIB_INFO_FIXED_TYPES_SOCKETS_POLLING:
    337     if (sizeof(output_buf->v_types_sockets_polling) > output_buf_size)
    338       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    339 #ifdef MHD_SUPPORT_SELECT
    340     output_buf->v_types_sockets_polling.func_select = MHD_YES;
    341 #else
    342     output_buf->v_types_sockets_polling.func_select = MHD_NO;
    343 #endif
    344 #ifdef MHD_SUPPORT_POLL
    345     output_buf->v_types_sockets_polling.func_poll = MHD_YES;
    346 #else
    347     output_buf->v_types_sockets_polling.func_poll = MHD_NO;
    348 #endif
    349 #ifdef MHD_SUPPORT_EPOLL
    350     output_buf->v_types_sockets_polling.tech_epoll = MHD_YES;
    351 #else
    352     output_buf->v_types_sockets_polling.tech_epoll = MHD_NO;
    353 #endif
    354     return MHD_SC_OK;
    355   case MHD_LIB_INFO_FIXED_SUPPORT_AGGREGATE_FD:
    356     if (sizeof(output_buf->v_support_aggregate_fd_bool) > output_buf_size)
    357       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    358 #ifdef MHD_SUPPORT_EPOLL
    359     output_buf->v_support_aggregate_fd_bool = MHD_YES;
    360 #else
    361     output_buf->v_support_aggregate_fd_bool = MHD_NO;
    362 #endif
    363     return MHD_SC_OK;
    364   case MHD_LIB_INFO_FIXED_TYPE_IPV6:
    365     if (sizeof(output_buf->v_ipv6) > output_buf_size)
    366       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    367 #if ! defined(HAVE_INET6)
    368     output_buf->v_ipv6 = MHD_LIB_INFO_FIXED_IPV6_TYPE_NONE;
    369 #elif ! defined(HAVE_DCLR_IPV6_V6ONLY)
    370     output_buf->v_ipv6 = MHD_LIB_INFO_FIXED_IPV6_TYPE_DUAL_ONLY;
    371 #else
    372     output_buf->v_ipv6 = MHD_LIB_INFO_FIXED_IPV6_TYPE_IPV6_PURE;
    373 #endif
    374     return MHD_SC_OK;
    375   case MHD_LIB_INFO_FIXED_SUPPORT_TCP_FASTOPEN:
    376     if (sizeof(output_buf->v_support_tcp_fastopen_bool) > output_buf_size)
    377       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    378 #ifdef HAVE_DCLR_TCP_FASTOPEN
    379     output_buf->v_support_tcp_fastopen_bool = MHD_YES;
    380 #else
    381     output_buf->v_support_tcp_fastopen_bool = MHD_NO;
    382 #endif
    383     return MHD_SC_OK;
    384   case MHD_LIB_INFO_FIXED_HAS_AUTODETECT_BIND_PORT:
    385     if (sizeof(output_buf->v_has_autodetect_bind_port_bool) > output_buf_size)
    386       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    387 #ifdef MHD_USE_GETSOCKNAME
    388     output_buf->v_has_autodetect_bind_port_bool = MHD_YES;
    389 #else
    390     output_buf->v_has_autodetect_bind_port_bool = MHD_NO;
    391 #endif
    392     return MHD_SC_OK;
    393   case MHD_LIB_INFO_FIXED_HAS_SENDFILE:
    394     if (sizeof(output_buf->v_has_sendfile_bool) > output_buf_size)
    395       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    396 #ifdef mhd_USE_SENDFILE
    397     output_buf->v_has_sendfile_bool = MHD_YES;
    398 #else
    399     output_buf->v_has_sendfile_bool = MHD_NO;
    400 #endif
    401     return MHD_SC_OK;
    402   case MHD_LIB_INFO_FIXED_HAS_AUTOSUPPRESS_SIGPIPE_INT:
    403     if (sizeof(output_buf->v_has_autosuppress_sigpipe_int_bool) >
    404         output_buf_size)
    405       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    406 #if ! defined (mhd_SEND_SPIPE_SUPPRESS_NEEDED)
    407     output_buf->v_has_autosuppress_sigpipe_int_bool = MHD_YES;
    408 #elif defined (mhd_SEND_SPIPE_SUPPRESS_POSSIBLE) \
    409     || defined(mhd_HAVE_MHD_THREAD_BLOCK_SIGPIPE)
    410     output_buf->v_has_autosuppress_sigpipe_int_bool = MHD_YES;
    411 #else
    412     output_buf->v_has_autosuppress_sigpipe_int_bool = MHD_NO;
    413 #endif
    414     return MHD_SC_OK;
    415   case MHD_LIB_INFO_FIXED_HAS_AUTOSUPPRESS_SIGPIPE_EXT:
    416     if (sizeof(output_buf->v_has_autosuppress_sigpipe_ext_bool) >
    417         output_buf_size)
    418       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    419 #if ! defined (mhd_SEND_SPIPE_SUPPRESS_NEEDED)
    420     output_buf->v_has_autosuppress_sigpipe_ext_bool = MHD_YES;
    421 #elif defined (mhd_SEND_SPIPE_SUPPRESS_POSSIBLE)
    422     output_buf->v_has_autosuppress_sigpipe_ext_bool = MHD_YES;
    423 #else
    424     output_buf->v_has_autosuppress_sigpipe_ext_bool = MHD_NO;
    425 #endif
    426     return MHD_SC_OK;
    427   case MHD_LIB_INFO_FIXED_HAS_THREAD_NAMES:
    428     if (sizeof(output_buf->v_has_thread_names_bool) > output_buf_size)
    429       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    430 #ifdef mhd_USE_THREAD_NAME
    431     output_buf->v_has_thread_names_bool = MHD_YES;
    432 #else
    433     output_buf->v_has_thread_names_bool = MHD_NO;
    434 #endif
    435     return MHD_SC_OK;
    436   case MHD_LIB_INFO_FIXED_TYPE_ITC:
    437     if (sizeof(output_buf->v_type_itc) > output_buf_size)
    438       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    439 #if ! defined(MHD_SUPPORT_THREADS)
    440     output_buf->v_type_itc = MHD_LIB_INFO_FIXED_ITC_TYPE_NONE;
    441 #elif defined(MHD_ITC_SOCKETPAIR_)
    442     output_buf->v_type_itc = MHD_LIB_INFO_FIXED_ITC_TYPE_SOCKETPAIR;
    443 #elif defined(MHD_ITC_PIPE_)
    444     output_buf->v_type_itc = MHD_LIB_INFO_FIXED_ITC_TYPE_PIPE;
    445 #elif defined(MHD_ITC_EVENTFD_)
    446     output_buf->v_type_itc = MHD_LIB_INFO_FIXED_ITC_TYPE_EVENTFD;
    447 #else
    448 #error The type of ITC is not defined
    449 #endif
    450     return MHD_SC_OK;
    451   case MHD_LIB_INFO_FIXED_SUPPORT_LARGE_FILE:
    452     if (sizeof(output_buf->v_support_large_file_bool) > output_buf_size)
    453       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    454 #if ! defined(HAVE_PREAD) && defined(lseek64)
    455     output_buf->v_support_large_file_bool = MHD_YES;
    456 #elif defined(HAVE_PREAD64)
    457     output_buf->v_support_large_file_bool = MHD_YES;
    458 #elif defined(mhd_W32_NATIVE)
    459     output_buf->v_support_large_file_bool = MHD_YES;
    460 #else
    461     output_buf->v_support_large_file_bool =
    462       (0x7FFFFFFFFFFFFFFF == ((off_t) 0x7FFFFFFFFFFFFFFF)) ? MHD_YES : MHD_NO;
    463 #endif
    464     return MHD_SC_OK;
    465   case MHD_LIB_INFO_FIXED_TLS_BACKENDS:
    466   case MHD_LIB_INFO_FIXED_TLS_KEY_PASSWORD_BACKENDS: /* Both backends have support */
    467     /* Simplified code: values of 'v_tls_backends' and
    468        'v_tls_key_password_backends' are always the same.
    469        To minimise the code size, use only the first member. The application
    470        gets correct resulting values for all members. */
    471     if (sizeof(output_buf->v_tls_backends) <= output_buf_size)
    472     {
    473 #ifndef MHD_SUPPORT_HTTPS
    474       output_buf->v_tls_backends.tls_supported = MHD_NO;
    475       output_buf->v_tls_backends.backend_gnutls = MHD_NO;
    476       output_buf->v_tls_backends.backend_openssl = MHD_NO;
    477 #else
    478       output_buf->v_tls_backends.tls_supported = MHD_YES;
    479 #  ifdef MHD_SUPPORT_GNUTLS
    480       output_buf->v_tls_backends.backend_gnutls = MHD_YES;
    481 #  else  /* ! MHD_SUPPORT_GNUTLS */
    482       output_buf->v_tls_backends.backend_gnutls = MHD_NO;
    483 #  endif /* ! MHD_SUPPORT_GNUTLS */
    484 #  ifdef MHD_SUPPORT_OPENSSL
    485       output_buf->v_tls_backends.backend_openssl = MHD_YES;
    486 #  else  /* ! MHD_SUPPORT_OPENSSL */
    487       output_buf->v_tls_backends.backend_openssl = MHD_NO;
    488 #  endif /* ! MHD_SUPPORT_OPENSSL */
    489 #endif
    490       return MHD_SC_OK;
    491     }
    492     return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    493     break;
    494   case MHD_LIB_INFO_FIXED_SENTINEL:
    495   default:
    496     break;
    497   }
    498   return MHD_SC_INFO_GET_TYPE_UNKNOWN;
    499 }
    500 
    501 
    502 MHD_EXTERN_ MHD_FN_MUST_CHECK_RESULT_
    503 MHD_FN_PAR_NONNULL_ (2)
    504 MHD_FN_PAR_OUT_ (2) enum MHD_StatusCode
    505 MHD_lib_get_info_dynamic_sz (
    506   enum MHD_LibInfoDynamic info_type,
    507   union MHD_LibInfoDynamicData *MHD_RESTRICT output_buf,
    508   size_t output_buf_size)
    509 {
    510   if (0 != output_buf_size)
    511     memset (output_buf, 0, output_buf_size); /* For forward-compatibility */
    512 
    513   switch (info_type)
    514   {
    515   case MHD_LIB_INFO_DYNAMIC_INITED_FULLY_ONCE:
    516     if (sizeof(output_buf->v_inited_fully_once_bool) > output_buf_size)
    517       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    518     output_buf->v_inited_fully_once_bool =
    519       mhd_lib_is_fully_initialised_once () ? MHD_YES : MHD_NO;
    520     return MHD_SC_OK;
    521   case MHD_LIB_INFO_DYNAMIC_INITED_FULLY_NOW:
    522     if (sizeof(output_buf->v_inited_fully_now_bool) > output_buf_size)
    523       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    524     output_buf->v_inited_fully_now_bool =
    525       mhd_lib_is_fully_initialised_now () ? MHD_YES : MHD_NO;
    526     return MHD_SC_OK;
    527   case MHD_LIB_INFO_DYNAMIC_TYPE_TLS:
    528     if (sizeof(output_buf->v_tls_backends) <= output_buf_size)
    529     {
    530 #ifndef MHD_SUPPORT_HTTPS
    531       output_buf->v_tls_backends.tls_supported = MHD_NO;
    532       output_buf->v_tls_backends.backend_gnutls = MHD_NO;
    533       output_buf->v_tls_backends.backend_openssl = MHD_NO;
    534       output_buf->v_tls_backends.backend_mbedtls = MHD_NO;
    535 #else
    536       bool gnutls_avail;
    537       bool openssl_avail;
    538       bool mdedtls_avail;
    539 
    540       if (! mhd_lib_init_global_if_needed ())
    541         return MHD_SC_INFO_GET_TYPE_UNOBTAINABLE;
    542 
    543       gnutls_avail = mhd_tls_gnu_is_inited_fine ();
    544       openssl_avail = mhd_tls_open_is_inited_fine ();
    545       mdedtls_avail = mhd_tls_mbed_is_inited_fine ();
    546 
    547       output_buf->v_tls_backends.tls_supported =
    548         (gnutls_avail || openssl_avail) ? MHD_YES : MHD_NO;
    549       output_buf->v_tls_backends.backend_gnutls =
    550         gnutls_avail ? MHD_YES : MHD_NO;
    551       output_buf->v_tls_backends.backend_openssl =
    552         openssl_avail ? MHD_YES : MHD_NO;
    553       output_buf->v_tls_backends.backend_mbedtls =
    554         mdedtls_avail ? MHD_YES : MHD_NO;
    555 
    556       mhd_lib_deinit_global_if_needed ();
    557 #endif
    558       return MHD_SC_OK;
    559     }
    560     return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    561   case MHD_LIB_INFO_DYNAMIC_SENTINEL:
    562   default:
    563     break;
    564   }
    565   return MHD_SC_INFO_GET_TYPE_UNKNOWN;
    566 }