axlisten: colors for command line
folkert
folkert at vanheusden.com
Tue Nov 20 08:53:39 EST 2018
> Would it be possible to have just ^M (enter) to exit listen/axlisten,
> because if it is invoked via telnet for a ham app it wants ctrl-c to
> exit...cannot exit...
The version below has the following new 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 <oh7lzb at sral.fi>
Alan Cox GW4PTS <alan at cymru.net>
Jean-Paul for rose decoding
Jeroen Vreeken for INP decoding
+Folkert van Heusden <mail at vanheusden.com>
call:
Alexander Tietzel DG6XA <TIETZE_A at 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
--
Wintips voor de staatsloterij? http://www.slimwinnen.nl/
Meer weten over Bitcoins? http://www.vanheusden.com/bitcoins/
Meer weten over TOR? http://www.vanheusden.com/tor/
----------------------------------------------------------------------
Phone: +31-6-41278122, PGP-key: 1F28D8AE, www.vanheusden.com
More information about the Linux-ham
mailing list