diff options
Diffstat (limited to 'lib/vty.c')
| -rw-r--r-- | lib/vty.c | 125 |
1 files changed, 65 insertions, 60 deletions
@@ -73,7 +73,8 @@ enum event { #endif /* VTYSH */ }; -static void vty_event(enum event, int, struct vty *); +static void vty_event_serv(enum event event, int sock); +static void vty_event(enum event, struct vty *); /* Extern host structure from command.c */ extern struct host host; @@ -396,16 +397,6 @@ static void vty_do_window_size(struct vty *vty) vty_out(vty, "%s", cmd); } -#if 0 /* Currently not used. */ -/* Make don't use lflow vty interface. */ -static void -vty_dont_lflow_ahead (struct vty *vty) -{ - unsigned char cmd[] = { IAC, DONT, TELOPT_LFLOW, '\0' }; - vty_out (vty, "%s", cmd); -} -#endif /* 0 */ - /* Authentication of vty */ static void vty_auth(struct vty *vty, char *buf) { @@ -1090,11 +1081,6 @@ static void vty_describe_command(struct vty *vty) vector_free(varcomps); } -#if 0 - vty_out (vty, " %-*s %s\n", width - desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd, - desc->str ? desc->str : ""); -#endif /* 0 */ } if ((token = token_cr)) { @@ -1299,6 +1285,7 @@ static int vty_execute(struct vty *vty) #define VTY_NORMAL 0 #define VTY_PRE_ESCAPE 1 #define VTY_ESCAPE 2 +#define VTY_CR 3 /* Escape character command map. */ static void vty_escape_map(unsigned char c, struct vty *vty) @@ -1340,14 +1327,13 @@ static int vty_read(struct thread *thread) int nbytes; unsigned char buf[VTY_READ_BUFSIZ]; - int vty_sock = THREAD_FD(thread); struct vty *vty = THREAD_ARG(thread); /* Read raw data from socket */ if ((nbytes = read(vty->fd, buf, VTY_READ_BUFSIZ)) <= 0) { if (nbytes < 0) { if (ERRNO_IO_RETRY(errno)) { - vty_event(VTY_READ, vty_sock, vty); + vty_event(VTY_READ, vty); return 0; } vty->monitor = 0; /* disable monitoring to avoid @@ -1396,12 +1382,6 @@ static int vty_read(struct thread *thread) case 'Q': vty_buffer_reset(vty); break; -#if 0 /* More line does not work for "show ip bgp". */ - case '\n': - case '\r': - vty->status = VTY_MORELINE; - break; -#endif default: break; } @@ -1444,6 +1424,17 @@ static int vty_read(struct thread *thread) continue; } + if (vty->escape == VTY_CR) { + /* if we get CR+NL, the NL results in an extra empty + * prompt line being printed without this; just drop + * the NL if it immediately follows CR. + */ + vty->escape = VTY_NORMAL; + + if (buf[i] == '\n') + continue; + } + switch (buf[i]) { case CONTROL('A'): vty_beginning_of_line(vty); @@ -1488,9 +1479,12 @@ static int vty_read(struct thread *thread) case CONTROL('Z'): vty_end_config(vty); break; - case '\n': case '\r': + vty->escape = VTY_CR; + /* fallthru */ + case '\n': vty_out(vty, "\n"); + buffer_flush_available(vty->obuf, vty->wfd); vty_execute(vty); break; case '\t': @@ -1521,8 +1515,8 @@ static int vty_read(struct thread *thread) if (vty->status == VTY_CLOSE) vty_close(vty); else { - vty_event(VTY_WRITE, vty->wfd, vty); - vty_event(VTY_READ, vty_sock, vty); + vty_event(VTY_WRITE, vty); + vty_event(VTY_READ, vty); } return 0; } @@ -1532,7 +1526,6 @@ static int vty_flush(struct thread *thread) { int erase; buffer_status_t flushrc; - int vty_sock = THREAD_FD(thread); struct vty *vty = THREAD_ARG(thread); /* Tempolary disable read thread. */ @@ -1544,20 +1537,20 @@ static int vty_flush(struct thread *thread) /* N.B. if width is 0, that means we don't know the window size. */ if ((vty->lines == 0) || (vty->width == 0) || (vty->height == 0)) - flushrc = buffer_flush_available(vty->obuf, vty_sock); + flushrc = buffer_flush_available(vty->obuf, vty->wfd); else if (vty->status == VTY_MORELINE) - flushrc = buffer_flush_window(vty->obuf, vty_sock, vty->width, + flushrc = buffer_flush_window(vty->obuf, vty->wfd, vty->width, 1, erase, 0); else flushrc = buffer_flush_window( - vty->obuf, vty_sock, vty->width, + vty->obuf, vty->wfd, vty->width, vty->lines >= 0 ? vty->lines : vty->height, erase, 0); switch (flushrc) { case BUFFER_ERROR: vty->monitor = 0; /* disable monitoring to avoid infinite recursion */ - zlog_info("buffer_flush failed on vty client fd %d, closing", - vty->fd); + zlog_info("buffer_flush failed on vty client fd %d/%d, closing", + vty->fd, vty->wfd); buffer_reset(vty->lbuf); buffer_reset(vty->obuf); vty_close(vty); @@ -1568,14 +1561,14 @@ static int vty_flush(struct thread *thread) else { vty->status = VTY_NORMAL; if (vty->lines == 0) - vty_event(VTY_READ, vty_sock, vty); + vty_event(VTY_READ, vty); } break; case BUFFER_PENDING: /* There is more data waiting to be written. */ vty->status = VTY_MORE; if (vty->lines == 0) - vty_event(VTY_WRITE, vty_sock, vty); + vty_event(VTY_WRITE, vty); break; } @@ -1678,8 +1671,8 @@ static struct vty *vty_create(int vty_sock, union sockunion *su) vty_prompt(vty); /* Add read/write thread. */ - vty_event(VTY_WRITE, vty_sock, vty); - vty_event(VTY_READ, vty_sock, vty); + vty_event(VTY_WRITE, vty); + vty_event(VTY_READ, vty); return vty; } @@ -1735,7 +1728,6 @@ void vty_stdio_resume(void) termios = stdio_orig_termios; termios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); - termios.c_oflag &= ~OPOST; termios.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN); termios.c_cflag &= ~(CSIZE | PARENB); termios.c_cflag |= CS8; @@ -1746,8 +1738,8 @@ void vty_stdio_resume(void) vty_prompt(stdio_vty); /* Add read/write thread. */ - vty_event(VTY_WRITE, 1, stdio_vty); - vty_event(VTY_READ, 0, stdio_vty); + vty_event(VTY_WRITE, stdio_vty); + vty_event(VTY_READ, stdio_vty); } void vty_stdio_close(void) @@ -1796,7 +1788,7 @@ static int vty_accept(struct thread *thread) accept_sock = THREAD_FD(thread); /* We continue hearing vty socket. */ - vty_event(VTY_SERV, accept_sock, NULL); + vty_event_serv(VTY_SERV, accept_sock); memset(&su, 0, sizeof(union sockunion)); @@ -1826,7 +1818,7 @@ static int vty_accept(struct thread *thread) close(vty_sock); /* continue accepting connections */ - vty_event(VTY_SERV, accept_sock, NULL); + vty_event_serv(VTY_SERV, accept_sock); return 0; } @@ -1842,7 +1834,7 @@ static int vty_accept(struct thread *thread) close(vty_sock); /* continue accepting connections */ - vty_event(VTY_SERV, accept_sock, NULL); + vty_event_serv(VTY_SERV, accept_sock); return 0; } @@ -1915,7 +1907,7 @@ static void vty_serv_sock_addrinfo(const char *hostname, unsigned short port) continue; } - vty_event(VTY_SERV, sock, NULL); + vty_event_serv(VTY_SERV, sock); } while ((ainfo = ainfo->ai_next) != NULL); freeaddrinfo(ainfo_save); @@ -1993,7 +1985,7 @@ static void vty_serv_un(const char *path) } } - vty_event(VTYSH_SERV, sock, NULL); + vty_event_serv(VTYSH_SERV, sock); } /* #define VTYSH_DEBUG 1 */ @@ -2008,7 +2000,7 @@ static int vtysh_accept(struct thread *thread) accept_sock = THREAD_FD(thread); - vty_event(VTYSH_SERV, accept_sock, NULL); + vty_event_serv(VTYSH_SERV, accept_sock); memset(&client, 0, sizeof(struct sockaddr_un)); client_len = sizeof(struct sockaddr_un); @@ -2042,7 +2034,7 @@ static int vtysh_accept(struct thread *thread) vty->type = VTY_SHELL_SERV; vty->node = VIEW_NODE; - vty_event(VTYSH_READ, sock, vty); + vty_event(VTYSH_READ, vty); return 0; } @@ -2051,7 +2043,7 @@ static int vtysh_flush(struct vty *vty) { switch (buffer_flush_available(vty->obuf, vty->wfd)) { case BUFFER_PENDING: - vty_event(VTYSH_WRITE, vty->wfd, vty); + vty_event(VTYSH_WRITE, vty); break; case BUFFER_ERROR: vty->monitor = @@ -2084,7 +2076,7 @@ static int vtysh_read(struct thread *thread) if ((nbytes = read(sock, buf, VTY_READ_BUFSIZ)) <= 0) { if (nbytes < 0) { if (ERRNO_IO_RETRY(errno)) { - vty_event(VTYSH_READ, sock, vty); + vty_event(VTYSH_READ, vty); return 0; } vty->monitor = 0; /* disable monitoring to avoid @@ -2150,7 +2142,7 @@ static int vtysh_read(struct thread *thread) if (vty->status == VTY_CLOSE) vty_close(vty); else - vty_event(VTYSH_READ, sock, vty); + vty_event(VTYSH_READ, vty); return 0; } @@ -2657,33 +2649,44 @@ int vty_config_node_exit(struct vty *vty) /* Master of the threads. */ static struct thread_master *vty_master; -static void vty_event(enum event event, int sock, struct vty *vty) +static void vty_event_serv(enum event event, int sock) { struct thread *vty_serv_thread = NULL; switch (event) { case VTY_SERV: - vty_serv_thread = thread_add_read(vty_master, vty_accept, vty, - sock, NULL); + vty_serv_thread = thread_add_read(vty_master, vty_accept, + NULL, sock, NULL); vector_set_index(Vvty_serv_thread, sock, vty_serv_thread); break; #ifdef VTYSH case VTYSH_SERV: - vty_serv_thread = thread_add_read(vty_master, vtysh_accept, vty, - sock, NULL); + vty_serv_thread = thread_add_read(vty_master, vtysh_accept, + NULL, sock, NULL); vector_set_index(Vvty_serv_thread, sock, vty_serv_thread); break; +#endif /* VTYSH */ + default: + assert(!"vty_event_serv() called incorrectly"); + } +} + +static void vty_event(enum event event, struct vty *vty) +{ + switch (event) { +#ifdef VTYSH case VTYSH_READ: - thread_add_read(vty_master, vtysh_read, vty, sock, + thread_add_read(vty_master, vtysh_read, vty, vty->fd, &vty->t_read); break; case VTYSH_WRITE: - thread_add_write(vty_master, vtysh_write, vty, sock, + thread_add_write(vty_master, vtysh_write, vty, vty->wfd, &vty->t_write); break; #endif /* VTYSH */ case VTY_READ: - thread_add_read(vty_master, vty_read, vty, sock, &vty->t_read); + thread_add_read(vty_master, vty_read, vty, vty->fd, + &vty->t_read); /* Time out treatment. */ if (vty->v_timeout) { @@ -2693,7 +2696,7 @@ static void vty_event(enum event event, int sock, struct vty *vty) } break; case VTY_WRITE: - thread_add_write(vty_master, vty_flush, vty, sock, + thread_add_write(vty_master, vty_flush, vty, vty->wfd, &vty->t_write); break; case VTY_TIMEOUT_RESET: @@ -2702,6 +2705,8 @@ static void vty_event(enum event event, int sock, struct vty *vty) thread_add_timer(vty_master, vty_timeout, vty, vty->v_timeout, &vty->t_timeout); break; + default: + assert(!"vty_event() called incorrectly"); } } @@ -2748,7 +2753,7 @@ static int exec_timeout(struct vty *vty, const char *min_str, vty_timeout_val = timeout; vty->v_timeout = timeout; - vty_event(VTY_TIMEOUT_RESET, 0, vty); + vty_event(VTY_TIMEOUT_RESET, vty); return CMD_SUCCESS; |
