# HG changeset patch # User Sebastien Decugis # Date 1559486368 -28800 # Node ID 09f94b1bedc32b58f5762e48c197f9efa293e4b9 # Parent cf411b1dcbbbf3908ab81e89560661aa474f2c4a# Parent 23db8abdccda6ab4eed6057333a5d398a6a8cc29 Merge new proposed changes diff -r 23db8abdccda -r 09f94b1bedc3 doc/acl_wl.conf.sample --- a/doc/acl_wl.conf.sample Sun Jun 02 22:34:59 2019 +0800 +++ b/doc/acl_wl.conf.sample Sun Jun 02 22:39:28 2019 +0800 @@ -3,6 +3,11 @@ # This extension is meant to allow connection from remote peers, without actively # maintaining this connection ourselves (as it would be the case by declaring the # peer in a ConnectPeer directive). +# +# This extension supports configuration reload at runtime. Send +# signal SIGUSR1 to the process to cause the process to reload its +# config. +# # The format of this file is very simple. It contains a list of peer names # separated by spaces or newlines. # diff -r 23db8abdccda -r 09f94b1bedc3 extensions/acl_wl/acl_wl.c --- a/extensions/acl_wl/acl_wl.c Sun Jun 02 22:34:59 2019 +0800 +++ b/extensions/acl_wl/acl_wl.c Sun Jun 02 22:39:28 2019 +0800 @@ -37,8 +37,17 @@ * Whitelist extension for freeDiameter. */ +#include +#include + #include "acl_wl.h" +static pthread_rwlock_t acl_wl_lock; + +#define MODULE_NAME "acl_wl" + +static char *acl_wl_config_file; + /* The validator function */ static int aw_validate(struct peer_info * info, int * auth, int (**cb2)(struct peer_info *)) { @@ -53,9 +62,20 @@ /* Default to unknown result */ *auth = 0; - + + if (pthread_rwlock_rdlock(&acl_wl_lock) != 0) { + fd_log_notice("%s: read-lock failed, skipping handler", MODULE_NAME); + return 0; + } + /* Now search the peer in our tree */ CHECK_FCT( aw_tree_lookup(info->pi_diamid, &res) ); + + if (pthread_rwlock_unlock(&acl_wl_lock) != 0) { + fd_log_notice("%s: read-unlock failed after aw_tree_lookup, exiting", MODULE_NAME); + exit(1); + } + if (res < 0) { /* The peer is not whitelisted */ return 0; @@ -87,20 +107,82 @@ return 0; } +static volatile int in_signal_handler = 0; + +/* signal handler */ +static void sig_hdlr(void) +{ + struct fd_list old_tree; + + if (in_signal_handler) { + fd_log_error("%s: already handling a signal, ignoring new one", MODULE_NAME); + return; + } + in_signal_handler = 1; + + if (pthread_rwlock_wrlock(&acl_wl_lock) != 0) { + fd_log_error("%s: locking failed, aborting config reload", MODULE_NAME); + return; + } + + /* save old config in case reload goes wrong */ + old_tree = tree_root; + fd_list_init(&tree_root, NULL); + + if (aw_conf_handle(acl_wl_config_file) != 0) { + fd_log_error("%s: error reloading configuration, restoring previous configuration", MODULE_NAME); + aw_tree_destroy(); + tree_root = old_tree; + } else { + struct fd_list new_tree; + new_tree = tree_root; + tree_root = old_tree; + aw_tree_destroy(); + tree_root = new_tree; + } + + if (pthread_rwlock_unlock(&acl_wl_lock) != 0) { + fd_log_error("%s: unlocking failed after config reload, exiting", MODULE_NAME); + exit(1); + } + + fd_log_notice("%s: reloaded configuration", MODULE_NAME); + + in_signal_handler = 0; +} + + /* entry point */ static int aw_entry(char * conffile) { TRACE_ENTRY("%p", conffile); CHECK_PARAMS(conffile); - + + acl_wl_config_file = conffile; + + pthread_rwlock_init(&acl_wl_lock, NULL); + + if (pthread_rwlock_wrlock(&acl_wl_lock) != 0) { + fd_log_notice("%s: write-lock failed, aborting", MODULE_NAME); + return EDEADLK; + } + /* Parse configuration file */ CHECK_FCT( aw_conf_handle(conffile) ); - + TRACE_DEBUG(INFO, "Extension ACL_wl initialized with configuration: '%s'", conffile); if (TRACE_BOOL(ANNOYING)) { aw_tree_dump(); } - + + if (pthread_rwlock_unlock(&acl_wl_lock) != 0) { + fd_log_notice("%s: write-unlock failed, aborting", MODULE_NAME); + return EDEADLK; + } + + /* Register reload callback */ + CHECK_FCT(fd_event_trig_regcb(SIGUSR1, MODULE_NAME, sig_hdlr)); + /* Register the validator function */ CHECK_FCT( fd_peer_validate_register ( aw_validate ) ); @@ -114,4 +196,4 @@ aw_tree_destroy(); } -EXTENSION_ENTRY("acl_wl", aw_entry); +EXTENSION_ENTRY(MODULE_NAME, aw_entry); diff -r 23db8abdccda -r 09f94b1bedc3 extensions/acl_wl/acl_wl.h --- a/extensions/acl_wl/acl_wl.h Sun Jun 02 22:34:59 2019 +0800 +++ b/extensions/acl_wl/acl_wl.h Sun Jun 02 22:39:28 2019 +0800 @@ -43,6 +43,8 @@ #include +extern struct fd_list tree_root; + /* Parse the configuration file */ int aw_conf_handle(char * conffile); diff -r 23db8abdccda -r 09f94b1bedc3 extensions/acl_wl/aw_conf.l --- a/extensions/acl_wl/aw_conf.l Sun Jun 02 22:34:59 2019 +0800 +++ b/extensions/acl_wl/aw_conf.l Sun Jun 02 22:39:28 2019 +0800 @@ -35,7 +35,7 @@ /* Lex extension's configuration parser. * - * The configuration file contains a default priority, and a list of peers with optional overwite priority. + * The configuration file contains a default priority, and a list of peers with optional overwrite priority. * -- see the app_test.conf.sample file for more detail. */ diff -r 23db8abdccda -r 09f94b1bedc3 extensions/acl_wl/aw_conf.y --- a/extensions/acl_wl/aw_conf.y Sun Jun 02 22:34:59 2019 +0800 +++ b/extensions/acl_wl/aw_conf.y Sun Jun 02 22:39:28 2019 +0800 @@ -57,6 +57,7 @@ /* Forward declaration */ int yyparse(char * conffile); +void aw_confrestart(FILE *input_file); static int fqdn_added = 0; @@ -74,19 +75,20 @@ if (aw_confin == NULL) { ret = errno; fd_log_debug("Unable to open extension configuration file %s for reading: %s", conffile, strerror(ret)); - TRACE_DEBUG (INFO, "Error occurred, message logged -- configuration file."); + TRACE_DEBUG (INFO, "acl_wl: Error occurred, message logged -- configuration file."); return ret; } + aw_confrestart(aw_confin); ret = yyparse(conffile); fclose(aw_confin); if (ret != 0) { - TRACE_DEBUG (INFO, "Unable to parse the configuration file."); + TRACE_DEBUG (INFO, "acl_wl: Unable to parse the configuration file."); return EINVAL; } else { - TRACE_DEBUG(FULL, "Read %d FQDN entries successfully.", fqdn_added); + TRACE_DEBUG(FULL, "acl_wl: Read %d FQDN entries successfully.", fqdn_added); } return 0; @@ -98,7 +100,7 @@ /* Function to report the errors */ void yyerror (YYLTYPE *ploc, char * conffile, char const *s) { - TRACE_DEBUG(INFO, "Error in configuration parsing"); + TRACE_DEBUG(INFO, "acl_wl: Error in configuration parsing"); if (ploc->first_line != ploc->last_line) fd_log_debug("%s:%d.%d-%d.%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_line, ploc->last_column, s); @@ -130,11 +132,11 @@ | conffile FQDN { fqdn_added++; - TRACE_DEBUG(FULL, "Added FQDN: %s", $2); + TRACE_DEBUG(FULL, "acl_wl: Added FQDN: %s", $2); } | conffile LEX_ERROR { - yyerror(&yylloc, conffile, "An error occurred while parsing the configuration file"); + yyerror(&yylloc, conffile, "acl_wl: An error occurred while parsing the configuration file"); return EINVAL; } ; diff -r 23db8abdccda -r 09f94b1bedc3 extensions/acl_wl/aw_tree.c --- a/extensions/acl_wl/aw_tree.c Sun Jun 02 22:34:59 2019 +0800 +++ b/extensions/acl_wl/aw_tree.c Sun Jun 02 22:39:28 2019 +0800 @@ -69,9 +69,9 @@ }; /* The root of the tree */ -static struct fd_list tree_root = FD_LIST_INITIALIZER(tree_root); +struct fd_list tree_root = FD_LIST_INITIALIZER(tree_root); -/* Note: we don't need to lock, since we add only when parsing the conf, and then read only */ +/* Note: we lock accesses to the tree with acl_wl_lock because of config reload */ /* The parsed name */ diff -r 23db8abdccda -r 09f94b1bedc3 extensions/dict_json/CMakeLists.txt --- a/extensions/dict_json/CMakeLists.txt Sun Jun 02 22:34:59 2019 +0800 +++ b/extensions/dict_json/CMakeLists.txt Sun Jun 02 22:39:28 2019 +0800 @@ -6,11 +6,12 @@ # We use JSONCPP and JSON-Schema to parse and validate JSON files PKG_CHECK_MODULES(JSONCPP REQUIRED jsoncpp) PKG_CHECK_MODULES(JSON_SCHEMA REQUIRED json-schema) +PKG_CHECK_MODULES(PCRECPP REQUIRED libpcrecpp) # List of source files SET(DICT_JSON_SRC dict_json.cc - dict_json_dict_schema.cc + ${CMAKE_CURRENT_BINARY_DIR}/dict_json_dict_schema.cc ) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) @@ -28,6 +29,14 @@ ADD_EXECUTABLE(dict-json-diff dict-json-diff.cc) TARGET_LINK_LIBRARIES(dict-json-diff ${JSONCPP_LIBRARIES} ${JSON_SCHEMA_STATIC_LIBRARIES}) +ADD_EXECUTABLE(json-schema-to-c json-schema-to-c.cc) +TARGET_LINK_LIBRARIES(json-schema-to-c ${JSONCPP_LIBRARIES} ${JSON_SCHEMA_STATIC_LIBRARIES} ${PCRECPP_LIBRARIES}) + +ADD_CUSTOM_COMMAND( + OUTPUT dict_json_dict_schema.cc + COMMAND json-schema-to-c ${CMAKE_CURRENT_SOURCE_DIR}/dict_json_dict_schema.json ${CMAKE_CURRENT_BINARY_DIR}/dict_json_dict_schema.cc + DEPENDS dict_json_dict_schema.json +) #### ## INSTALL section ## @@ -38,6 +47,3 @@ INSTALL(TARGETS dict-json-diff RUNTIME DESTINATION ${INSTALL_DAEMON_SUFFIX} COMPONENT freeDiameter-dictionary-json) - -# dict_json_dict_schema.cc is created from dict_json_dict_schema.json -# the tool for that is not yet open source, but the conversion is straightforward diff -r 23db8abdccda -r 09f94b1bedc3 extensions/dict_json/dict_json_dict_schema.cc --- a/extensions/dict_json/dict_json_dict_schema.cc Sun Jun 02 22:34:59 2019 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,164 +0,0 @@ -const char * dict_json_dict_schema = "\ -{ \n\ - \"definitions\": { \n\ - \"content\": { \n\ - \"type\": \"array\", \n\ - \"items\": { \n\ - \"type\": \"object\", \n\ - \"additionalProperties\": false, \n\ - \"required\": [ \"AVP\" ], \n\ - \"properties\": { \n\ - \"AVP\": { \"type\": \"string\" }, \n\ - \"Vendor\": { \"$ref\": \"#/definitions/unsigned-integer\" }, \n\ - \"First\": { \"type\": \"boolean\" }, \n\ - \"Min\": { \"$ref\": \"#/definitions/unsigned-integer\" }, \n\ - \"Max\": { \"anyOf\": [ { \"type\": \"integer\" }, { \"enum\": [ \"unbounded\" ] } ] } \n\ - } \n\ - } \n\ - }, \n\ - \n\ - \"identifier\": { \"type\": \"string\", \"pattern\": \"^[[:print:]]+$\" }, \n\ - \"type\": { \n\ - \"enum\": [ \n\ - \"Address\", \n\ - \"DiameterIdentity\", \n\ - \"DiameterURI\", \n\ - \"Enumerated\", \n\ - \"Float32\", \n\ - \"Float64\", \n\ - \"Grouped\", \n\ - \"Integer32\", \n\ - \"Integer64\", \n\ - \"IPFilterRule\", \n\ - \"OctetString\", \n\ - \"Time\", \n\ - \"Unsigned32\", \n\ - \"Unsigned64\", \n\ - \"UTF8String\" \n\ - ] \n\ - }, \n\ - \"unsigned-integer\": { \"type\": \"integer\", \"minimum\": 0 } \n\ - }, \n\ - \n\ - \"type\": \"object\", \n\ - \"additionalProperties\": false, \n\ - \"properties\": { \n\ - \"Vendors\": { \n\ - \"type\": \"array\", \n\ - \"items\": { \n\ - \"type\": \"object\", \n\ - \"additionalProperties\": false, \n\ - \"required\": [ \"Code\", \"Name\" ], \n\ - \"properties\": { \n\ - \"Code\": { \"$ref\": \"#/definitions/unsigned-integer\" }, \n\ - \"Name\": { \"$ref\": \"#/definitions/identifier\" } \n\ - } \n\ - } \n\ - }, \n\ - \"Types\": { \n\ - \"type\": \"array\", \n\ - \"items\": { \n\ - \"type\": \"object\", \n\ - \"additionalProperties\": false, \n\ - \"required\": [ \"Name\", \"Base\" ], \n\ - \"properties\": { \n\ - \"Name\": { \"type\": \"string\" }, \n\ - \"Base\": { \"type\": \"string\" } \n\ - } \n\ - } \n\ - }, \n\ - \"AVPs\": { \n\ - \"type\": \"array\", \n\ - \"items\": { \n\ - \"type\": \"object\", \n\ - \"additionalProperties\": false, \n\ - \"required\": [ \"Code\", \"Name\", \"Type\" ], \n\ - \"properties\": { \n\ - \"Code\": { \"$ref\": \"#/definitions/unsigned-integer\" }, \n\ - \"Vendor\": { \"$ref\": \"#/definitions/unsigned-integer\" }, \n\ - \"Name\": { \"$ref\": \"#/definitions/identifier\" }, \n\ - \"Flags\": { \n\ - \"type\": \"object\", \n\ - \"additionalProperties\": false, \n\ - \"properties\": { \n\ - \"Must\": { \"type\": \"string\", \"pattern\": \"^[VMP]*$\" }, \n\ - \"MustNot\": { \"type\": \"string\", \"pattern\": \"^[VMP]*$\" } \n\ - } \n\ - }, \n\ - \"Type\": { \"$ref\": \"#/definitions/identifier\" }, \n\ - \"EnumValues\": { \n\ - \"type\": \"array\", \n\ - \"items\": { \n\ - \"type\": \"object\", \n\ - \"additionalProperties\": false, \n\ - \"required\": [ \"Code\", \"Name\" ], \n\ - \"properties\": { \n\ - \"Code\": { \"anyOf\": [ { \"type\": \"integer\" }, { \"type\": \"number\" }, { \"type\": \"string\" } ] }, \n\ - \"Name\": { \"type\": \"string\", \"pattern\": \"^[[:print:]]*$\" } \n\ - } \n\ - } \n\ - } \n\ - } \n\ - } \n\ - }, \n\ - \"Applications\": { \n\ - \"type\": \"array\", \n\ - \"items\": { \n\ - \"type\": \"object\", \n\ - \"additionalProperties\": false, \n\ - \"required\": [ \"Code\", \"Name\" ], \n\ - \"properties\": { \n\ - \"Code\": { \"$ref\": \"#/definitions/unsigned-integer\" }, \n\ - \"Name\": { \"$ref\": \"#/definitions/identifier\" } \n\ - } \n\ - } \n\ - }, \n\ - \"Commands\": { \n\ - \"type\": \"array\", \n\ - \"items\": { \n\ - \"type\": \"object\", \n\ - \"additionalProperties\": false, \n\ - \"required\": [ \"Code\", \"Name\" ], \n\ - \"properties\": { \n\ - \"Code\": { \"$ref\": \"#/definitions/unsigned-integer\" }, \n\ - \"Name\": { \"$ref\": \"#/definitions/identifier\" }, \n\ - \"Application\": { \"$ref\": \"#/definitions/identifier\" }, \n\ - \"Flags\": { \n\ - \"type\": \"object\", \n\ - \"additionalProperties\": false, \n\ - \"properties\": { \n\ - \"Must\": { \"type\": \"string\", \"pattern\": \"^[RPE]*$\" }, \n\ - \"MustNot\": { \"type\": \"string\", \"pattern\": \"^[RPET]*$\" } \n\ - } \n\ - } \n\ - } \n\ - } \n\ - }, \n\ - \"CommandRules\": { \n\ - \"type\": \"array\", \n\ - \"items\": { \n\ - \"type\": \"object\", \n\ - \"additionalProperties\": false, \n\ - \"required\": [ \"Command\", \"Content\" ], \n\ - \"properties\": { \n\ - \"Command\": { \"type\": \"string\", \"minimum\": 0 }, \n\ - \"Content\": { \"$ref\": \"#/definitions/content\" } \n\ - } \n\ - } \n\ - }, \n\ - \"AVPRules\": { \n\ - \"type\": \"array\", \n\ - \"items\": { \n\ - \"type\": \"object\", \n\ - \"additionalProperties\": false, \n\ - \"required\": [ \"AVP\", \"Content\" ], \n\ - \"properties\": { \n\ - \"AVP\": { \"type\": \"string\" }, \n\ - \"Vendor\": { \"type\": \"integer\", \"minimum\" : 0 }, \n\ - \"Content\": { \"$ref\": \"#/definitions/content\" } \n\ - } \n\ - } \n\ - } \n\ - } \n\ -} \n\ -"; diff -r 23db8abdccda -r 09f94b1bedc3 extensions/dict_json/json-schema-to-c.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extensions/dict_json/json-schema-to-c.cc Sun Jun 02 22:39:28 2019 +0800 @@ -0,0 +1,350 @@ +/********************************************************************************************************** + * Software License Agreement (BSD License) * + * Author: Thomas Klausner * + * * + * Copyright (c) 2016, 2017, 2019 Thomas Klausner * + * All rights reserved. * + * * + * Written under contract by nfotex IT GmbH, http://nfotex.com/ * + * * + * Redistribution and use of this software in source and binary forms, with or without modification, are * + * permitted provided that the following conditions are met: * + * * + * * Redistributions of source code must retain the above * + * copyright notice, this list of conditions and the * + * following disclaimer. * + * * + * * Redistributions in binary form must reproduce the above * + * copyright notice, this list of conditions and the * + * following disclaimer in the documentation and/or other * + * materials provided with the distribution. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +[[noreturn]] +void usage(char *prg, int exit_status) { + FILE *f = (exit_status ? stderr : stdout); + + fprintf(f, "Usage: %s [-hV] [-i include] [-N variable-name] [-n namespace] [-t type] json [output]\n", prg); + fprintf(f, "options:\n\ + -h, --help print this usage message and exit\n\ + -i, --include FILE include FILE in output C source file\n\ + -n, --namespace NAME specify namespace in which to define variable\n\ + -N, --name NAME specify name of variable to define\n\ + --no-validate don't validate against JSON meta schema (default)\n\ + --type TYPE specify type of variable (char * (default) or std::string)\n\ + --validate validate against JSON meta schema\n\ + --validate-only validate against JSON meta schema and exit (don't create C source)\n\ +"); + + exit(exit_status); +} + +const char *OPTIONS = "hi:N:n:t:V"; + +enum { + OPT_NO_VALIDATE = 256, + OPT_VALIDATE_ONLY +}; +struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "include", required_argument, NULL, 'i' }, + { "name", required_argument, NULL, 'N' }, + { "namespace", required_argument, NULL, 'n' }, + { "no-validate", no_argument, NULL, OPT_NO_VALIDATE }, + { "type", required_argument, NULL, 't' }, + { "validate", no_argument, NULL, 'V' }, + { "validate-only", no_argument, NULL, OPT_VALIDATE_ONLY }, + { NULL, 0, NULL, 0 } +}; + +char *read_full_file (const char *filename, off_t max_size, off_t* size_ret, const char *desc) { + FILE *fp; + if ((fp = fopen (filename, "rb")) == NULL) { + fprintf (stderr, "couldn't open %s file [%s]: %d, %s\n", desc, filename, errno, strerror(errno)); + return NULL; + } + struct stat stat_buf; + if (fstat (fileno(fp), &stat_buf) < 0) { + fprintf (stderr, "couldn't stat %s file [%s]: %d, %s\n", desc, filename, errno, strerror(errno)); + fclose (fp); + return NULL; + } + off_t n = stat_buf.st_size; + if (max_size > 0 && n > max_size) { + fprintf (stderr, "%s file [%s] is larger than %lld bytes\n", desc, filename, (long long)max_size); + fclose (fp); + return NULL; + } + char *buf; + if ((buf = (char *) malloc ((size_t)n+1)) == NULL) { + fprintf (stderr, "error allocating %lld bytes for read of %s file [%s]\n", (long long)n, desc, filename); + fclose (fp); + return NULL; + } + if (fread (buf, 1, (size_t)n, fp) < (size_t) n) { + fprintf (stderr, "error reading %s file [%s]: %d, %s\n", desc, filename, errno, strerror(errno)); + fclose (fp); + free (buf); + return NULL; + } + + fclose (fp); + buf[n] = '\0'; + if (size_ret != NULL) + *size_ret = n; + return buf; +} + +int main (int argc, char **argv) { + char *name_space = NULL; + char *name = NULL; + bool free_name = false; + char default_type[] = "char *"; + char *type = default_type; + bool validate = false; + bool convert = true; + char *include = NULL; + + int c; + while ((c=getopt_long(argc, argv, OPTIONS, options, NULL)) != EOF) { + switch (c) { + case 'i': + include = optarg; + break; + + case 'N': + name = optarg; + break; + + case 'n': + name_space = optarg; + break; + + case 't': + type = optarg; + break; + + case 'V': + validate = true; + break; + + case OPT_NO_VALIDATE: + validate = false; + break; + + case OPT_VALIDATE_ONLY: + validate = true; + convert = false; + break; + + case 'h': + usage(argv[0], 0); + + default: + usage(argv[0], 1); + } + } + + if (optind != argc - 2 && optind != argc - 1) + usage(argv[0], 1); + + char *input = argv[optind]; + char *output = NULL; + if (optind == argc -2) { + output = argv[optind+1]; + } + + char *str = read_full_file(input, 10*1024*1024, NULL, input); + + Json::Reader reader; + + Json::Value json; + if (!reader.parse(str, json)) { + fprintf(stderr, "%s: parse error: %s\n", input, reader.getFormattedErrorMessages().c_str()); + exit(1); + } + + if (validate) { + std::string error_message; + Json::SchemaValidator *validator; + + try { + validator = Json::SchemaValidator::create_meta_validator(); + } + catch (Json::SchemaValidator::Exception e) { + fprintf(stderr, "%s: can't create meta schema validator\n", argv[0]); + exit(1); + } + + if (!validator->validate(json)) { + const std::vector errors = validator->errors(); + + for (unsigned int i=0; i(end-base)); + + for (char *p = name; *p; p++) { + if ((*p >= 'A' && *p < 'Z') || (*p >= 'a' && *p < 'z') || *p == '_') { + continue; + } + else if (*p >= '0' && *p <= '9') { + if (p > name) { + continue; + } + } + *p = '_'; + } + } + else { + for (const char *p = name; *p; p++) { + if ((*p >= 'A' && *p < 'Z') || (*p >= 'a' && *p < 'z') || *p == '_') { + continue; + } + else if (*p >= '0' && *p <= '9') { + if (p > name) { + continue; + } + } + else if (p[0] == ':' && p[1] == ':') { + p += 1; + continue; + } + + fprintf(stderr, "%s: name [%s] is not a valid C identifier\n", argv[0], name); + exit(1); + } + } + + if (include) { + fprintf(fout, "#include <%s>\n\n", include); + } + + if (strcmp(type, "std::string") == 0) { + fputs("#include \n\n", fout); + } + + if (name_space) { + fprintf(fout, "namespace %s {\n\n", name_space); + } + + fprintf(fout, "const %s %s = \"\\\n", type, name); + + if (free_name) { + free(name); + name = NULL; + } + + char line[8192]; + + while (fgets(line, sizeof(line), fin)) { + if (line[strlen(line)-1] == '\n') + line[strlen(line)-1] = '\0'; + + char *p = line; + char *end = line+strlen(line); + char *q; + do { + q = p + strcspn(p, "\"\\"); + if (q < end) { + fprintf(fout, "%.*s\\%c", (int)(q-p), p, *q); + p=q+1; + } + else + fprintf(fout, "%s", p); + } while (q < end); + + fputs(" \\n\\\n", fout); + } + + fputs("\";\n", fout); + + if (name_space) { + fputs("\n}\n", fout); + } + + if (ferror(fin)) { + fprintf(stderr, "%s: read error on schema file [%s]: %s\n", argv[0], input, strerror(errno)); + fclose(fout); + unlink(output); + exit(1); + } + + fclose(fin); + + if (ferror(fout)) { + fprintf(stderr, "%s: write error on output file [%s]: %s\n", argv[0], output, strerror(errno)); + fclose(fout); + unlink(output); + exit(1); + } + + fclose(fout); + + exit(0); +} diff -r 23db8abdccda -r 09f94b1bedc3 libfdcore/cnxctx.c --- a/libfdcore/cnxctx.c Sun Jun 02 22:34:59 2019 +0800 +++ b/libfdcore/cnxctx.c Sun Jun 02 22:39:28 2019 +0800 @@ -1546,11 +1546,6 @@ tmp = gnutls_certificate_type_get_name (gnutls_certificate_type_get (session)); LOG_D("\t - Certificate Type: %s", tmp); - /* print the compression algorithm (if any) - */ - tmp = gnutls_compression_get_name (gnutls_compression_get (session)); - LOG_D("\t - Compression: %s", tmp); - /* print the name of the cipher used. * ie 3DES. */ diff -r 23db8abdccda -r 09f94b1bedc3 tests/tests.h --- a/tests/tests.h Sun Jun 02 22:34:59 2019 +0800 +++ b/tests/tests.h Sun Jun 02 22:39:28 2019 +0800 @@ -131,7 +131,9 @@ } +#ifndef GNUTLS_VERSION_210 GCRY_THREAD_OPTION_PTHREAD_IMPL; +#endif /* GNUTLS_VERSION_210 */ /* gnutls debug. */ static void fd_gnutls_debug(int level, const char * str) { @@ -213,8 +215,10 @@ parse_cmdline(argc, argv); /* Initialize gcrypt and gnutls */ +#ifndef GNUTLS_VERSION_210 (void) gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); (void) gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); +#endif /* GNUTLS_VERSION_210 */ CHECK( 0, gnutls_global_init()); /* Set gnutls debug level ? */ if (gnutls_debug) {