summaryrefslogtreecommitdiffstats
path: root/util.c
diff options
context:
space:
mode:
authorroot <root@nolonger-other.tetra.james.local>2020-10-25 13:26:29 +0000
committerroot <root@nolonger-other.tetra.james.local>2020-10-25 13:26:29 +0000
commit62bc1af6c6a1201db551e1ec523e757415464fd5 (patch)
tree49c2eadf8a51e7e43a059f1aff59997c3c169c5e /util.c
parent4b4e4972088d82cac99941398834d8e6d661682c (diff)
downloadgalaxy_tools-62bc1af6c6a1201db551e1ec523e757415464fd5.tar.gz
galaxy_tools-62bc1af6c6a1201db551e1ec523e757415464fd5.tar.bz2
galaxy_tools-62bc1af6c6a1201db551e1ec523e757415464fd5.zip
tidy up, make less awful
Diffstat (limited to 'util.c')
-rw-r--r--util.c306
1 files changed, 306 insertions, 0 deletions
diff --git a/util.c b/util.c
new file mode 100644
index 0000000..95268b4
--- /dev/null
+++ b/util.c
@@ -0,0 +1,306 @@
+#include <string.h>
+#include <unistd.h>
+#include <termio.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+
+
+
+#include "util.h"
+
+
+void
+set_nonblocking (int fd)
+{
+ long arg = 0;
+ arg = fcntl (fd, F_GETFL, arg);
+ arg |= O_NONBLOCK;
+ fcntl (fd, F_SETFL, arg);
+}
+
+void
+set_blocking (int fd)
+{
+ long arg = 0;
+ arg = fcntl (fd, F_GETFL, arg);
+ arg &= ~O_NONBLOCK;
+ fcntl (fd, F_SETFL, arg);
+}
+
+int fd_can_read (int fd)
+{
+ struct timeval tv = {0};
+ fd_set rfds;
+ FD_ZERO (&rfds);
+ FD_SET (fd, &rfds);
+
+ if (select (fd + 1, &rfds, NULL, NULL, &tv) == 1)
+ return 1;
+
+ return 0;
+}
+
+int fd_drain (int fd)
+{
+ char c;
+
+ while (fd_can_read (fd))
+ if (read (fd, &c, 1) != 1) return -1;
+
+
+ return 0;
+}
+
+
+static speed_t
+baud_to_speed_t (int baud)
+{
+ switch (baud) {
+#ifdef B0
+
+ case 0:
+ return B0;
+#endif
+#ifdef B50
+
+ case 50:
+ return B50;
+#endif
+#ifdef B75
+
+ case 75:
+ return B75;
+#endif
+#ifdef B110
+
+ case 110:
+ return B110;
+#endif
+#ifdef B134
+
+ case 134:
+ return B134;
+#endif
+#ifdef B150
+
+ case 150:
+ return B150;
+#endif
+#ifdef B200
+
+ case 200:
+ return B200;
+#endif
+#ifdef B300
+
+ case 300:
+ return B300;
+#endif
+#ifdef B600
+
+ case 600:
+ return B600;
+#endif
+#ifdef B1200
+
+ case 1200:
+ return B1200;
+#endif
+#ifdef B1800
+
+ case 1800:
+ return B1800;
+#endif
+#ifdef B2400
+
+ case 2400:
+ return B2400;
+#endif
+#ifdef B4800
+
+ case 4800:
+ return B4800;
+#endif
+#ifdef B9600
+
+ case 9600:
+ return B9600;
+#endif
+#ifdef B19200
+
+ case 19200:
+ return B19200;
+#endif
+#ifdef B38400
+
+ case 38400:
+ return B38400;
+#endif
+#ifdef B57600
+
+ case 57600:
+ return B57600;
+#endif
+#ifdef B115200
+
+ case 115200:
+ return B115200;
+#endif
+#ifdef B230400
+
+ case 230400:
+ return B230400;
+#endif
+ }
+
+ return -1;
+}
+
+
+
+static void
+default_termios (struct termios *termios)
+{
+ termios->c_iflag = 0;
+ termios->c_oflag = NL0 | CR0 | TAB0 | BS0 | VT0 | FF0;
+ termios->c_lflag = 0;
+ termios->c_cflag = CS8 | CREAD | CLOCAL;
+
+ termios->c_cc[VINTR] = 003;
+ termios->c_cc[VQUIT] = 034;
+ termios->c_cc[VERASE] = 0177;
+ termios->c_cc[VKILL] = 025;
+ termios->c_cc[VEOF] = 004;
+ termios->c_cc[VEOL] = 0;
+ termios->c_cc[VEOL2] = 0;
+ termios->c_cc[VSTART] = 021;
+ termios->c_cc[VSTOP] = 023;
+ termios->c_cc[VSUSP] = 032;
+ termios->c_cc[VLNEXT] = 026;
+ termios->c_cc[VWERASE] = 027;
+ termios->c_cc[VREPRINT] = 022;
+ termios->c_cc[VDISCARD] = 017;
+
+
+}
+
+
+//XXX: no locks
+
+int open_tty (const char *path, int baud)
+{
+ int fd;
+ struct termios termios;
+ speed_t s = baud_to_speed_t (baud);
+
+ if (s == (speed_t) -1) return -1;
+
+
+ fd = open (path, O_RDWR | O_NOCTTY | O_NONBLOCK);
+
+
+ if (tcgetattr (fd, &termios)) {
+ close (fd);
+ return -1;
+ }
+
+ default_termios (&termios);
+
+ if (tcsetattr (fd, TCSANOW, &termios)) {
+ close (fd);
+ return -1;
+ }
+
+ cfsetispeed (&termios, s);
+ cfsetospeed (&termios, s);
+
+ return fd;
+}
+
+
+
+static int host_to_sin (const char *host, struct sockaddr_in *sin)
+{
+
+ struct hostent *he = gethostbyname2 (host, AF_INET);
+
+ if (!he) {
+ if (!inet_aton (host, &sin->sin_addr))
+ return -1;
+
+ return 0;
+ }
+
+ if (he->h_addrtype != AF_INET)
+ return -1;
+
+ sin->sin_family = AF_INET;
+
+ memcpy (&sin->sin_addr, he->h_addr_list[0], he->h_length);
+
+ return 0;
+}
+
+
+int open_tcp_client (const char *host, unsigned port)
+{
+ struct sockaddr_in sin = {0};
+ int fd;
+
+
+ if (host_to_sin (host, &sin))
+ return -1;
+
+
+ fd = socket (PF_INET, SOCK_STREAM, 0);
+
+ if (fd < 0) return -1;
+
+ sin.sin_port = htons (port);
+
+ if (connect (fd, (struct sockaddr *)&sin, sizeof (sin))) {
+ close (fd);
+ return -1;
+ }
+
+ return fd;
+}
+
+int open_tcp_server (unsigned port)
+{
+ int fd;
+ int enable = 1;
+ struct sockaddr_in sin = {0};
+
+ fd = socket (PF_INET, SOCK_STREAM, 0);
+
+ if (fd < 0) return -1;
+
+ if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof (enable)))
+ return -1;
+
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons (port);
+ sin.sin_addr.s_addr = INADDR_ANY;
+
+ if (bind (fd, (struct sockaddr *)&sin, sizeof (sin))) {
+ close (fd);
+ return -1;
+ }
+
+ if (listen (fd, 5)) {
+ close (fd);
+ return -1;
+ }
+
+ return fd;
+}
+
+
+
+