Skip to content
Snippets Groups Projects
Unverified Commit 3e1b9be4 authored by Kurotych Anatolii's avatar Kurotych Anatolii Committed by GitHub
Browse files

Merge pull request #11 from kelvinblockchain/feature-2043

Feature 2043
parents 7ec96997 945e0f99
No related branches found
No related tags found
No related merge requests found
...@@ -78,16 +78,13 @@ if(BUILD_KELVIN_NODE_TESTS) ...@@ -78,16 +78,13 @@ if(BUILD_KELVIN_NODE_TESTS)
add_subdirectory(test) add_subdirectory(test)
endif() endif()
set(SOURCES sources/main.c )
if(UNIX) if(UNIX)
add_definitions ("-DDAP_OS_LINUX") add_definitions ("-DDAP_OS_LINUX")
endif() endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ")
add_executable(${PROJECT_NAME} "sources/main.c" "sources/sig_unix_handler.c" ${HEADERS} ${SOURCES} ) add_executable(${PROJECT_NAME} "sources/main.c" "sources/sig_unix_handler.c")
add_executable(${PROJECT_NAME}-cli "sources/main_node_cli.c" ) add_executable(${PROJECT_NAME}-cli "sources/main_node_cli.c" "sources/main_node_cli_shell.c" "sources/main_node_cli_net.c" )
add_executable(${PROJECT_NAME}-tool "sources/main_node_tool.c" ) add_executable(${PROJECT_NAME}-tool "sources/main_node_tool.c" )
target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_core_server dap_enc_server dap_udp_server dap_session target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_core_server dap_enc_server dap_udp_server dap_session
...@@ -98,7 +95,7 @@ target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_core_server dap_en ...@@ -98,7 +95,7 @@ target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_core_server dap_en
dap_chain_net dap_chain_net_srv dap_chain_net_srv_app dap_chain_net_srv_app_db dap_chain_net dap_chain_net_srv dap_chain_net_srv_app dap_chain_net_srv_app_db
dap_chain_net_srv_datum dap_chain_net_srv_datum_pool dap_chain_net_srv_vpn dap_chain_net_srv_datum dap_chain_net_srv_datum_pool dap_chain_net_srv_vpn
dap_chain_wallet dap_chain_global_db dap_chain_mempool m pthread magic ) dap_chain_wallet dap_chain_global_db dap_chain_mempool m pthread magic )
target_link_libraries(${PROJECT_NAME}-cli m ) target_link_libraries(${PROJECT_NAME}-cli m dap_chain_net curl)
target_link_libraries(${PROJECT_NAME}-tool dap_core dap_crypto dap_core_server dap_enc_server dap_udp_server dap_session target_link_libraries(${PROJECT_NAME}-tool dap_core dap_crypto dap_core_server dap_enc_server dap_udp_server dap_session
dap_enc_server dap_stream dap_stream_ch_vpn dap_stream_ch_chain dap_stream_ch_chain_net dap_enc_server dap_stream dap_stream_ch_vpn dap_stream_ch_chain dap_stream_ch_chain_net
dap_stream_ch_chain_net_srv dap_chain dap_chain_crypto dap_client dap_stream_ch_chain_net_srv dap_chain dap_chain_crypto dap_client
...@@ -109,6 +106,7 @@ target_link_libraries(${PROJECT_NAME}-tool dap_core dap_crypto dap_core_server d ...@@ -109,6 +106,7 @@ target_link_libraries(${PROJECT_NAME}-tool dap_core dap_crypto dap_core_server d
dap_chain_wallet dap_chain_global_db dap_chain_mempool m pthread magic ) dap_chain_wallet dap_chain_global_db dap_chain_mempool m pthread magic )
target_include_directories(${PROJECT_NAME} INTERFACE .) target_include_directories(${PROJECT_NAME} INTERFACE .)
target_include_directories(${PROJECT_NAME}-cli INTERFACE .)
target_include_directories(${PROJECT_NAME}-tool INTERFACE .) target_include_directories(${PROJECT_NAME}-tool INTERFACE .)
INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../dist/ DESTINATION ${CMAKE_INSTALL_PREFIX} FILES_MATCHING PATTERN "*" PATTERN "*") INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../dist/ DESTINATION ${CMAKE_INSTALL_PREFIX} FILES_MATCHING PATTERN "*" PATTERN "*")
...@@ -117,83 +115,3 @@ INSTALL(TARGETS ${PROJECT_NAME}-cli DESTINATION ${CMAKE_INSTALL_PREFIX}/bin ) ...@@ -117,83 +115,3 @@ INSTALL(TARGETS ${PROJECT_NAME}-cli DESTINATION ${CMAKE_INSTALL_PREFIX}/bin )
INSTALL(TARGETS ${PROJECT_NAME}-tool DESTINATION ${CMAKE_INSTALL_PREFIX}/bin ) INSTALL(TARGETS ${PROJECT_NAME}-tool DESTINATION ${CMAKE_INSTALL_PREFIX}/bin )
INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/ DESTINATION ${CMAKE_INSTALL_PREFIX}/bin FILES_MATCHING PATTERN "*" PATTERN "*" PERMISSIONS OWNER_EXECUTE;OWNER_READ;OWNER_WRITE;WORLD_READ;GROUP_READ ) INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/ DESTINATION ${CMAKE_INSTALL_PREFIX}/bin FILES_MATCHING PATTERN "*" PATTERN "*" PERMISSIONS OWNER_EXECUTE;OWNER_READ;OWNER_WRITE;WORLD_READ;GROUP_READ )
INCLUDE(CPack) INCLUDE(CPack)
# Delete this later
#include_directories("${INCLUDE_DIRECTORIES} ${monero_crypto_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_core_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_core_unix_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_http_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_crypto_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_enc_server_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_http_server_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_core_server_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_server_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_client_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_stream_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_stream_ch_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_stream_ch_chain_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_stream_ch_chain_net_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_stream_ch_chain_net_srv_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_stream_ch_vpn_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_udp_server_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_session_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_chain_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_chain_block_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_chain_block_cs_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_chain_block_cs_poa_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_chain_crypto_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_chain_dag_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_chain_dag_cs_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_chain_dag_cs_hashgraph_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_chain_dag_cs_poa_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_chain_dag_cs_poh_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_chain_net_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_chain_net_srv_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_chain_net_srv_app_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_chain_net_srv_app_db_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_chain_net_srv_datum_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_chain_net_srv_datum_pool_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_chain_net_srv_vpn_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_chain_wallet_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_chain_global_db_INCLUDE_DIRS}")
#include_directories("${INCLUDE_DIRECTORIES} ${dap_chain_mempool_INCLUDE_DIRS}")
#add_definitions ("${monero_crypto_DEFINITIONS}")
#add_definitions(" ${dap_core_DEFINITIONS}")
#add_definitions(" ${dap_core_unix_DEFINITIONS}")
#add_definitions(" ${dap_http_DEFINITIONS}")
#add_definitions(" ${dap_crypto_DEFINITIONS}")
#add_definitions(" ${dap_enc_server_DEFINITIONS}")
#add_definitions(" ${dap_http_server_DEFINITIONS}")
#add_definitions(" ${dap_core_server_DEFINITIONS}")
#add_definitions(" ${dap_server_DEFINITIONS}")
#add_definitions(" ${dap_client_DEFINITIONS}")
#add_definitions(" ${dap_stream_DEFINITIONS}")
#add_definitions(" ${dap_stream_ch_DEFINITIONS}")
#add_definitions(" ${dap_stream_ch_chain_DEFINITIONS}")
#add_definitions(" ${dap_stream_ch_chain_net_DEFINITIONS}")
#add_definitions(" ${dap_stream_ch_chain_net_srv_DEFINITIONS}")
#add_definitions(" ${dap_stream_ch_vpn_DEFINITIONS}")
#add_definitions(" ${dap_udp_server_DEFINITIONS}")
#add_definitions(" ${dap_session_DEFINITIONS}")
#add_definitions(" ${dap_chain_DEFINITIONS}")
#add_definitions(" ${dap_chain_block_DEFINITIONS}")
#add_definitions(" ${dap_chain_block_cs_DEFINITIONS}")
#add_definitions(" ${dap_chain_block_cs_poa_DEFINITIONS}")
#add_definitions(" ${dap_chain_crypto_DEFINITIONS}")
#add_definitions(" ${dap_chain_dag_DEFINITIONS}")
#add_definitions(" ${dap_chain_dag_cs_DEFINITIONS}")
#add_definitions(" ${dap_chain_dag_cs_hashgraph_DEFINITIONS}")
#add_definitions(" ${dap_chain_dag_cs_poa_DEFINITIONS}")
#add_definitions(" ${dap_chain_dag_cs_poh_DEFINITIONS}")
#add_definitions(" ${dap_chain_net_DEFINITIONS}")
#add_definitions(" ${dap_chain_net_srv_DEFINITIONS}")
#add_definitions(" ${dap_chain_net_srv_app_DEFINITIONS}")
#add_definitions(" ${dap_chain_net_srv_app_db_DEFINITIONS}")
#add_definitions(" ${dap_chain_net_srv_datum_DEFINITIONS}")
#add_definitions(" ${dap_chain_net_srv_datum_pool_DEFINITIONS}")
#add_definitions(" ${dap_chain_net_srv_vpn_DEFINITIONS}")
#add_definitions(" ${dap_chain_wallet_DEFINITIONS}")
#add_definitions(" ${dap_chain_global_db_DEFINITIONS}")
#add_definitions(" ${dap_chain_mempool_DEFINITIONS}")
...@@ -61,6 +61,7 @@ ...@@ -61,6 +61,7 @@
#include "dap_chain_net_srv_vpn.h" #include "dap_chain_net_srv_vpn.h"
#include "dap_chain_global_db.h" #include "dap_chain_global_db.h"
#include "dap_chain_mempool.h" #include "dap_chain_mempool.h"
#include "dap_chain_node_cli.h"
#include "dap_stream_session.h" #include "dap_stream_session.h"
#include "dap_stream.h" #include "dap_stream.h"
...@@ -262,6 +263,11 @@ int main(int argc, const char * argv[]) ...@@ -262,6 +263,11 @@ int main(int argc, const char * argv[])
return -10; return -10;
} }
if(dap_chain_node_cli_init(g_config)) {
log_it(L_CRITICAL, "Can't init server for console");
return -11;
}
if (sig_unix_handler_init(dap_config_get_item_str_default(g_config, if (sig_unix_handler_init(dap_config_get_item_str_default(g_config,
"resources", "resources",
"pid_path", "pid_path",
......
...@@ -8,23 +8,221 @@ ...@@ -8,23 +8,221 @@
This file is part of DAP (Deus Applications Prototypes) the open source project This file is part of DAP (Deus Applications Prototypes) the open source project
DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
DAP is distributed in the hope that it will be useful, DAP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. along with any DAP based project. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
//#include "dap_client.h"
#include "dap_common.h"
#include "dap_chain_node_cli.h"
#include "main_node_cli.h"
#include "main_node_cli_net.h"
#include "main_node_cli_shell.h"
static connect_param *cparam;
/**
* split string to argc and argv
*/
static char** split_word(char *line, int *argc)
{
if(!line)
{
if(argc)
*argc = 0;
return NULL ;
}
char **argv = calloc(sizeof(char*), strlen(line));
int n = 0;
char *s, *start = line;
size_t len = strlen(line);
for(s = line; s <= line + len; s++) {
if(whitespace(*s)) {
*s = '\0';
argv[n] = start;
s++;
// miss spaces
for(; whitespace(*s); s++)
;
start = s;
n++;
}
}
// last param
if(len) {
argv[n] = start;
n++;
}
if(argc)
*argc = n;
return argv;
}
/*
* Execute a command line.
*/
int execute_line(char *line)
{
register int i;
const COMMAND *command;
char *word;
/* Isolate the command word. */
i = 0;
while(line[i] && whitespace(line[i]))
i++;
word = line + i;
/* while(line[i] && !whitespace(line[i]))
i++;
if(line[i])
line[i++] = '\0';
command = find_command(word);
if(!command)
{
fprintf(stderr, "%s: No such command\n", word);
return (-1);
}*/
/* Get argument to command, if any.
while(whitespace(line[i]))
i++;
word = line + i;*/
int argc = 0;
char **argv = split_word(word, &argc);
// Call the function
if(argc > 0) {
cmd_state cmd;
memset(&cmd, 0, sizeof(cmd_state));
cmd.cmd_name = (char *) argv[0];
cmd.cmd_param_count = argc - 1;
if(cmd.cmd_param_count > 0)
cmd.cmd_param = (char**) (argv + 1);
// Send command
int res = node_cli_post_command(cparam, &cmd);
return res;
}
fprintf(stderr, "No command\n");
return -1; //((*(command->func))(argc, (const char **) argv, NULL));
}
/**
* Clear and delete memory of structure cmd_state
*/
void free_cmd_state(cmd_state *cmd) {
if(!cmd->cmd_param)
return;
for(int i = 0; i < cmd->cmd_param_count; i++)
{
DAP_DELETE(cmd->cmd_param[i]);
}
DAP_DELETE(cmd->cmd_res);
DAP_DELETE(cmd);
}
/**
* Read and execute commands until EOF is reached. This assumes that
* the input source has already been initialized.
*/
int shell_reader_loop()
{
char *line, *s;
rl_initialize(); /* Bind our completer. */
int done = 0;
// Loop reading and executing lines until the user quits.
for(; done == 0;) {
// Read a line of input
line = rl_readline("> ");
if(!line)
break;
/* Remove leading and trailing whitespace from the line.
Then, if there is anything left, add it to the history list
and execute it. */
s = rl_stripwhite(line);
if(*s)
{
add_history(s);
execute_line(s);
}
DAP_DELETE(line);
}
exit(0);
}
int main(int argc, const char * argv[]) int main(int argc, const char * argv[])
{ {
// set_default_locale();
// command_execution_string = shell_script_filename = (char *) NULL;
// connect to node
cparam = node_cli_connect();
if(!cparam)
{
printf("Can't connected to kelvin-node\n");
exit(0);
}
/*{
printf("start node_cli_post_command()\n");
cmd_state *cmd = DAP_NEW_Z(cmd_state);
cmd->cmd_name = "cmd1";
cmd->cmd_param_count = 2;
cmd->cmd_param = DAP_NEW_Z_SIZE(char*, cmd->cmd_param_count * sizeof(char*));
cmd->cmd_param[0] = strdup("t2-t1");
cmd->cmd_param[1] = strdup("-opt");
int a = node_cli_post_command(cparam, cmd);
printf("node_cli_post_command()=%d\n", a);
free_cmd_state(cmd);
}*/
const COMMAND *command = NULL;
// in the first argument of command line look for the command
if(argc > 1)
command = find_command(argv[1]);
// command found
if(command)
{
// Call the function
//int res = ((*(command->func))(argc - 2, argv + 2));
cmd_state cmd;
memset(&cmd, 0, sizeof(cmd_state));
cmd.cmd_name = (char *) argv[1];
cmd.cmd_param_count = argc - 2;
if(cmd.cmd_param_count > 0)
cmd.cmd_param = (char**) (argv + 2);
// Send command
int res = node_cli_post_command(cparam, &cmd);
node_cli_desconnect(cparam);
return res;
}
// command not found, start interactive shell
shell_reader_loop();
node_cli_desconnect(cparam);
return 0; return 0;
} }
/*
* Authors:
* Dmitriy A. Gearasimov <kahovski@gmail.com>
* DeM Labs Inc. https://demlabs.net
* DeM Labs Open source community https://github.com/demlabsinc
* Copyright (c) 2017-2019
* All rights reserved.
This file is part of DAP (Deus Applications Prototypes) the open source project
DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DAP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with any DAP based project. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stdint.h>
// command description
typedef struct cmd_state_ {
char *cmd_name;
char **cmd_param;
int cmd_param_count;
int ret_code;
// for reply
char *cmd_res;
size_t cmd_res_len;
size_t cmd_res_cur;
} cmd_state;
/**
* Clear and delete memory of structure cmd_state
*/
void free_cmd_state(cmd_state *cmd);
/*
* Authors:
* Dmitriy A. Gearasimov <kahovski@gmail.com>
* DeM Labs Inc. https://demlabs.net
* DeM Labs Open source community https://github.com/demlabsinc
* Copyright (c) 2017-2019
* All rights reserved.
This file is part of DAP (Deus Applications Prototypes) the open source project
DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DAP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with any DAP based project. If not, see <http://www.gnu.org/licenses/>.
*/
//#include <dap_client.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <sys/socket.h>
#include "dap_common.h"
#include "dap_chain_node_cli.h" // for UNIX_SOCKET_FILE
#include "main_node_cli_net.h"
/**
* Add to one array another one
*
* memory - destination array of data
* add_mem - source array of data
* memory_len - memory array size
* add_size - add_mem array size
*/
static int add_mem_data(uint8_t **memory, size_t *memory_len, char *add_mem, size_t add_size)
{
*memory = (char*) realloc(*memory, *memory_len + add_size + 1);
//out of memory!
if(*memory == NULL) {
//printf("not enough memory (realloc returned NULL)\n");
return 0;
}
if(add_mem) {
memcpy((*memory + *memory_len), add_mem, add_size);
// increase the received bytes number
*memory_len += add_size;
// zero out the last byte
*(*memory + *memory_len) = 0;
}
return add_size;
}
//callback functions to receive header
static size_t WriteHttpMemoryHeadCallback(void *contents, size_t size, size_t nmemb, cmd_state *cmd)
{
if(!cmd)
return 0;
//printf("[header] %s len=%d\n", contents, size * nmemb);
const char *head_str = "Content-Length:";
int len_str = strlen(head_str);
if(!strncasecmp(contents, head_str, len_str)) {
cmd->cmd_res_len = atoi((contents + len_str));
cmd->cmd_res_cur = 0;
cmd->cmd_res = DAP_NEW_Z_SIZE(char, cmd->cmd_res_len);
}
return size * nmemb;
}
// callback function to receive data
static size_t WriteHttpMemoryCallback(void *contents, size_t size, size_t nmemb, cmd_state *cmd)
{
//printf("[data] %s len=%d\n", contents, size * nmemb);
if(!cmd)
return 0;
// add received data to body
memcpy(cmd->cmd_res + cmd->cmd_res_cur, contents, size * nmemb);
cmd->cmd_res_cur += size * nmemb;
return size * nmemb;
}
/**
* Connect to node unix socket server
*
* return struct connect_param if connect established, else NULL
*/
connect_param* node_cli_connect(void)
{
curl_global_init(CURL_GLOBAL_DEFAULT);
connect_param *param = DAP_NEW_Z(connect_param);
CURL *curl_handle = curl_easy_init();
int ret = curl_easy_setopt(curl_handle, CURLOPT_UNIX_SOCKET_PATH, UNIX_SOCKET_FILE); // unix socket mode
curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, 60L); // complete within 60 seconds
ret = curl_easy_setopt(curl_handle, CURLOPT_CONNECT_ONLY, 1L); // connection only
ret = curl_easy_setopt(curl_handle, CURLOPT_URL, "http:/localhost/connect");
// execute request
ret = curl_easy_perform(curl_handle);
if(!ret)
{
param->curl = curl_handle;
curl_easy_setopt(curl_handle, CURLOPT_CONNECT_ONLY, 0L); // disable mode - connection only
}
else
{
curl_easy_cleanup(curl_handle);
DAP_DELETE(param);
param = NULL;
}
return param;
}
/**
* Send request to kelvin-node
*
* return 0 if OK, else error code
*/
int node_cli_post_command(connect_param *conn, cmd_state *cmd)
{
if(!conn || !conn->curl || !cmd || !cmd->cmd_name)
{
assert(0);
return -1;
}
CURLcode ret;
CURL *curl = conn->curl;
ret = curl_easy_setopt(curl, CURLOPT_HEADER, 0L); // don't get header in the body
//ret = curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "gzip, deflate"); // allow receive of compressed data
//callback functions to receive data
ret = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteHttpMemoryCallback); // callback for the data read
//callback functions to receive header
ret = curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, WriteHttpMemoryHeadCallback); // callback for the header read
// passing a parameter to the callback function
ret = curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void * )cmd);
ret = curl_easy_setopt(curl, CURLOPT_HEADERDATA, (void * )cmd);
ret = curl_easy_setopt(curl, CURLOPT_USERAGENT, "kelvin-console 1.0");
char *post_data = NULL;
ret = curl_easy_setopt(curl, CURLOPT_POST, 1); // POST request - optional if CURLOPT_POSTFIELDS will be
size_t post_data_len = 0;
add_mem_data((uint8_t**) &post_data, &post_data_len, cmd->cmd_name, strlen(cmd->cmd_name));
if(cmd->cmd_param) {
for(int i = 0; i < cmd->cmd_param_count; i++) {
if(cmd->cmd_param[i]) {
add_mem_data((uint8_t**) &post_data, &post_data_len, "\r\n", 2);
add_mem_data((uint8_t**) &post_data, &post_data_len, cmd->cmd_param[i], strlen(cmd->cmd_param[i]));
}
}
add_mem_data((uint8_t**) &post_data, &post_data_len, "\r\n\r\n", 4);
if(post_data)
ret = curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data); // data for POST request
if(post_data_len >= 0)
ret = curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long )post_data_len); // if need a lot to send: CURLOPT_POSTFIELDSIZE_LARGE
// sending request and receiving the http page (filling cmd)
//printf("cmd='%s'\n", cmd->cmd_name);
ret = curl_easy_perform(curl); // curl_easy_send
//printf("res=%s(err_code=%d) ret='%s'\n", (!ret) ? "OK" : "Err", ret, (cmd->cmd_res) ? cmd->cmd_res : "-");
if(ret != CURLE_OK)
printf("Error (err_code=%d)\n", ret);
printf("%s\n", (cmd->cmd_res) ? cmd->cmd_res : "no response");
DAP_DELETE(post_data);
return ret;
}
else
printf("%s\n", "no parameters");
return -1;
}
int node_cli_desconnect(connect_param *param)
{
if(param) {
if(param->curl)
curl_easy_cleanup(param->curl);
DAP_DELETE(param);
}
curl_global_cleanup();
}
/*
* Authors:
* Dmitriy A. Gearasimov <kahovski@gmail.com>
* DeM Labs Inc. https://demlabs.net
* DeM Labs Open source community https://github.com/demlabsinc
* Copyright (c) 2017-2019
* All rights reserved.
This file is part of DAP (Deus Applications Prototypes) the open source project
DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DAP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with any DAP based project. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <curl/curl.h>
#include "main_node_cli.h"
// connection description
typedef struct connect_param_ {
CURL *curl;
//SOCKET sock;
} connect_param;
/**
* Connect to node unix socket server
*
* return struct connect_param if connect established, else NULL
*/
connect_param* node_cli_connect(void);
/**
* Send request to kelvin-node
*
* return 0 if OK, else error code
*/
int node_cli_post_command(connect_param *conn, cmd_state *cmd);
int node_cli_desconnect(connect_param *conn);
#include <locale.h>
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ttydefaults.h>
#include <unistd.h>
#include "dap_common.h"
#include "main_node_cli.h"
#include "main_node_cli_shell.h"
//#include "posixjmp.h"
#ifndef savestring
#define savestring(x) strcpy ((char *)malloc (1 + strlen (x)), (x))
#endif
typedef void rl_voidfunc_t(void);
typedef void rl_vintfunc_t(int);
/* Current prompt. */
char *rl_prompt = (char *) NULL;
int rl_visible_prompt_length = 0;
/* Non-zero means we have been called at least once before. */
static int rl_initialized;
/* The stuff that gets printed out before the actual text of the line.
This is usually pointing to rl_prompt. */
char *rl_display_prompt = (char *) NULL;
/* Non-zero makes this the next keystroke to read. */
int rl_pending_input = 0;
/* Make this non-zero to return the current input_line. */
int rl_done;
/* Non-zero if the previous command was a kill command. */
int _rl_last_command_was_kill = 0;
/* Top level environment for readline_internal (). */
jmp_buf _rl_top_level;
/* Length of the current input line. */
int rl_end;
/* The character that can generate an EOF. Really read from
the terminal driver... just defaulted here. */
int _rl_eof_char = CTRL('D');
#define NEWLINE '\n'
/* Input error; can be returned by (*rl_getc_function) if readline is reading
a top-level command (RL_ISSTATE (RL_STATE_READCMD)). */
#define READERR (-2)
/* Possible state values for rl_readline_state */
#define RL_STATE_NONE 0x000000 /* no state; before first call */
#define RL_STATE_INITIALIZING 0x0000001 /* initializing */
#define RL_STATE_INITIALIZED 0x0000002 /* initialization done */
#define RL_STATE_READCMD 0x0000008 /* reading a command key */
#define RL_STATE_INPUTPENDING 0x0020000 /* rl_execute_next called */
#define RL_STATE_TERMPREPPED 0x0000004 /* terminal is prepped */
/* Flags word encapsulating the current readline state. */
unsigned long rl_readline_state = RL_STATE_NONE;
#define RL_SETSTATE(x) (rl_readline_state |= (x))
#define RL_UNSETSTATE(x) (rl_readline_state &= ~(x))
#define RL_ISSTATE(x) (rl_readline_state & (x))
/* The names of the streams that we do input and output to. */
FILE *rl_instream = (FILE *) NULL;
FILE *rl_outstream = (FILE *) NULL;
/**
* Read one symbol
*/
unsigned char rl_getc(FILE *stream)
{
int result;
unsigned char c;
while(1)
{
#if defined (__MINGW32__)
if (isatty (fileno (stream)))
return (_getch ()); /* "There is no error return." */
#endif
result = 0;
if(result >= 0)
result = read(fileno(stream), &c, sizeof(unsigned char));
if(result == sizeof(unsigned char))
return (c);
/* If zero characters are returned, then the file that we are
reading from is empty! Return EOF in that case. */
if(result == 0)
return (EOF);
}
}
/**
* Set up the prompt and expand it. Called from readline()
*/
int rl_set_prompt(const char *prompt)
{
free(rl_prompt);
rl_prompt = prompt ? savestring(prompt) : (char *) NULL;
rl_display_prompt = rl_prompt ? rl_prompt : "";
fprintf(stdout, prompt);
fflush(stdout);
//rl_visible_prompt_length = rl_expand_prompt (rl_prompt);
return 0;
}
/**
* Read a line of input. Prompt with PROMPT. An empty PROMPT means none.
* A return value of NULL means that EOF was encountered.
*/
char *rl_readline(const char *prompt)
{
int value_size = 3, value_len = 0;
char *value = DAP_NEW_Z_SIZE(char, value_size + 1);
// Set up the prompt
rl_set_prompt(prompt);
// Read a line of input from the global rl_instream, doing output on the global rl_outstream.
while(1)
{
unsigned char c = rl_getc(rl_instream);
if(c == EOF || c == NEWLINE)
break;
value[value_len] = c;
value_len++;
if(value_len == value_size) {
value_size += 32;
value = realloc(value, value_size + 1);
}
}
return (value);
}
static char* _rl_get_locale_var(const char *v)
{
char *lspec;
lspec = getenv("LC_ALL");
if(lspec == 0 || *lspec == 0)
lspec = getenv(v);
if(lspec == 0 || *lspec == 0)
lspec = getenv("LANG");
return lspec;
}
/*
* Query the right environment variables and call setlocale() to initialize
* the C library locale settings.
*/
static char* _rl_init_locale(void)
{
char *ret, *lspec;
/* Set the LC_CTYPE locale category from environment variables. */
lspec = _rl_get_locale_var("LC_CTYPE");
/* Since _rl_get_locale_var queries the right environment variables,
we query the current locale settings with setlocale(), and, if
that doesn't return anything, we set lspec to the empty string to
force the subsequent call to setlocale() to define the `native'
environment. */
if(lspec == 0 || *lspec == 0)
lspec = setlocale(LC_CTYPE, (char *) NULL);
if(lspec == 0)
lspec = "";
ret = setlocale(LC_CTYPE, lspec); /* ok, since it does not change locale */
//_rl_utf8locale = (ret && *ret) ? utf8locale (ret) : 0;
return ret;
}
/*
* Initialize readline (and terminal if not already).
*/
int rl_initialize(void)
{
/* If we have never been called before, initialize the
terminal and data structures. */
if(rl_initialized == 0)
{
RL_SETSTATE(RL_STATE_INITIALIZING);
rl_instream = (FILE *) stdin;
rl_outstream = (FILE *) stdout;
RL_UNSETSTATE(RL_STATE_INITIALIZING);
rl_initialized++;
RL_SETSTATE(RL_STATE_INITIALIZED);
}
else
(void) _rl_init_locale(); /* check current locale */
RL_SETSTATE(RL_STATE_INITIALIZING);
rl_instream = (FILE *) stdin;
rl_outstream = (FILE *) stdout;
RL_UNSETSTATE(RL_STATE_INITIALIZING);
}
int parse_shell_options(char **argv, int arg_start, int arg_end)
{
int arg_index;
int arg_character, on_or_off, next_arg, i;
char *o_option, *arg_string;
arg_index = arg_start;
while(arg_index != arg_end && (arg_string = argv[arg_index]) &&
(*arg_string == '-' || *arg_string == '+'))
{
/* There are flag arguments, so parse them. */
next_arg = arg_index + 1;
/* A single `-' signals the end of options. From the 4.3 BSD sh.
An option `--' means the same thing; this is the standard
getopt(3) meaning. */
if(arg_string[0] == '-' &&
(arg_string[1] == '\0' ||
(arg_string[1] == '-' && arg_string[2] == '\0')))
return (next_arg);
i = 1;
on_or_off = arg_string[0];
while(arg_character = arg_string[i++])
{
switch (arg_character)
{
case 'c':
//want_pending_command = 1;
break;
case 'l':
//make_login_shell = 1;
break;
case 's':
//read_from_stdin = 1;
break;
case 'o':
o_option = argv[next_arg];
if(o_option == 0)
{
//list_minus_o_opts(-1, (on_or_off == '-') ? 0 : 1);
break;
}
//if(set_minus_o_option(on_or_off, o_option) != EXECUTION_SUCCESS)
// exit(EX_BADUSAGE);
next_arg++;
break;
case 'O':
/* Since some of these can be overridden by the normal
interactive/non-interactive shell initialization or
initializing posix mode, we save the options and process
them after initialization. */
o_option = argv[next_arg];
if(o_option == 0)
{
//shopt_listopt(o_option, (on_or_off == '-') ? 0 : 1);
break;
}
//add_shopt_to_alist(o_option, on_or_off);
next_arg++;
break;
case 'D':
//dump_translatable_strings = 1;
break;
default:
break;
// if(change_flag(arg_character, on_or_off) == FLAG_ERROR)
// {
// report_error(_("%c%c: invalid option"), on_or_off, arg_character);
// show_shell_usage(stderr, 0);
// exit(EX_BADUSAGE);
// }
}
}
/* Can't do just a simple increment anymore -- what about
"bash -abouo emacs ignoreeof -hP"? */
arg_index = next_arg;
}
return (arg_index);
}
/**
* Strip whitespace from the start and end of STRING. Return a pointer into STRING.
*/
char * rl_stripwhite(char *string)
{
register char *s, *t;
for(s = string; whitespace(*s); s++)
;
if(*s == 0)
return (s);
t = s + strlen(s) - 1;
while(t > s && whitespace(*t))
t--;
*++t = '\0';
return s;
}
/* The structure used to store a history entry. */
typedef struct _hist_entry {
char *line;
char *timestamp; /* char * rather than time_t for read/write */
char *data;
} HIST_ENTRY;
/**
* Place STRING at the end of the history list.
*/
void add_history(const char *string)
{
HIST_ENTRY *temp;
// The data field is set to NULL
// TODO
}
/*
* Authors:
* Dmitriy A. Gearasimov <kahovski@gmail.com>
* DeM Labs Inc. https://demlabs.net
* DeM Labs Open source community https://github.com/demlabsinc
* Copyright (c) 2017-2019
* All rights reserved.
This file is part of DAP (Deus Applications Prototypes) the open source project
DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DAP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with any DAP based project. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef whitespace
#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
#endif
/*
* Initialize readline (and terminal if not already).
*/
int rl_initialize(void);
/**
* Strip whitespace from the start and end of STRING. Return a pointer into STRING.
*/
char * rl_stripwhite(char *string);
/**
* Read a line of input. Prompt with PROMPT. An empty PROMPT means none.
* A return value of NULL means that EOF was encountered.
*/
char *rl_readline(const char *prompt);
/**
* Place STRING at the end of the history list.
*/
void add_history(const char *string);
int parse_shell_options(char **argv, int arg_start, int arg_end);
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment