16 #include <sys/socket.h>
18 #include <sys/epoll.h>
19 #include <sys/ioctl.h>
32 #include <arpa/telnet.h>
38 #define SOCKET_FILE "/run/vpp/cli.sock"
48 term = is_interactive ? getenv (
"TERM") :
"vppctl";
53 IAC, SB, TELOPT_TTYPE, 0, term, IAC, SE);
62 if (ioctl (STDIN_FILENO, TIOCGWINSZ, &ws) < 0)
70 ws.ws_col >> 8, ws.ws_col & 0xff,
71 ws.ws_row >> 8, ws.ws_row & 0xff, IAC, SE);
84 tcsetattr (STDIN_FILENO, TCSAFLUSH, &
orig_tio);
95 if (s->rx_buffer[
i] == IAC)
97 if (s->rx_buffer[
i + 1] == SB)
100 char opt = s->rx_buffer[
i + 2];
102 while (s->rx_buffer[
i] != IAC)
111 if (opt == TELOPT_TTYPE)
116 else if (is_interactive && opt == TELOPT_NAWS)
123 TELCMD (s->rx_buffer[
i + 1]),
124 TELOPT (s->rx_buffer[
i + 2]));
142 struct epoll_event event;
149 int is_interactive = 0;
160 if (argc > 1 && strncmp (argv[0],
"-s", 2) == 0)
170 cmd =
format (cmd,
"%s%c", (argv++)[0], argc ?
' ' : 0);
178 is_interactive = isatty (STDIN_FILENO) && cmd == 0;
185 if (sigaction (SIGWINCH, &sa, 0) < 0)
193 if (sigaction (SIGTERM, &sa, 0) < 0)
200 if (tcgetattr (STDIN_FILENO, &
orig_tio) < 0)
209 tio.c_lflag &= ~(ECHO | ICANON | IEXTEN);
213 if (tcsetattr (STDIN_FILENO, TCSAFLUSH, &tio) < 0)
220 efd = epoll_create1 (0);
223 event.events = EPOLLIN | EPOLLPRI | EPOLLERR;
224 event.data.fd = STDIN_FILENO;
225 if (epoll_ctl (efd, EPOLL_CTL_ADD, STDIN_FILENO, &event) != 0)
236 event.events = EPOLLIN | EPOLLPRI | EPOLLERR;
237 event.data.fd = s->fd;
238 if (epoll_ctl (efd, EPOLL_CTL_ADD, s->fd, &event) != 0)
254 if ((n = epoll_wait (efd, &event, 1, -1)) < 0)
267 if (event.data.fd == STDIN_FILENO)
275 n = read (STDIN_FILENO,
c,
sizeof (
c));
288 else if (event.data.fd == s->fd)
302 u8 *p = str, *q = str;
307 while (q < (p +
len) && *q)
310 n = write (STDOUT_FILENO, p, q - p);
317 while (q < (p +
len) && !*q)
329 if (do_quit && do_quit < acked)
336 if (cmd && sent_ttype)
365 tcsetattr (STDIN_FILENO, TCSAFLUSH, &
orig_tio);