Skip to content

Commit

Permalink
vty_cli: add history handler
Browse files Browse the repository at this point in the history
Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
  • Loading branch information
fabbione committed Oct 28, 2010
1 parent 5fb87f7 commit dccdf70
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 16 deletions.
16 changes: 10 additions & 6 deletions vty.c
Expand Up @@ -36,6 +36,14 @@ static void sigpipe_handler(int sig)
return;
}

static void knet_vty_close(struct knet_vty *vty)
{
knet_vty_free_history(vty);
vty->active = 0;
close(vty->vty_sock);
vty_current_connections--;
}

static void *vty_accept_thread(void *arg)
{
struct knet_vty *vty = (struct knet_vty *)&knet_vtys[*(int *)arg];
Expand Down Expand Up @@ -82,9 +90,7 @@ static void *vty_accept_thread(void *arg)
addrtostr_free(src_ip);

pthread_mutex_lock(&knet_vty_mutex);
vty->active = 0;
close(vty->vty_sock);
vty_current_connections--;
knet_vty_close(vty);
pthread_mutex_unlock(&knet_vty_mutex);

return NULL;
Expand Down Expand Up @@ -159,10 +165,8 @@ int knet_vty_main_loop(const char *configfile, const char *ip_addr,
(!knet_vtys[conn_index].disable_idle)) {
knet_vtys[conn_index].idle++;
if (knet_vtys[conn_index].idle > KNET_VTY_CLI_TIMEOUT) {
close(knet_vtys[conn_index].vty_sock);
knet_vty_close(&knet_vtys[conn_index]);
pthread_cancel(knet_vtys[conn_index].vty_thread);
knet_vtys[conn_index].active=0;
vty_current_connections--;
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions vty.h
Expand Up @@ -13,12 +13,17 @@

#define KNET_VTY_MAX_LINE 512

#define KNET_VTY_MAX_HIST 50

struct knet_vty {
pthread_t vty_thread; /* thread struct for this vty */
struct sockaddr_storage src_sa; /* source IP */
socklen_t src_sa_len; /* sa len */
char username[64]; /* username */
char line[KNET_VTY_MAX_LINE]; /* input line */
char *history[KNET_VTY_MAX_HIST]; /* history */
int history_idx; /* index to history */
int history_pos; /* position in the history */
int insert_mode; /* add or insert */
int line_idx; /* index on the input line */
int cursor_pos; /* position of the cursor in the line */
Expand Down
105 changes: 95 additions & 10 deletions vty_cli.c
Expand Up @@ -3,6 +3,7 @@
#include <errno.h>
#include <sys/select.h>
#include <unistd.h>
#include <stdlib.h>

#include "utils.h"
#include "vty.h"
Expand Down Expand Up @@ -53,7 +54,6 @@ static void knet_vty_add_to_buf(struct knet_vty *vty, unsigned char *buf, int po
knet_vty_write(vty, "%s", telnet_backward_char);
}

/*
static void knet_vty_rewrite_line(struct knet_vty *vty)
{
int i;
Expand All @@ -67,7 +67,6 @@ static void knet_vty_rewrite_line(struct knet_vty *vty)
knet_vty_write(vty, "%s", telnet_backward_char);

}
*/

static void knet_vty_forward_char(struct knet_vty *vty)
{
Expand Down Expand Up @@ -208,6 +207,90 @@ static void knet_vty_transpose_chars(struct knet_vty *vty)
knet_vty_add_to_buf(vty, swap, 1);
}

static void knet_vty_history_add(struct knet_vty *vty)
{
int idx;

if (vty->line_idx == 0)
return;

idx = vty->history_idx % KNET_VTY_MAX_HIST;

if (vty->history[idx]) {
free(vty->history[idx]);
vty->history[idx] = NULL;
}

vty->history[idx] = strdup(vty->line);
if (vty->history[idx] == NULL) {
log_error("Not enough memory to add history lines!");
knet_vty_write(vty, "Not enough memory to add history lines!");
}

vty->history_idx++;

if (vty->history_idx == KNET_VTY_MAX_HIST)
vty->history_idx = 0;

vty->history_pos = vty->history_idx;
}

static void knet_vty_history_print(struct knet_vty *vty)
{
int len;

knet_vty_kill_line_from_beginning(vty);

len = strlen(vty->history[vty->history_pos]);
memcpy(vty->line, vty->history[vty->history_pos], len);
vty->cursor_pos = vty->line_idx = len;

knet_vty_rewrite_line(vty);
}

static void knet_vty_history_prev(struct knet_vty *vty)
{
int idx;

idx = vty->history_pos;

if (idx == 0) {
idx = KNET_VTY_MAX_HIST - 1;
} else {
idx--;
}

if (vty->history[idx] == NULL)
return;

vty->history_pos = idx;

knet_vty_history_print(vty);
}

static void knet_vty_history_next(struct knet_vty *vty)
{
int idx;

if (vty->history_pos == vty->history_idx)
return;

idx = vty->history_pos;

if (idx == (KNET_VTY_MAX_HIST - 1)) {
idx = 0;
} else {
idx++;
}

if (vty->history[idx] == NULL)
return;

vty->history_pos = idx;

knet_vty_history_print(vty);
}

static int knet_vty_process_buf(struct knet_vty *vty, unsigned char *buf, int buflen)
{
int i;
Expand Down Expand Up @@ -238,25 +321,25 @@ static int knet_vty_process_buf(struct knet_vty *vty, unsigned char *buf, int bu
knet_vty_end_of_line(vty);
break;
case ('5'):
log_info("pg-up key");
knet_vty_history_prev(vty);
break;
case ('6'):
log_info("pg-down key");
knet_vty_history_next(vty);
break;
}

vty_ext_escape_out:
vty_ext_escape_out:
vty->escape = VTY_NORMAL;
continue;
}

if (vty->escape == VTY_ESCAPE) {
switch (buf[i]) {
case ('A'):
log_info("previous line");
knet_vty_history_prev(vty);
break;
case ('B'):
log_info("next line");
knet_vty_history_next(vty);
break;
case ('C'):
knet_vty_forward_char(vty);
Expand Down Expand Up @@ -345,10 +428,10 @@ static int knet_vty_process_buf(struct knet_vty *vty, unsigned char *buf, int bu
knet_vty_kill_line(vty);
break;
case CONTROL('N'):
log_info("next line");
knet_vty_history_next(vty);
break;
case CONTROL('P'):
log_info("previous line");
knet_vty_history_prev(vty);
break;
case CONTROL('T'):
knet_vty_transpose_chars(vty);
Expand All @@ -365,9 +448,11 @@ static int knet_vty_process_buf(struct knet_vty *vty, unsigned char *buf, int bu
case '\n':
case '\r':
knet_vty_write(vty, "%s", telnet_newline);
if (strlen(vty->line))
if (strlen(vty->line)) {
knet_vty_write(vty, "Processing: %s%s",
vty->line, telnet_newline);
knet_vty_history_add(vty);
}
knet_vty_reset_buf(vty);
break;
case '\t':
Expand Down
16 changes: 16 additions & 0 deletions vty_utils.c
Expand Up @@ -6,6 +6,7 @@
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>

Expand Down Expand Up @@ -185,3 +186,18 @@ int knet_vty_set_iacs(struct knet_vty *vty)

return 0;
}

void knet_vty_free_history(struct knet_vty *vty)
{
int i;

if (check_vty(vty))
return;

for (i = 0; i <= KNET_VTY_MAX_HIST; i++) {
if (vty->history[i]) {
free(vty->history[i]);
vty->history[i] = NULL;
}
}
}
2 changes: 2 additions & 0 deletions vty_utils.h
Expand Up @@ -16,4 +16,6 @@ void knet_vty_print_banner(struct knet_vty *vty);

int knet_vty_set_iacs(struct knet_vty *vty);

void knet_vty_free_history(struct knet_vty *vty);

#endif

0 comments on commit dccdf70

Please sign in to comment.