Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F4511799
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/vty_cli.c b/vty_cli.c
index 8ece3998..367090c4 100644
--- a/vty_cli.c
+++ b/vty_cli.c
@@ -1,243 +1,247 @@
#include "config.h"
#include <errno.h>
#include <sys/select.h>
#include <unistd.h>
#include "utils.h"
#include "vty.h"
#include "vty_cli.h"
#include "vty_utils.h"
/* if this code looks like quagga lib/vty.c it is because we stole it in good part */
#define CONTROL(X) ((X) - '@')
#define VTY_NORMAL 0
#define VTY_PRE_ESCAPE 1
#define VTY_ESCAPE 2
static const char telnet_backward_char[] = { 0x08 };
static const char telnet_space_char[] = { ' ' };
static const char telnet_newline[] = { '\n', '\r', 0x0 };
static void knet_vty_reset_buf(struct knet_vty *vty)
{
memset(vty->line, 0, sizeof(vty->line));
vty->line_idx = 0;
vty->cursor_pos = 0;
}
static void knet_vty_add_to_buf(struct knet_vty *vty, unsigned char *buf, int pos)
{
if (vty->cursor_pos == vty->line_idx) {
vty->line[vty->line_idx] = buf[pos];
} else {
memmove(&vty->line[vty->cursor_pos+1], &vty->line[vty->cursor_pos],
vty->line_idx - vty->cursor_pos);
vty->line[vty->cursor_pos] = buf[pos];
}
vty->line_idx++;
vty->cursor_pos++;
}
static void knet_vty_rewrite_line(struct knet_vty *vty)
{
int i;
for (i = 0; i <= vty->cursor_pos; i++)
knet_vty_write(vty, "%s", telnet_backward_char);
knet_vty_write(vty, "%s", vty->line);
for (i = 0; i < (vty->line_idx - vty->cursor_pos); i++)
knet_vty_write(vty, "%s", telnet_backward_char);
}
static void knet_vty_forward_char(struct knet_vty *vty)
{
char buf[2];
if (vty->cursor_pos < vty->line_idx) {
buf[1] = vty->line[vty->cursor_pos];
buf[2] = 0;
knet_vty_write(vty, "%s", buf);
vty->cursor_pos++;
}
}
static void knet_vty_backward_char(struct knet_vty *vty)
{
if (vty->cursor_pos > 0) {
knet_vty_write(vty, "%s", telnet_backward_char);
vty->cursor_pos--;
}
}
static int knet_vty_process_buf(struct knet_vty *vty, unsigned char *buf, int buflen)
{
int i;
if (vty->line_idx >= KNET_VTY_MAX_LINE)
return -1;
for (i = 0; i < buflen; i++) {
if (vty->escape == VTY_ESCAPE) {
switch (buf[i]) {
case ('A'):
log_info("previous line");
break;
case ('B'):
log_info("next line");
break;
case ('C'):
knet_vty_forward_char(vty);
break;
case ('D'):
knet_vty_backward_char(vty);
break;
default:
break;
}
vty->escape = VTY_NORMAL;
continue;
}
if (vty->escape == VTY_PRE_ESCAPE) {
switch (buf[i]) {
case '[':
vty->escape = VTY_ESCAPE;
break;
case 'b':
vty->escape = VTY_NORMAL;
log_info("backword word");
break;
case 'f':
vty->escape = VTY_NORMAL;
log_info("forward word");
break;
case 'd':
vty->escape = VTY_NORMAL;
log_info("forward kill word");
break;
case CONTROL('H'):
case 0x7f:
vty->escape = VTY_NORMAL;
log_info("backward kill word");
break;
default:
break;
}
continue;
}
switch (buf[i]) {
case CONTROL('A'):
while (vty->cursor_pos != 0)
knet_vty_backward_char(vty);
break;
case CONTROL('B'):
knet_vty_backward_char(vty);
break;
case CONTROL('C'):
- log_info("stop input");
+ knet_vty_write(vty, "%s", telnet_newline);
+ knet_vty_reset_buf(vty);
break;
case CONTROL('D'):
log_info("delete char / go one level down");
break;
case CONTROL('E'):
log_info("end of line");
break;
case CONTROL('F'):
knet_vty_forward_char(vty);
break;
case CONTROL('H'):
case 0x7f:
log_info("delete backward char");
break;
case CONTROL('K'):
log_info("kill line");
break;
case CONTROL('N'):
log_info("next line");
break;
case CONTROL('P'):
log_info("previous line");
break;
case CONTROL('T'):
log_info("transport chars");
break;
case CONTROL('U'):
log_info("kill line from beginning");
break;
case CONTROL('W'):
log_info("kill backward word");
break;
case CONTROL('Z'):
log_info("end config");
break;
case '\n':
case '\r':
knet_vty_write(vty, "%s", telnet_newline);
+ if (strlen(vty->line))
+ knet_vty_write(vty, "Processing: %s%s",
+ vty->line, telnet_newline);
knet_vty_reset_buf(vty);
break;
case '\t':
log_info("command completion");
break;
case '?':
log_info("help");
break;
case '\033':
vty->escape = VTY_PRE_ESCAPE;
break;
default:
if (buf[i] > 31 && buf[i] < 127)
knet_vty_add_to_buf(vty, buf, i);
break;
}
}
return 0;
}
void knet_vty_cli_bind(struct knet_vty *vty)
{
int se_result = 0;
fd_set rfds;
struct timeval tv;
unsigned char buf[VTY_MAX_BUFFER_SIZE];
int readlen;
while (se_result >= 0 && !vty->got_epipe) {
FD_ZERO (&rfds);
FD_SET (vty->vty_sock, &rfds);
tv.tv_sec = 1;
tv.tv_usec = 0;
se_result = select((vty->vty_sock + 1), &rfds, 0, 0, &tv);
if ((se_result == -1) || (vty->got_epipe))
goto out_clean;
if ((se_result == 0) || (!FD_ISSET(vty->vty_sock, &rfds)))
continue;
memset(buf, 0 , sizeof(buf));
readlen = knet_vty_read(vty, buf, sizeof(buf));
if (readlen <= 0)
goto out_clean;
if (knet_vty_process_buf(vty, buf, readlen) < 0) {
knet_vty_write(vty, "\nError processing command: command too long\n");
knet_vty_reset_buf(vty);
}
if (vty->escape == VTY_NORMAL)
knet_vty_rewrite_line(vty);
}
out_clean:
return;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Wed, Jun 25, 2:36 AM (20 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1951890
Default Alt Text
(5 KB)
Attached To
Mode
rK kronosnet
Attached
Detach File
Event Timeline
Log In to Comment