From 888ca6cf83cbd682a41a3b8d3d949045cb474b6f Mon Sep 17 00:00:00 2001 From: "Constantin P." <papizh.konstantin@demlabs.net> Date: Fri, 21 Feb 2025 09:02:24 +0000 Subject: [PATCH] Develop port 02.25 --- core/include/dap_strfuncs.h | 1 + core/src/dap_file_utils.c | 4 +- core/src/dap_strfuncs.c | 10 + core/src/dap_time.c | 31 ++- io/dap_server.c | 55 +++-- io/include/dap_net.h | 2 + io/include/dap_server.h | 1 + net/server/cli_server/dap_cli_server.c | 275 ++++++++++++------------- 8 files changed, 201 insertions(+), 178 deletions(-) diff --git a/core/include/dap_strfuncs.h b/core/include/dap_strfuncs.h index b9a238400..c00e70bbd 100755 --- a/core/include/dap_strfuncs.h +++ b/core/include/dap_strfuncs.h @@ -39,6 +39,7 @@ DAP_PRINTF_ATTR(1, 2) char *dap_strdup_printf(const char *a_format, ...); char *dap_strncpy(char *a_dst, const char *a_src, size_t a_limit); char* dap_stpcpy(char *a_dest, const char *a_src); char* dap_strstr_len(const char *a_haystack, ssize_t a_haystack_len, const char *a_needle); +const char* dap_str_find(const char **a_str_array, const char *a_str); // concatenates all of str_array's strings, sliding in an optional separator, the returned string is newly allocated. char* dap_strjoinv(const char *a_separator, char **a_str_array); char *dap_strjoin(const char *a_separator, ...); diff --git a/core/src/dap_file_utils.c b/core/src/dap_file_utils.c index 19007826a..6d9084af8 100755 --- a/core/src/dap_file_utils.c +++ b/core/src/dap_file_utils.c @@ -775,12 +775,12 @@ char *dap_file_get_contents2(const char *a_filename, size_t *length) #endif return log_it(L_ERROR, "Can't open file \"%s\", error %d: %s", a_filename, l_err, dap_strerror(l_err)), NULL; } - off_t l_size = fseeko(f, 0, SEEK_END) ? ftello(f) : -1; + off_t l_size = !fseeko(f, 0, SEEK_END) ? ftello(f) : -1; char *l_buffer = NULL; if (l_size <= 0) { log_it(L_ERROR, "Can't get file %s size or file is empty", a_filename); l_err = -3; - } else if (!( l_buffer = DAP_NEW_Z_SIZE(char, l_size)) ) { + } else if (!( l_buffer = DAP_NEW_Z_SIZE(char, l_size + 1)) ) { log_it(L_CRITICAL, "%s", c_error_memory_alloc); l_err = -4; } else { diff --git a/core/src/dap_strfuncs.c b/core/src/dap_strfuncs.c index d8f1923f9..baa48d5e2 100755 --- a/core/src/dap_strfuncs.c +++ b/core/src/dap_strfuncs.c @@ -516,6 +516,16 @@ char* dap_strjoinv(const char *a_separator, char **a_str_array) return l_string; } +const char* dap_str_find(const char **a_str_array, const char *a_str) { + if (!a_str_array || !a_str) + return NULL; + for (size_t i = 0; !!a_str_array[i]; ++i) { + if ( !dap_strcmp(a_str, a_str_array[i]) ) + return (const char*)a_str_array[i]; + } + return NULL; +} + /** * dap_strjoin: * @a_separator: (allow-none): a string to insert between each of the diff --git a/core/src/dap_time.c b/core/src/dap_time.c index 51a6d4af4..eb45e4bab 100644 --- a/core/src/dap_time.c +++ b/core/src/dap_time.c @@ -83,11 +83,9 @@ dap_time_t dap_time_now(void) */ dap_nanotime_t dap_nanotime_now(void) { - dap_nanotime_t l_time_nsec; struct timespec cur_time; clock_gettime(CLOCK_REALTIME, &cur_time); - l_time_nsec = (dap_nanotime_t)cur_time.tv_sec * DAP_NSEC_PER_SEC + cur_time.tv_nsec; - return l_time_nsec; + return (dap_nanotime_t)cur_time.tv_sec * DAP_NSEC_PER_SEC + cur_time.tv_nsec; } /** @@ -180,16 +178,13 @@ int dap_time_to_str_rfc822(char *a_out, size_t a_out_size_max, dap_time_t a_time */ dap_time_t dap_time_from_str_rfc822(const char *a_time_str) { - dap_time_t l_time = 0; - if(!a_time_str) { - return l_time; - } - struct tm l_tm = {}; - strptime(a_time_str, "%d %b %Y %T %z", &l_tm); - + dap_return_val_if_fail(a_time_str, 0); + struct tm l_tm = { }; + char *ret = strptime(a_time_str, "%d %b %Y %T %z", &l_tm); + if ( !ret || *ret ) + return log_it(L_ERROR, "Invalid timestamp \"%s\", expected RFC822 string", a_time_str), 0; time_t tmp = mktime(&l_tm); - l_time = (tmp <= 0) ? 0 : tmp; - return l_time; + return tmp > 0 ? (dap_time_t)tmp : 0; } /** @@ -199,16 +194,14 @@ dap_time_t dap_time_from_str_rfc822(const char *a_time_str) */ dap_time_t dap_time_from_str_simplified(const char *a_time_str) { - dap_time_t l_time = 0; - if(!a_time_str) { - return l_time; - } + dap_return_val_if_fail(a_time_str, 0); struct tm l_tm = {}; - strptime(a_time_str, "%y%m%d", &l_tm); + char *ret = strptime(a_time_str, "%y%m%d", &l_tm); + if ( !ret || *ret ) + return log_it(L_ERROR, "Invalid timestamp \"%s\", expected simplified string \"yy\"mm\"dd", a_time_str), 0; l_tm.tm_sec++; time_t tmp = mktime(&l_tm); - l_time = (tmp <= 0) ? 0 : tmp; - return l_time; + return tmp > 0 ? (dap_time_t)tmp : 0; } /** diff --git a/io/dap_server.c b/io/dap_server.c index 0317f1541..f235d0f69 100644 --- a/io/dap_server.c +++ b/io/dap_server.c @@ -289,6 +289,14 @@ dap_server_t *dap_server_new(const char *a_cfg_section, dap_events_socket_callba if ( dap_server_listen_addr_add(l_server, l_cur_ip, l_cur_port, DESCRIPTOR_TYPE_SOCKET_LISTENING, &l_callbacks) ) log_it( L_ERROR, "Can't add address \"%s : %u\" to listen in server", l_cur_ip, l_cur_port); } + + l_server->whitelist = dap_config_get_array_str(g_config, a_cfg_section, DAP_CFG_PARAM_WHITE_LIST, NULL); + l_server->blacklist = dap_config_get_array_str(g_config, a_cfg_section, DAP_CFG_PARAM_BLACK_LIST, NULL); + + if (l_server->whitelist && l_server->blacklist) { + log_it(L_CRITICAL, "Server can't have both black- and whitelists, fix section [%s]", a_cfg_section); + l_server->whitelist = NULL; /* Blacklist will have priority */ + } } if (!l_server->es_listeners) { log_it(L_INFO, "Server with no listeners created. " @@ -329,7 +337,7 @@ static void s_es_server_accept(dap_events_socket_t *a_es_listener, SOCKET a_remo dap_server_t *l_server = a_es_listener->server; assert(l_server); - dap_events_socket_t * l_es_new = NULL; + dap_events_socket_t *l_es_new = NULL; debug_if(l_server->ext_log, L_DEBUG, "Listening socket %"DAP_FORMAT_SOCKET" uuid "DAP_FORMAT_ESOCKET_UUID" binded on %s:%u " "accepted new connection from remote %"DAP_FORMAT_SOCKET"", a_es_listener->socket, a_es_listener->uuid, @@ -342,43 +350,54 @@ static void s_es_server_accept(dap_events_socket_t *a_es_listener, SOCKET a_remo a_es_listener->socket, errno, dap_strerror(errno)); return; } - l_es_new = dap_events_socket_wrap_no_add(a_remote_socket, &l_server->client_callbacks); - l_es_new->server = l_server; - unsigned short l_family = a_remote_addr->ss_family; - l_es_new->type = DESCRIPTOR_TYPE_SOCKET_CLIENT; - l_es_new->addr_storage = *a_remote_addr; - char l_port_str[NI_MAXSERV]; + char l_remote_addr_str[INET6_ADDRSTRLEN] = "", l_port_str[NI_MAXSERV] = ""; - switch (l_family) { + dap_events_desc_type_t l_es_type = DESCRIPTOR_TYPE_SOCKET_CLIENT; + switch (a_remote_addr->ss_family) { #ifdef DAP_OS_UNIX case AF_UNIX: - l_es_new->type = DESCRIPTOR_TYPE_SOCKET_LOCAL_CLIENT; + l_es_type = DESCRIPTOR_TYPE_SOCKET_LOCAL_CLIENT; debug_if(l_server->ext_log, L_INFO, "Connection accepted at \"%s\", socket %"DAP_FORMAT_SOCKET, a_es_listener->remote_addr_str, a_remote_socket); break; #endif case AF_INET: case AF_INET6: - if (getnameinfo((struct sockaddr*)a_remote_addr, sizeof(*a_remote_addr), l_es_new->remote_addr_str, - sizeof(l_es_new->remote_addr_str), l_port_str, sizeof(l_port_str), NI_NUMERICHOST | NI_NUMERICSERV)) + if ( getnameinfo((struct sockaddr*)a_remote_addr, sizeof(*a_remote_addr), + l_remote_addr_str, sizeof(l_remote_addr_str), + l_port_str, sizeof(l_port_str), NI_NUMERICHOST | NI_NUMERICSERV) ) { #ifdef DAP_OS_WINDOWS _set_errno(WSAGetLastError()); #endif log_it(L_ERROR, "getnameinfo() error %d: %s", errno, dap_strerror(errno)); + closesocket(a_remote_socket); return; - } - l_es_new->remote_port = strtol(l_port_str, NULL, 10); - debug_if(l_server->ext_log, L_INFO, "Connection accepted from %s : %hu, socket %"DAP_FORMAT_SOCKET, - l_es_new->remote_addr_str, l_es_new->remote_port, a_remote_socket); + } + if (( l_server->whitelist + ? !dap_str_find(l_server->whitelist, l_remote_addr_str) + : !!dap_str_find(l_server->blacklist, l_remote_addr_str) )) { + closesocket(a_remote_socket); + return debug_if(l_server->ext_log, L_INFO, "Connection from %s : %s denied. Dump it", + l_remote_addr_str, l_port_str); + } + + debug_if(l_server->ext_log, L_INFO, "Connection accepted from %s : %s, socket %"DAP_FORMAT_SOCKET, + l_remote_addr_str, l_port_str, a_remote_socket); int one = 1; - if ( setsockopt(l_es_new->socket, IPPROTO_TCP, TCP_NODELAY, (const char*)&one, sizeof(one)) < 0 ) + if ( setsockopt(a_remote_socket, IPPROTO_TCP, TCP_NODELAY, (const char*)&one, sizeof(one)) < 0 ) log_it(L_WARNING, "Can't disable Nagle alg, error %d: %s", errno, dap_strerror(errno)); break; default: - log_it(L_ERROR, "Unsupported protocol family %hu from accept()", l_family); - break; + closesocket(a_remote_socket); + return log_it(L_ERROR, "Unsupported protocol family %hu from accept()", a_remote_addr->ss_family); } + l_es_new = dap_events_socket_wrap_no_add(a_remote_socket, &l_server->client_callbacks); + l_es_new->server = l_server; + l_es_new->type = l_es_type; + l_es_new->addr_storage = *a_remote_addr; + l_es_new->remote_port = strtol(l_port_str, NULL, 10); + dap_strncpy(l_es_new->remote_addr_str, l_remote_addr_str, INET6_ADDRSTRLEN); dap_worker_add_events_socket( dap_events_worker_get_auto(), l_es_new ); } diff --git a/io/include/dap_net.h b/io/include/dap_net.h index 81d337fb7..0afab9c11 100644 --- a/io/include/dap_net.h +++ b/io/include/dap_net.h @@ -47,6 +47,8 @@ #define DAP_CFG_PARAM_SOCK_PATH "listen-path" #define DAP_CFG_PARAM_SOCK_PERMISSIONS "listen-unix-socket-permissions" #define DAP_CFG_PARAM_LEGACY_PORT "listen-port-tcp" +#define DAP_CFG_PARAM_WHITE_LIST "white-list" +#define DAP_CFG_PARAM_BLACK_LIST "black-list" typedef struct dap_link_info { dap_stream_node_addr_t node_addr; diff --git a/io/include/dap_server.h b/io/include/dap_server.h index 4b83316c3..3a2855e99 100644 --- a/io/include/dap_server.h +++ b/io/include/dap_server.h @@ -53,6 +53,7 @@ typedef struct dap_server { dap_server_callback_t delete_callback; dap_cpu_stats_t cpu_stats; dap_list_t *es_listeners; + const char **whitelist, **blacklist; void *_inheritor; bool ext_log; } dap_server_t; diff --git a/net/server/cli_server/dap_cli_server.c b/net/server/cli_server/dap_cli_server.c index 33c494703..b8b1fe6d6 100644 --- a/net/server/cli_server/dap_cli_server.c +++ b/net/server/cli_server/dap_cli_server.c @@ -67,15 +67,25 @@ typedef struct cli_cmd_arg { char *buf, status; } cli_cmd_arg_t; -static bool s_cli_cmd_exec(void *a_arg); - -dap_cli_handler_cl_t *s_json_rpc_handler = NULL; +static void* s_cli_cmd_exec(void *a_arg); + +static bool s_allowed_cmd_check(char *a_buf) { + enum json_tokener_error jterr; + const char *l_method; + json_object *jobj = json_tokener_parse_verbose(a_buf, &jterr), + *jobj_method = NULL; + if ( jterr != json_tokener_success ) + return log_it(L_ERROR, "Can't parse json command, error %s", json_tokener_error_desc(jterr)), false; + if ( json_object_object_get_ex(jobj, "method", &jobj_method) ) + l_method = json_object_get_string(jobj_method); + else { + log_it(L_ERROR, "Invalid command request, dump it"); + json_object_put(jobj); + return false; + } -void dap_json_rpc_cli_handler_add(const char *a_method, handler_func_cli_t* a_fund) { - dap_cli_handler_cl_t *l_handler = DAP_NEW(dap_cli_handler_cl_t); - l_handler->func = a_fund; - l_handler->method = a_method; - HASH_ADD_STR(s_json_rpc_handler, method, l_handler); + bool l_allowed = !!dap_str_find( dap_config_get_array_str(g_config, "cli-server", "allowed_cmd", NULL), l_method ); + return debug_if(!l_allowed, L_ERROR, "Command %s is restricted", l_method), json_object_put(jobj), l_allowed; } DAP_STATIC_INLINE void s_cli_cmd_schedule(dap_events_socket_t *a_es, void *a_arg) { @@ -108,14 +118,31 @@ DAP_STATIC_INLINE void s_cli_cmd_schedule(dap_events_socket_t *a_es, void *a_arg size_t l_hdr_len = (size_t)(l_arg->buf - (char*)a_es->buf_in); if ( a_es->buf_in_size < l_arg->buf_size + l_hdr_len ) return; - l_arg->buf = DAP_DUP_SIZE(l_arg->buf, l_arg->buf_size); + + if ( ((struct sockaddr_in*)&a_es->addr_storage)->sin_addr.s_addr != htonl(INADDR_LOOPBACK) +#ifdef DAP_OS_UNIX + && a_es->addr_storage.ss_family != AF_UNIX +#endif + && !s_allowed_cmd_check(l_arg->buf) ) { + dap_events_socket_write_f_unsafe(a_es, "HTTP/1.1 403 Forbidden\r\n"); + a_es->flags |= DAP_SOCK_SIGNAL_CLOSE; + return; + } + + l_arg->buf = strndup(l_arg->buf, l_arg->buf_size); l_arg->worker = a_es->worker; l_arg->es_uid = a_es->uuid; - dap_proc_thread_callback_add_pri(NULL, s_cli_cmd_exec, l_arg, DAP_QUEUE_MSG_PRIORITY_HIGH); + + pthread_t l_tid; + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_create(&l_tid, &attr, s_cli_cmd_exec, l_arg); + + //dap_proc_thread_callback_add_pri(NULL, s_cli_cmd_exec, l_arg, DAP_QUEUE_MSG_PRIORITY_HIGH); a_es->buf_in_size = 0; a_es->callbacks.arg = NULL; - return; - } + } return; } dap_events_socket_write_f_unsafe(a_es, "HTTP/1.1 500 Internal Server Error\r\n"); @@ -198,19 +225,6 @@ static inline void s_cmd_add_ex(const char * a_name, dap_cli_server_cmd_callback log_it(L_DEBUG,"Added command %s",l_cmd_item->name); } -int is_json_clear_method(const char *a_name) { - static const char *long_method[] = { - "j_tx_create" - }; - for (size_t i = 0; i < sizeof(long_method)/sizeof(long_method[0]); i++) { - if (!strcmp(a_name, long_method[i])) { - return 1; - } - } - return 0; -} - - int json_commands(const char * a_name) { static const char* long_cmd[] = { "tx_history", @@ -230,6 +244,7 @@ int json_commands(const char * a_name) { "token", "esbocs", "global_db", + "net_srv", "net", "srv_stake", "voting", @@ -247,6 +262,7 @@ int json_commands(const char * a_name) { "stats", "stake_lock", "exec_cmd", + "print_log", "srv_xchange", "file", "policy" @@ -410,16 +426,17 @@ dap_cli_cmd_t *dap_cli_server_cmd_find_by_alias(const char *a_alias, char **a_ap return l_alias->standard_command; } -static bool s_cli_cmd_exec(void *a_arg) { +static void* s_cli_cmd_exec(void *a_arg) { cli_cmd_arg_t *l_arg = (cli_cmd_arg_t*)a_arg; char *l_ret = dap_cli_cmd_exec(l_arg->buf), *l_full_ret = dap_strdup_printf("HTTP/1.1 200 OK\r\n" "Content-Length: %zu\r\n\r\n" "%s", dap_strlen(l_ret), l_ret); + DAP_DELETE(l_ret); dap_events_socket_write(l_arg->worker, l_arg->es_uid, l_full_ret, dap_strlen(l_full_ret)); - // TODO: pagination and ouput optimizations - DAP_DEL_MULTY(l_ret, l_arg->buf, l_full_ret, l_arg); - return false; + // TODO: pagination and output optimizations + DAP_DEL_MULTY(l_arg->buf, l_full_ret, l_arg); + return NULL; } char *dap_cli_cmd_exec(char *a_req_str) { @@ -429,122 +446,102 @@ char *dap_cli_cmd_exec(char *a_req_str) { int l_verbose = 0; // command is found char *cmd_name = request->method; - if (is_json_clear_method(cmd_name)) { - json_object *l_obj_ret = json_object_new_object(); - dap_cli_handler_cl_t *l_handler = NULL; - HASH_FIND_STR(s_json_rpc_handler, cmd_name, l_handler); - if (!l_handler) { - dap_json_rpc_error_add(l_obj_ret, 1, "Can't find handler '%s' method", cmd_name); - } else { - dap_json_rpc_params_t *params = request->params; - if (params->length == 1){ - json_object *l_obj_params = dap_json_rpc_params_get(params, 0); - l_handler->func(l_obj_params, l_obj_ret); - } - } - dap_json_rpc_response_t *l_response = dap_json_rpc_response_create(l_obj_ret, - TYPE_RESPONSE_JSON, request->id); - char *response_string = dap_json_rpc_response_to_string(l_response); - json_object_put(l_obj_ret); - dap_json_rpc_response_free(l_response); - dap_json_rpc_request_free(request); - return response_string; - } else { - dap_cli_cmd_t *l_cmd = dap_cli_server_cmd_find(cmd_name); - bool l_finded_by_alias = false; - char *l_append_cmd = NULL; - char *l_ncmd = NULL; - if (!l_cmd) { - l_cmd = dap_cli_server_cmd_find_by_alias(cmd_name, &l_append_cmd, &l_ncmd); - l_finded_by_alias = true; - } - dap_json_rpc_params_t *params = request->params; - - char *str_cmd = dap_json_rpc_params_get(params, 0); - int res = -1; - char *str_reply = NULL; - json_object *l_json_arr_reply = json_object_new_array(); - if (l_cmd) { - if (l_cmd->overrides.log_cmd_call) - l_cmd->overrides.log_cmd_call(str_cmd); - else { - char *l_str_cmd = dap_strdup(str_cmd); - char *l_ptr = strstr(l_str_cmd, "-password"); - if (l_ptr) { - l_ptr += 10; - while (l_ptr[0] != '\0' && l_ptr[0] != ';') { - *l_ptr = '*'; - l_ptr += 1; - } + dap_cli_cmd_t *l_cmd = dap_cli_server_cmd_find(cmd_name); + bool l_finded_by_alias = false; + char *l_append_cmd = NULL; + char *l_ncmd = NULL; + if (!l_cmd) { + l_cmd = dap_cli_server_cmd_find_by_alias(cmd_name, &l_append_cmd, &l_ncmd); + l_finded_by_alias = true; + } + dap_json_rpc_params_t *params = request->params; + + char *str_cmd = dap_json_rpc_params_get(params, 0); + if (!str_cmd) + str_cmd = cmd_name; + int res = -1; + char *str_reply = NULL; + json_object *l_json_arr_reply = json_object_new_array(); + if (l_cmd) { + if (l_cmd->overrides.log_cmd_call) + l_cmd->overrides.log_cmd_call(str_cmd); + else { + char *l_str_cmd = dap_strdup(str_cmd); + char *l_ptr = strstr(l_str_cmd, "-password"); + if (l_ptr) { + l_ptr += 10; + while (l_ptr[0] != '\0' && l_ptr[0] != ';') { + *l_ptr = '*'; + l_ptr += 1; } - debug_if(dap_config_get_item_bool_default(g_config, "cli-server", "debug-more", false), - L_DEBUG, "execute command=%s", l_str_cmd); - DAP_DELETE(l_str_cmd); } + debug_if(dap_config_get_item_bool_default(g_config, "cli-server", "debug-more", false), + L_DEBUG, "execute command=%s", l_str_cmd); + DAP_DELETE(l_str_cmd); + } - char **l_argv = dap_strsplit(str_cmd, ";", -1); - int argc = 0; - // Count argc - while (l_argv[argc] != NULL) argc++; - // Support alias - if (l_finded_by_alias) { - int l_argc = argc + 1; - char **al_argv = DAP_NEW_Z_COUNT(char*, l_argc + 1); - al_argv[0] = l_ncmd; - al_argv[1] = l_append_cmd; - for (int i = 1; i < argc; i++) - al_argv[i + 1] = l_argv[i]; - cmd_name = l_ncmd; - DAP_FREE(l_argv[0]); - DAP_DEL_Z(l_argv); - l_argv = al_argv; - argc = l_argc; - } - // Call the command function - if (l_cmd && l_argv && l_cmd->func) { - if (json_commands(cmd_name)) { - res = l_cmd->func(argc, l_argv, (void *) &l_json_arr_reply); - } else if (l_cmd->arg_func) { - res = l_cmd->func_ex(argc, l_argv, l_cmd->arg_func, (void *) &str_reply); - } else { - res = l_cmd->func(argc, l_argv, (void *) &str_reply); - } - } else if (l_cmd) { - log_it(L_WARNING, "NULL arguments for input for command \"%s\"", str_cmd); - dap_json_rpc_error_add(l_json_arr_reply, -1, "NULL arguments for input for command \"%s\"", str_cmd); + char **l_argv = dap_strsplit(str_cmd, ";", -1); + int argc = 0; + // Count argc + while (l_argv[argc] != NULL) argc++; + // Support alias + if (l_finded_by_alias) { + int l_argc = argc + 1; + char **al_argv = DAP_NEW_Z_COUNT(char*, l_argc + 1); + al_argv[0] = l_ncmd; + al_argv[1] = l_append_cmd; + for (int i = 1; i < argc; i++) + al_argv[i + 1] = l_argv[i]; + cmd_name = l_ncmd; + DAP_FREE(l_argv[0]); + DAP_DEL_Z(l_argv); + l_argv = al_argv; + argc = l_argc; + } + // Call the command function + if (l_cmd && l_argv && l_cmd->func) { + if (json_commands(cmd_name)) { + res = l_cmd->func(argc, l_argv, (void *) &l_json_arr_reply); + } else if (l_cmd->arg_func) { + res = l_cmd->func_ex(argc, l_argv, l_cmd->arg_func, (void *) &str_reply); } else { - log_it(L_WARNING, "No function for command \"%s\" but it registred?!", str_cmd); - dap_json_rpc_error_add(l_json_arr_reply, -1, "No function for command \"%s\" but it registred?!", str_cmd); + res = l_cmd->func(argc, l_argv, (void *) &str_reply); } - // find '-verbose' command - l_verbose = dap_cli_server_cmd_find_option_val(l_argv, 1, argc, "-verbose", NULL); - dap_strfreev(l_argv); + } else if (l_cmd) { + log_it(L_WARNING, "NULL arguments for input for command \"%s\"", str_cmd); + dap_json_rpc_error_add(l_json_arr_reply, -1, "NULL arguments for input for command \"%s\"", str_cmd); } else { - dap_json_rpc_error_add(l_json_arr_reply, -1, "can't recognize command=%s", str_cmd); - log_it(L_ERROR, "Reply string: \"%s\"", str_reply); + log_it(L_WARNING, "No function for command \"%s\" but it registred?!", str_cmd); + dap_json_rpc_error_add(l_json_arr_reply, -1, "No function for command \"%s\" but it registred?!", str_cmd); } - char *reply_body = NULL; - // -verbose - if (l_verbose) { - if (str_reply) { - reply_body = dap_strdup_printf("%d\r\nret_code: %d\r\n%s\r\n", res, res, str_reply); - DAP_DELETE(str_reply); - } else { - json_object *json_res = json_object_new_object(); - json_object_object_add(json_res, "ret_code", json_object_new_int(res)); - json_object_array_add(l_json_arr_reply, json_res); - } - } else - reply_body = str_reply; - - // create response - dap_json_rpc_response_t *response = reply_body - ? dap_json_rpc_response_create(reply_body, TYPE_RESPONSE_STRING, request->id) - : dap_json_rpc_response_create(json_object_get(l_json_arr_reply), TYPE_RESPONSE_JSON, request->id); - json_object_put(l_json_arr_reply); - char *response_string = dap_json_rpc_response_to_string(response); - dap_json_rpc_response_free(response); - dap_json_rpc_request_free(request); - return response_string; + // find '-verbose' command + l_verbose = dap_cli_server_cmd_find_option_val(l_argv, 1, argc, "-verbose", NULL); + dap_strfreev(l_argv); + } else { + dap_json_rpc_error_add(l_json_arr_reply, -1, "can't recognize command=%s", str_cmd); + log_it(L_ERROR, "Reply string: \"%s\"", str_reply); } + char *reply_body = NULL; + // -verbose + if (l_verbose) { + if (str_reply) { + reply_body = dap_strdup_printf("%d\r\nret_code: %d\r\n%s\r\n", res, res, str_reply); + DAP_DELETE(str_reply); + } else { + json_object *json_res = json_object_new_object(); + json_object_object_add(json_res, "ret_code", json_object_new_int(res)); + json_object_array_add(l_json_arr_reply, json_res); + } + } else + reply_body = str_reply; + + // create response + dap_json_rpc_response_t *response = reply_body + ? dap_json_rpc_response_create(reply_body, TYPE_RESPONSE_STRING, request->id) + : dap_json_rpc_response_create(json_object_get(l_json_arr_reply), TYPE_RESPONSE_JSON, request->id); + json_object_put(l_json_arr_reply); + char *response_string = dap_json_rpc_response_to_string(response); + dap_json_rpc_response_free(response); + dap_json_rpc_request_free(request); + return response_string; } -- GitLab