Skip to content
Snippets Groups Projects
Commit c30ec25e authored by dmitriy.gerasimov's avatar dmitriy.gerasimov
Browse files

Merge branch 'support-3319' into 'master'

support-3319

See merge request !85
parents 48a8db6e b1fa42f8
No related branches found
No related tags found
1 merge request!85support-3319
......@@ -52,7 +52,7 @@ SET( CPACK_GENERATOR "DEB")
SET( CPACK_PACKAGE_NAME "${PROJECT_NAME}")
SET( CPACK_PACKAGE_VERSION_MAJOR 2)
SET( CPACK_PACKAGE_VERSION_MINOR 11)
SET( CPACK_PACKAGE_VERSION_PATCH 6)
SET( CPACK_PACKAGE_VERSION_PATCH 7)
SET( CPACK_SYSTEM_TYPE "debian")
SET( CPACK_SYSTEM_VERSION "10.0")
......@@ -150,6 +150,7 @@ add_subdirectory(libdap-server)
add_subdirectory(libdap-chain-crypto)
add_subdirectory(libdap-chain-common)
add_subdirectory(libdap-chain)
add_subdirectory(libdap-chain-cli)
add_subdirectory(libdap-chain-wallet)
add_subdirectory(libdap-chain-cs-dag)
add_subdirectory(libdap-chain-cs-dag-poa)
......@@ -193,8 +194,6 @@ set( NODE_SOURCES
)
set( NODE_CLI_SOURCES
sources/main_node_cli.c
sources/main_node_cli_shell.c
sources/main_node_cli_net.c
)
set( NODE_TOOL_SOURCES
sources/main_node_tool.c
......@@ -217,7 +216,7 @@ endif()
if(WIN32)
add_executable(${PROJECT_NAME} "sources/main.c" "sources/exh_win32.c" "sources/sig_win32_handler.c")
add_executable(${NODE_CLI_TARGET} "sources/main_node_cli.c" "sources/main_node_cli_shell.c" "sources/main_node_cli_net.c" )
add_executable(${NODE_CLI_TARGET} "sources/main_node_cli.c" )
add_executable(${NODE_TOOL_TARGET} "sources/main_node_tool.c" )
target_link_libraries(${NODE_CLI_TARGET} dap_chain_net
......@@ -349,7 +348,7 @@ if(UNIX)
dap_cuttdb)
set(NODE_CLI_LIBRARIES
m dap_chain_net curl dap_cuttdb)
m dap_chain_net curl dap_cuttdb dap_app_cli)
set(NODE_TOOL_LIBRARIES
dap_core dap_crypto dap_server_core dap_enc_server dap_udp_server dap_session
......
......@@ -32,9 +32,9 @@
#include "dap_file_utils.h"
#include "dap_strfuncs.h"
#include "dap_chain_node_cli.h"
#include "main_node_cli.h"
#include "main_node_cli_net.h"
#include "main_node_cli_shell.h"
#include "dap_app_cli.h"
#include "dap_app_cli_net.h"
#include "dap_app_cli_shell.h"
#ifdef __ANDROID__
#include "cellframe_node.h"
......@@ -46,7 +46,7 @@
#include "dap_defines.h"
static connect_param *cparam;
static dap_app_cli_connect_param_t *cparam;
/**
* split string to argc and argv
......@@ -91,7 +91,6 @@ static char** split_word(char *line, int *argc)
int execute_line(char *line)
{
register int i;
dap_chain_node_cmd_item_t *command;
char *word;
/* Isolate the command word. */
......@@ -124,14 +123,14 @@ int execute_line(char *line)
// Call the function
if(argc > 0) {
cmd_state cmd;
memset(&cmd, 0, sizeof(cmd_state));
dap_app_cli_cmd_state_t cmd;
memset(&cmd, 0, sizeof(dap_app_cli_cmd_state_t));
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);
int res = dap_app_cli_post_command(cparam, &cmd);
return res;
}
fprintf(stderr, "No command\n");
......@@ -141,7 +140,7 @@ int execute_line(char *line)
/**
* Clear and delete memory of structure cmd_state
*/
void free_cmd_state(cmd_state *cmd) {
void free_cmd_state(dap_app_cli_cmd_state_t *cmd) {
if(!cmd->cmd_param)
return;
for(int i = 0; i < cmd->cmd_param_count; i++)
......@@ -223,7 +222,14 @@ int main(int argc, const char *argv[])
}
// connect to node
cparam = node_cli_connect();
#ifndef _WIN32
const char* listen_socket = dap_config_get_item_str( g_config, "conserver", "listen_unix_socket_path"); // unix socket mode
#else
const char* listen_socket = NULL;
#endif
cparam = dap_app_cli_connect(listen_socket);
if(!cparam)
{
printf("Can't connected to %s\n",dap_get_appname());
......@@ -246,20 +252,20 @@ int main(int argc, const char *argv[])
if(argc > 1){
// Call the function
//int res = ((*(command->func))(argc - 2, argv + 2));
cmd_state cmd;
memset(&cmd, 0, sizeof(cmd_state));
dap_app_cli_cmd_state_t cmd;
memset(&cmd, 0, sizeof(dap_app_cli_cmd_state_t));
cmd.cmd_name = strdup(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_disconnect(cparam);
int res = dap_app_cli_post_command(cparam, &cmd);
dap_app_cli_disconnect(cparam);
return res;
}else{
// command not found, start interactive shell
shell_reader_loop();
node_cli_disconnect(cparam);
dap_app_cli_disconnect(cparam);
}
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>
* Alexander Lysikov <alexander.lysikov@demlabs.net>
* 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 <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <getopt.h>
#include <signal.h>
#include <string.h>
#include <assert.h>
#ifdef _WIN32
#include <winsock2.h>
#include <windows.h>
#include <mswsock.h>
#include <ws2tcpip.h>
#include <io.h>
#include <pthread.h>
#else
#include <sys/socket.h>
#endif
#include "dap_common.h"
#include "dap_strfuncs.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 = (uint8_t*) 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 + 1);
}
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();
#ifndef _WIN32
int ret = curl_easy_setopt(curl_handle, CURLOPT_UNIX_SOCKET_PATH, dap_config_get_item_str( g_config, "conserver", "listen_unix_socket_path") ); // unix socket mode
#else
int ret = curl_easy_setopt(curl_handle, CURLOPT_PORT, dap_config_get_item_uint16 ( g_config, "conserver", "listen_port_tcp")); // unix socket mode
#endif
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, "cellframe-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
if (ret != CURLE_OK) {
printf("Error (err_code=%d)\n", ret);
return -1;
}
int l_err_code = -1;
if (cmd->cmd_res) {
char **l_str = dap_strsplit(cmd->cmd_res, "\r\n", 1);
int l_cnt = dap_str_countv(l_str);
char *l_str_reply = NULL;
if (l_cnt == 2) {
l_err_code = strtol(l_str[0], NULL, 10);
l_str_reply = l_str[1];
}
printf("%s\n", (l_str_reply) ? l_str_reply : "no response");
dap_strfreev(l_str);
}
DAP_DELETE(post_data);
return l_err_code;
}
int node_cli_disconnect(connect_param *param)
{
if(param) {
if(param->curl)
curl_easy_cleanup(param->curl);
DAP_DELETE(param);
}
curl_global_cleanup();
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 <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_disconnect(connect_param *conn);
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <getopt.h>
#include <signal.h>
#include <string.h>
#include <assert.h>
#include <setjmp.h>
#include <locale.h>
#ifdef _WIN32
#include <winsock2.h>
#include <windows.h>
#include <mswsock.h>
#include <ws2tcpip.h>
#include <io.h>
#include <pthread.h>
#else
#include <sys/ttydefaults.h>
#endif
#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, "%s", 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