void lgtd_libevent_log(int severity, const char *msg) { switch (severity) { case EVENT_LOG_DEBUG: lgtd_debug("%s", msg); break; case EVENT_LOG_MSG: lgtd_info("%s", msg); break; case EVENT_LOG_WARN: lgtd_warnx("%s", msg) break; case EVENT_LOG_ERR: lgtd_warnx("%s", msg); break; default: break; } }
static bool lgtd_jsonrpc_extract_values_from_schema_and_array(void *output, const struct lgtd_jsonrpc_node *schema, int schema_size, const jsmntok_t *tokens, int ntokens, const char *json) { if (!ntokens || tokens[0].type != JSMN_ARRAY) { return false; } int si, ti, objsize = tokens[0].size; for (si = 0, ti = 1; si < schema_size && ti < ntokens && objsize--; si++) { if (!schema[si].type_cmp(&tokens[ti], json)) { lgtd_debug( "jsonrpc client sent an invalid value for %s", schema[si].key ); return false; } if (schema[si].value_offset != -1) { LGTD_JSONRPC_SET_JSMNTOK( output, schema[si].value_offset, &tokens[ti] ); } // skip the value, if it's an object or an array we need to // skip everything in it: int value_ntokens = ti; if (tokens[ti].type == JSMN_OBJECT || tokens[ti].type == JSMN_ARRAY) { ti = lgtd_jsonrpc_consume_object_or_array( tokens, ti, ntokens, json ); } else { ti++; } value_ntokens = ti - value_ntokens; if (schema[si].ntokens_offset != -1) { LGTD_JSONRPC_SET_NTOKENS( output, schema[si].ntokens_offset, value_ntokens ); } } return si == schema_size; }
static bool lgtd_jsonrpc_extract_values_from_schema_and_dict(void *output, const struct lgtd_jsonrpc_node *schema, int schema_size, const jsmntok_t *tokens, int ntokens, const char *json) { if (!ntokens || tokens[0].type != JSMN_OBJECT) { return false; } for (int ti = 1; ti < ntokens;) { // make sure it's a key, otherwise we reached the end of the object: if (tokens[ti].type != JSMN_STRING) { break; } int si = 0; for (;; si++) { if (si == schema_size) { ti++; // nothing matched, skip the key break; } int tokenlen = LGTD_JSONRPC_TOKEN_LEN(&tokens[ti]); if (schema[si].keylen != tokenlen) { continue; } int diff = memcmp( schema[si].key, &json[tokens[ti].start], tokenlen ); if (!diff) { ti++; // keys looks good, move to the value if (!schema[si].type_cmp(&tokens[ti], json)) { lgtd_debug( "jsonrpc client sent an invalid value for %s", schema[si].key ); return false; } if (schema[si].value_offset != -1) { const jsmntok_t *seen = LGTD_JSONRPC_GET_JSMNTOK( output, schema[si].value_offset ); if (seen) { // duplicate key lgtd_debug( "jsonrpc client sent duplicate parameter %s", schema[si].key ); return false; } LGTD_JSONRPC_SET_JSMNTOK( output, schema[si].value_offset, &tokens[ti] ); } break; } } // skip the value, if it's an object or an array we need to // skip everything in it: int value_ntokens = ti; if (tokens[ti].type == JSMN_OBJECT || tokens[ti].type == JSMN_ARRAY) { ti = lgtd_jsonrpc_consume_object_or_array( tokens, ti, ntokens, json ); } else { ti++; } value_ntokens = ti - value_ntokens; if (si < schema_size && schema[si].ntokens_offset != -1) { LGTD_JSONRPC_SET_NTOKENS( output, schema[si].ntokens_offset, value_ntokens ); } } for (int si = 0; si != schema_size; si++) { if (!schema[si].optional) { const jsmntok_t *seen = LGTD_JSONRPC_GET_JSMNTOK( output, schema[si].value_offset ); if (!seen) { lgtd_debug("missing jsonrpc parameter %s", schema[si].key); return false; } lgtd_debug("got jsonrpc parameter %s", schema[si].key); } } return true; }