Hi, Maybe this patch can help?
It is against git://git.linux-ax25.org/pub/scm/ax25-apps.git This patch below has the following features: - colors in non-ncurses mode (-C) - press 'q' to exit (-e to enable) diff --git a/AUTHORS b/AUTHORS index 7b91e72..deeee0d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -17,6 +17,7 @@ Heikki Hannikainen OH7LZB <oh7...@sral.fi> Alan Cox GW4PTS <a...@cymru.net> Jean-Paul for rose decoding Jeroen Vreeken for INP decoding +Folkert van Heusden <m...@vanheusden.com> call: Alexander Tietzel DG6XA <tietz...@etech.fh-hamburg.de> diff --git a/listen/listen.c b/listen/listen.c index 6504ed5..fb80987 100644 --- a/listen/listen.c +++ b/listen/listen.c @@ -3,6 +3,8 @@ #include <netdb.h> #include <unistd.h> +#include <termios.h> +#include <poll.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -202,9 +204,15 @@ int main(int argc, char **argv) struct ifreq ifr; int proto = ETH_P_AX25; int exit_code = EXIT_SUCCESS; + char q_exit = 0; + struct pollfd fds[2]; + struct termios oldtermios, newtermios; - while ((s = getopt(argc, argv, "8achip:rtv")) != -1) { + while ((s = getopt(argc, argv, "e8acChip:rtv")) != -1) { switch (s) { + case 'e': + q_exit = 1; + break; case '8': sevenbit = 0; break; @@ -214,6 +222,9 @@ int main(int argc, char **argv) case 'c': color = 1; break; + case 'C': + a_color = 1; + break; case 'h': dumpstyle = HEX; break; @@ -276,6 +287,17 @@ int main(int argc, char **argv) return 1; } + fds[0].fd = sock; + fds[0].events = POLLIN; + + fds[1].fd = STDIN_FILENO; + fds[1].events = POLLIN; + + tcgetattr(STDIN_FILENO, &oldtermios); + newtermios = oldtermios; + + cfmakeraw(&newtermios); + if (color) { color = initcolor(); /* Initialize color support */ if (!color) @@ -285,93 +307,120 @@ int main(int argc, char **argv) setservent(1); while (!sigint) { + int rc; + asize = sizeof(sa); - signal(SIGINT, handle_sigint); - signal(SIGTERM, handle_sigint); - size = recvfrom(sock, buffer, sizeof(buffer), 0, &sa, &asize); - if (size == -1) { - /* - * Signals are cared for by the handler, and we - * don't want to abort on SIGWINCH - */ - if (errno == EINTR) { - refresh(); - continue; - } else if (!(errno == EBADF && sigint)) { - perror("recv"); - exit_code = errno; - } + tcsetattr(STDIN_FILENO, TCSANOW, &newtermios); + fds[0].events = fds[1].events = POLLIN; + fds[0].revents = fds[1].revents = 0; + + rc = poll(fds, q_exit ? 2 : 1, -1); + if (rc == -1) { + perror("poll"); break; } - gettimeofday(&t_recv, NULL); - signal(SIGINT, SIG_DFL); - signal(SIGTERM, SIG_DFL); - if (sock == -1 || sigint) - break; - if (dev != NULL && strcmp(dev, sa.sa_data) != 0) + if (rc == 0) continue; - if (proto == ETH_P_ALL) { - strcpy(ifr.ifr_name, sa.sa_data); + if (q_exit && fds[1].revents == POLLIN) { + int c = getchar(); + if (c == 'q' || c == 3) + break; + } + + tcsetattr(STDIN_FILENO, TCSANOW, &oldtermios); + + if (fds[0].revents == POLLIN) { signal(SIGINT, handle_sigint); signal(SIGTERM, handle_sigint); - if (ioctl(sock, SIOCGIFHWADDR, &ifr) == -1) { - if (!(errno == EBADF && sigint)) { - perror("SIOCGIFHWADDR"); + size = recvfrom(sock, buffer, sizeof(buffer), 0, &sa, &asize); + if (size == -1) { + /* + * Signals are cared for by the handler, and we + * don't want to abort on SIGWINCH + */ + if (errno == EINTR) { + refresh(); + continue; + } else if (!(errno == EBADF && sigint)) { + perror("recv"); exit_code = errno; - break; } + break; } + gettimeofday(&t_recv, NULL); signal(SIGINT, SIG_DFL); signal(SIGTERM, SIG_DFL); if (sock == -1 || sigint) break; - if (ifr.ifr_hwaddr.sa_family == AF_AX25) { - if (size > 2 && *buffer == 0xcc) { - /* IP packets from the ax25 de-segmenter - are seen on socket "PF_PACKET, - SOCK_PACKET, ETH_P_ALL" without - AX.25 header (just the IP-frame), - prefixed by 0xcc (AX25_P_IP). - It's unclear why in the kernel code - this happens (unsegmentet AX25 PID - AX25_P_IP have not this behavior). - We have already displayed all the - segments and like to ignore this - data. - AX.25 packets start with a kiss - byte (buffer[0]); ax25_dump() - looks for it. - There's no kiss command 0xcc - defined; kiss bytes are checked - against & 0xf (= 0x0c), which is - also not defined. - Kiss commands may have one argument. - => We can make safely make the - assumption for first byte == 0xcc - and length > 2, that we safeley can - detect those IP frames, and then - ignore it. - */ - continue; - } + + if (dev != NULL && strcmp(dev, sa.sa_data) != 0) + continue; + + if (proto == ETH_P_ALL) { + strcpy(ifr.ifr_name, sa.sa_data); + signal(SIGINT, handle_sigint); + signal(SIGTERM, handle_sigint); + if (ioctl(sock, SIOCGIFHWADDR, &ifr) == -1) { + if (!(errno == EBADF && sigint)) { + perror("SIOCGIFHWADDR"); + exit_code = errno; + break; + } + } + signal(SIGINT, SIG_DFL); + signal(SIGTERM, SIG_DFL); + if (sock == -1 || sigint) + break; + if (ifr.ifr_hwaddr.sa_family == AF_AX25) { + if (size > 2 && *buffer == 0xcc) { + /* IP packets from the ax25 de-segmenter + are seen on socket "PF_PACKET, + SOCK_PACKET, ETH_P_ALL" without + AX.25 header (just the IP-frame), + prefixed by 0xcc (AX25_P_IP). + It's unclear why in the kernel code + this happens (unsegmentet AX25 PID + AX25_P_IP have not this behavior). + We have already displayed all the + segments and like to ignore this + data. + AX.25 packets start with a kiss + byte (buffer[0]); ax25_dump() + looks for it. + There's no kiss command 0xcc + defined; kiss bytes are checked + against & 0xf (= 0x0c), which is + also not defined. + Kiss commands may have one argument. + => We can make safely make the + assumption for first byte == 0xcc + and length > 2, that we safeley can + detect those IP frames, and then + ignore it. + */ + continue; + } + display_port(sa.sa_data); + ki_dump(buffer, size, dumpstyle); + /* lprintf(T_DATA, "\n"); */ + } + } else { display_port(sa.sa_data); ki_dump(buffer, size, dumpstyle); -/* lprintf(T_DATA, "\n"); */ + /* lprintf(T_DATA, "\n"); */ } - } else { - display_port(sa.sa_data); - ki_dump(buffer, size, dumpstyle); -/* lprintf(T_DATA, "\n"); */ + if (color) + refresh(); } - if (color) - refresh(); } if (color) endwin(); + tcsetattr(STDIN_FILENO, TCSANOW, &oldtermios); + return exit_code; } diff --git a/listen/listen.h b/listen/listen.h index 46ec397..72c185e 100644 --- a/listen/listen.h +++ b/listen/listen.h @@ -36,6 +36,7 @@ /* In utils.c */ extern int color; /* Colorized mode */ +extern int a_color; /* ANSI-colorized mode */ extern int sevenbit; /* Are we on a 7-bit terminal? */ extern int ibmhack; /* IBM mapping? */ diff --git a/listen/utils.c b/listen/utils.c index 4d99e10..26653a4 100644 --- a/listen/utils.c +++ b/listen/utils.c @@ -16,6 +16,7 @@ #include "listen.h" int color = 0; /* Colorized? */ +int a_color = 0; /* ANSI-colorized mode */ int sevenbit = 1; /* Are we on a 7-bit terminal? */ int ibmhack = 0; /* IBM mapping? */ @@ -45,7 +46,7 @@ void lprintf(int dtype, char *fmt, ...) vsnprintf(str, 1024, fmt, args); va_end(args); - if (color) { + if (color || a_color) { for (p = str; *p != '\0'; p++) { ch = *p; @@ -63,9 +64,20 @@ void lprintf(int dtype, char *fmt, ...) || (dtype == T_TIMESTAMP)) ch |= A_BOLD; - ch |= COLOR_PAIR(dtype); + if (color) { + ch |= COLOR_PAIR(dtype); + addch(ch); + } + else { /* a_color */ + if (ch & A_BOLD) + printf("\x1b[1m"); + if (ch & A_REVERSE) + printf("\x1b[7m"); - addch(ch); + printf("\x1b[%dm%c", 30 + (dtype & 7), ch & 255); + + printf("\x1b[0m"); + } } } else { for (p = str; *p != '\0'; p++) Folkert van Heusden -- ---------------------------------------------------------------------- Phone: +31-6-41278122, PGP-key: 1F28D8AE, www.vanheusden.com