31 #define CTRL(c) (c - '@')
32 #define TELNET_HISTORY ".openocd_history"
71 char *line_end = strchr(
line,
'\n');
97 const char *
function,
const char *
string)
113 for (i = 0; i < tmp; i += 16)
117 for (i = 0; i < tmp; i += 16)
120 for (i = 0; i < tmp; i += 16)
143 LOG_INFO(
"unable to get user home directory, telnet history will be disabled");
153 char *p = strchr(
buffer,
'\n');
179 LOG_INFO(
"unable to get user home directory, telnet history will be disabled");
191 while (!t_con->
history[i] && num > 0) {
198 for (; num > 0; num--) {
199 fprintf(histfp,
"%s\n", t_con->
history[i]);
218 LOG_ERROR(
"Failed to allocate telnet connection.");
311 if (*t_con->
line && (!prev_line || strcmp(t_con->
line, prev_line))) {
373 for (
size_t i = 0; i < tmp; i += 16)
379 for (
size_t i = 0; i < tmp; i += 16)
497 if (strcmp(t_con->
line,
"history") == 0) {
513 if (strcmp(t_con->
line,
"shutdown") == 0)
579 bool is_variable_auto_completion =
false;
580 bool have_spaces =
false;
583 char c = t_con->
line[seq_start];
585 if (c ==
';' || c ==
'[' || c ==
'{') {
588 }
else if (c ==
' ') {
590 }
else if (c ==
'$' && !have_spaces) {
591 is_variable_auto_completion =
true;
603 size_t usr_cmd_pos = seq_start;
604 while ((usr_cmd_pos < t_con->line_cursor) && isspace(t_con->
line[usr_cmd_pos]))
612 size_t usr_cmd_len = t_con->
line_cursor - usr_cmd_pos;
616 size_t optimized_spaces = 0;
617 char query[usr_cmd_len + 1];
618 for (
size_t i = 0; i < usr_cmd_len; i++) {
619 if ((i < usr_cmd_len - 1) && isspace(t_con->
line[usr_cmd_pos + i])
620 && isspace(t_con->
line[usr_cmd_pos + i + 1])) {
625 query[i - optimized_spaces] = t_con->
line[usr_cmd_pos + i];
628 usr_cmd_len -= optimized_spaces;
629 query[usr_cmd_len] =
'\0';
634 if (is_variable_auto_completion)
635 query_cmd =
alloc_printf(
"lsort [info vars {%s*}]", query);
637 query_cmd =
alloc_printf(
"_telnet_autocomplete_helper {%s*}", query);
646 if (retval != JIM_OK)
650 Jim_IncrRefCount(list);
653 size_t common_len = 0;
654 char *first_match =
NULL;
657 for (
int i = 0; i < len; i++) {
659 Jim_IncrRefCount(elem);
661 char *
name = (
char *)Jim_GetString(elem,
NULL);
664 bool ignore_cmd =
false;
665 if (!is_variable_auto_completion) {
674 if (
cmd && !
cmd->handler && !
cmd->jim_handler) {
686 struct cmd_match *match = calloc(1,
sizeof(
struct cmd_match));
694 common_len = strlen(
name);
697 size_t new_common_len = usr_cmd_len;
699 while (new_common_len < common_len && first_match[new_common_len] ==
name[new_common_len])
702 common_len = new_common_len;
718 else if (common_len > usr_cmd_len) {
719 int completion_size = common_len - usr_cmd_len;
728 struct cmd_match *match;
738 for (
size_t i = t_con->
line_cursor; i < t_con->line_size; i++)
743 struct cmd_match *tmp, *match;
754 unsigned char *buf_p;
761 else if (bytes_read == -1) {
762 LOG_ERROR(
"error during read: %s", strerror(errno));
768 switch (t_con->
state) {
770 if (*buf_p == 0xff) {
773 if (isprint(*buf_p)) {
776 if (*buf_p == 0x1b) {
779 }
else if ((*buf_p == 0xd) || (*buf_p == 0xa)) {
783 if ((bytes_read > 1) && ((*(buf_p + 1) == 0xa) ||
784 (*(buf_p + 1) == 0xd))) {
788 if ((bytes_read > 1) && (*(buf_p + 1) == 0)) {
797 }
else if ((*buf_p == 0x7f) || (*buf_p == 0x8)) {
799 }
else if (*buf_p == 0x15) {
801 }
else if (*buf_p ==
CTRL(
'B')) {
804 }
else if (*buf_p ==
CTRL(
'C')) {
806 }
else if (*buf_p ==
CTRL(
'F')) {
809 }
else if (*buf_p ==
CTRL(
'P')) {
811 }
else if (*buf_p ==
CTRL(
'N')) {
813 }
else if (*buf_p ==
CTRL(
'A')) {
815 }
else if (*buf_p ==
CTRL(
'E')) {
817 }
else if (*buf_p ==
CTRL(
'K')) {
819 }
else if (*buf_p ==
'\t') {
822 LOG_DEBUG(
"unhandled nonprintable: %2.2x", *buf_p);
858 }
else if (*buf_p ==
'C') {
861 }
else if (*buf_p ==
'A') {
863 }
else if (*buf_p ==
'B') {
865 }
else if (*buf_p ==
'F') {
868 }
else if (*buf_p ==
'H') {
871 }
else if (*buf_p ==
'3') {
889 LOG_ERROR(
"BUG: unexpected value in t_con->last_escape");
935 .new_connection_during_keep_alive_handler =
NULL,
939 .keep_client_alive_handler =
NULL,
953 LOG_ERROR(
"Failed to allocate telnet service.");
983 .handler = handle_telnet_port_command,
985 .help =
"Specify port on which to listen "
986 "for incoming telnet connections. "
987 "Read help on 'gdb port'.",
988 .usage =
"[port_num]",
996 .handler = handle_exit_command,
999 .help =
"exit telnet session",
1005 .help =
"telnet commands",
bool jimcmd_is_oocd_command(Jim_Cmd *cmd)
Return true if the command cmd is registered by OpenOCD.
void * jimcmd_privdata(Jim_Cmd *cmd)
Return the pointer to the command's private data specified during the registration of command cmd .
void command_set_output_handler(struct command_context *context, command_output_handler_t output_handler, void *priv)
int command_run_line(struct command_context *context, char *line)
#define CALL_COMMAND_HANDLER(name, extra ...)
Use this to macro to call a command helper (or a nested handler).
#define ERROR_COMMAND_CLOSE_CONNECTION
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
static int register_commands(struct command_context *cmd_ctx, const char *cmd_prefix, const struct command_registration *cmds)
Register one or more commands in the specified context, as children of parent (or top-level commends,...
char * get_home_dir(const char *append_path)
static struct esp_usb_jtag * priv
static int list_is_singular(const struct list_head *head)
static void list_add_tail(struct list_head *new, struct list_head *head)
static int list_empty(const struct list_head *head)
#define list_for_each_entry_safe(p, n, h, field)
#define list_for_each_entry(p, h, field)
int log_remove_callback(log_callback_fn fn, void *priv)
int log_add_callback(log_callback_fn fn, void *priv)
char * alloc_printf(const char *format,...)
#define LOG_ERROR(expr ...)
#define LOG_INFO(expr ...)
#define LOG_DEBUG(expr ...)
static uint32_t lh(unsigned int rd, unsigned int base, uint16_t offset) __attribute__((unused))
int connection_write(struct connection *connection, const void *data, int len)
int connection_read(struct connection *connection, void *data, int len)
int add_service(const struct service_driver *driver, const char *port, int max_connections, void *priv)
#define CONNECTION_LIMIT_UNLIMITED
#define ERROR_SERVER_REMOTE_CLOSED
void * output_handler_priv
struct command_context * cmd_ctx
const char * name
the name of the server
char * history[TELNET_LINE_HISTORY_SIZE]
char line[TELNET_LINE_MAX_SIZE]
int delete_debug_msg_receiver(struct command_context *cmd_ctx, struct target *target)
void telnet_service_free(void)
static int telnet_prompt(struct connection *connection)
static void telnet_cut_line_to_end(struct connection *connection)
static const struct service_driver telnet_service_driver
static void telnet_auto_complete(struct connection *connection)
static int telnet_bell(struct connection *connection)
int telnet_register_commands(struct command_context *cmd_ctx)
static void telnet_load_history(struct telnet_connection *t_con)
int telnet_init(char *banner)
static int telnet_output(struct command_context *cmd_ctx, const char *line)
static void telnet_clear_line(struct connection *connection, struct telnet_connection *t_con)
static char * telnet_port
static const struct command_registration telnet_subcommand_handlers[]
static int telnet_history_print(struct connection *connection)
COMMAND_HANDLER(handle_telnet_port_command)
static bool telnet_insert(struct connection *connection, const void *data, size_t len)
static void telnet_log_callback(void *priv, const char *file, unsigned int line, const char *function, const char *string)
static void telnet_history_up(struct connection *connection)
static int telnet_write(struct connection *connection, const void *data, int len)
static bool telnet_can_insert(struct connection *connection, size_t len)
static void telnet_history_add(struct connection *connection)
static void telnet_interrupt(struct connection *connection)
static int telnet_input(struct connection *connection)
static int telnet_exec_line(struct connection *connection)
static void telnet_move_cursor(struct connection *connection, size_t pos)
static void telnet_save_history(struct telnet_connection *t_con)
static void telnet_history_down(struct connection *connection)
static void telnet_history_go(struct connection *connection, int idx)
static const struct command_registration telnet_command_handlers[]
static void telnet_remove_character(struct connection *connection)
static int telnet_new_connection(struct connection *connection)
static int telnet_connection_closed(struct connection *connection)
static int telnet_outputline(struct connection *connection, const char *line)
static void telnet_delete_character(struct connection *connection)
#define TELNET_LINE_HISTORY_SIZE
#define TELNET_BUFFER_SIZE
#define TELNET_LINE_MAX_SIZE