Browse Source

telnet: add telnet history support

adapted from Yoshinori Sato's patch:
2f07f4600a

Change-Id: I084b86d316b0aa6e9593f007c024961dbda805e9
Signed-off-by: Spencer Oliver <spen@spen-soft.co.uk>
Reviewed-on: http://openocd.zylin.com/1310
Tested-by: jenkins
Reviewed-by: Freddie Chopin <freddie.chopin@gmail.com>
tags/v0.7.0-rc1
Spencer Oliver 8 years ago
committed by Freddie Chopin
parent
commit
ff1108ad38
3 changed files with 130 additions and 0 deletions
  1. +44
    -0
      src/helper/configuration.c
  2. +1
    -0
      src/helper/configuration.h
  3. +85
    -0
      src/server/telnet_server.c

+ 44
- 0
src/helper/configuration.c View File

@@ -128,3 +128,47 @@ int parse_config_file(struct command_context *cmd_ctx)

return ERROR_OK;
}

#ifndef _WIN32
#include <pwd.h>
#endif

char *get_home_dir(const char *append_path)
{
char *home = getenv("HOME");

if (home == NULL) {

#ifdef _WIN32
home = getenv("USERPROFILE");

if (home == NULL) {

char homepath[MAX_PATH];
char *drive = getenv("HOMEDRIVE");
char *path = getenv("HOMEPATH");
if (drive && path) {
snprintf(homepath, MAX_PATH, "%s/%s", drive, path);
home = homepath;
}
}
#else
struct passwd *pwd = getpwuid(getuid());
if (pwd)
home = pwd->pw_dir;

#endif
}

if (home == NULL)
return home;

char *home_path;

if (append_path)
home_path = alloc_printf("%s/%s", home, append_path);
else
home_path = alloc_printf("%s", home);

return home_path;
}

+ 1
- 0
src/helper/configuration.h View File

@@ -40,5 +40,6 @@ int configuration_output_handler(struct command_context *cmd_ctx,
FILE *open_file_from_path(const char *file, const char *mode);

char *find_file(const char *name);
char *get_home_dir(const char *append_path);

#endif /* CONFIGURATION_H */

+ 85
- 0
src/server/telnet_server.c View File

@@ -30,6 +30,7 @@

#include "telnet_server.h"
#include <target/target_request.h>
#include <helper/configuration.h>

static const char *telnet_port;

@@ -40,6 +41,7 @@ static char *negotiate =
"\xFF\xFE\x01"; /* IAC DON'T Echo */

#define CTRL(c) (c - '@')
#define TELNET_HISTORY ".openocd_history"

/* The only way we can detect that the socket is closed is the first time
* we write to it, we will fail. Subsequent write operations will
@@ -127,6 +129,82 @@ static void telnet_log_callback(void *priv, const char *file, unsigned line,
telnet_write(connection, "\b", 1);
}

static void telnet_load_history(struct telnet_connection *t_con)
{
FILE *histfp;
char buffer[TELNET_BUFFER_SIZE];
int i = 0;

char *history = get_home_dir(TELNET_HISTORY);

if (history == NULL) {
LOG_INFO("unable to get user home directory, telnet history will be disabled");
return;
}

histfp = fopen(history, "rb");

if (histfp) {

while (fgets(buffer, sizeof(buffer), histfp) != NULL) {

char *p = strchr(buffer, '\n');
if (p)
*p = '\0';
if (buffer[0] && i < TELNET_LINE_HISTORY_SIZE)
t_con->history[i++] = strdup(buffer);
}

t_con->next_history = i;
t_con->next_history %= TELNET_LINE_HISTORY_SIZE;
/* try to set to last entry - 1, that way we skip over any exit/shutdown cmds */
t_con->current_history = t_con->next_history > 0 ? i - 1 : 0;
fclose(histfp);
}

free(history);
}

static void telnet_save_history(struct telnet_connection *t_con)
{
FILE *histfp;
int i;
int num;

char *history = get_home_dir(TELNET_HISTORY);

if (history == NULL) {
LOG_INFO("unable to get user home directory, telnet history will be disabled");
return;
}

histfp = fopen(history, "wb");

if (histfp) {

num = TELNET_LINE_HISTORY_SIZE;
i = t_con->current_history + 1;
i %= TELNET_LINE_HISTORY_SIZE;

while (t_con->history[i] == NULL && num > 0) {
i++;
i %= TELNET_LINE_HISTORY_SIZE;
num--;
}

if (num > 0) {
for (; num > 0; num--) {
fprintf(histfp, "%s\n", t_con->history[i]);
i++;
i %= TELNET_LINE_HISTORY_SIZE;
}
}
fclose(histfp);
}

free(history);
}

static int telnet_new_connection(struct connection *connection)
{
struct telnet_connection *telnet_connection = malloc(sizeof(struct telnet_connection));
@@ -164,6 +242,7 @@ static int telnet_new_connection(struct connection *connection)
telnet_connection->history[i] = NULL;
telnet_connection->next_history = 0;
telnet_connection->current_history = 0;
telnet_load_history(telnet_connection);

log_add_callback(telnet_log_callback, connection);

@@ -306,6 +385,9 @@ static int telnet_input(struct connection *connection)
/* to suppress prompt in log callback during command execution */
t_con->line_cursor = -1;

if (strcmp(t_con->line, "shutdown") == 0)
telnet_save_history(t_con);

retval = command_run_line(command_context, t_con->line);

t_con->line_cursor = 0;
@@ -490,6 +572,9 @@ static int telnet_connection_closed(struct connection *connection)
t_con->prompt = NULL;
}

/* save telnet history */
telnet_save_history(t_con);

for (i = 0; i < TELNET_LINE_HISTORY_SIZE; i++) {
if (t_con->history[i]) {
free(t_con->history[i]);


Loading…
Cancel
Save