diff options
Diffstat (limited to 'src/b98.c')
-rw-r--r-- | src/b98.c | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/src/b98.c b/src/b98.c new file mode 100644 index 0000000..2ca408f --- /dev/null +++ b/src/b98.c @@ -0,0 +1,112 @@ +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/select.h> +#include <unistd.h> + +#include "b98.h" +#include "tls.h" + +pid_t pid = 0; +int from_b98[2]; +int to_b98[2]; + +#define PARENT_READ from_b98[0] +#define CHILD_WRITE from_b98[1] +#define CHILD_READ to_b98[0] +#define PARENT_WRITE to_b98[1] + +int bot_init(void) +{ + if (pipe (from_b98)) { + perror("from_b98 pipe"); + return 1; + } + if (pipe (to_b98)) { + perror("to_b98 pipe"); + return 1; + } + pid = fork (); + if (pid == (pid_t) 0) { // Child process + close(PARENT_WRITE); + close(PARENT_READ); + + dup2(CHILD_READ, STDIN_FILENO); close(CHILD_READ); + dup2(CHILD_WRITE, STDOUT_FILENO); close(CHILD_WRITE); + + execvp("fungi", (char *[]) { "fungi", "bot.b98" } ); + perror("execv"); + return 1; + } + else if (pid < (pid_t) 0) { + fprintf (stderr, "Fork failed.\n"); + return 1; + } + else { // Parent process + close(CHILD_READ); + close(CHILD_WRITE); + return 0; + } +} + +int bot_loop(int socket_fd) +{ + fd_set rfds; + while (1) { + struct timeval timeout; + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + FD_ZERO(&rfds); + FD_SET(PARENT_READ, &rfds); + FD_SET(socket_fd, &rfds); + select(20, &rfds, NULL, NULL, &timeout); + if ( FD_ISSET(PARENT_READ, &rfds) ) { + static char sbuf[512]; /* string buffer */ + static int n = 0; /* nition in buffer */ + ssize_t len = n + read(PARENT_READ, sbuf + n, 512 - n); + while (n < len) { + if ((n > 0 && sbuf[n] == '\n' && sbuf[n - 1] == '\r') ) { /* If we got a full message */ + tls_send(sbuf, n); + sbuf[n - 1] = '\0'; + printf(">>> %s\n", sbuf); + memmove(sbuf, sbuf + n + 1, len - n - 1); + len = len - n - 1; + if (len == 1) + len = 0; + n = 0; /* we reinitialise n for the next run */ + } else if (n == 512) { /* If we got a full buffer without finding a \r\n */ + fprintf(stderr, "We got a full buffer without finding a \r\n"); + return 2; + } else { /* Nothing to do otherwise but roll the next char */ + n++; + } + } + } else if ( FD_ISSET(socket_fd, &rfds) ) { + tls_read(&bot_handle_input); + } + } +} + +int bot_handle_input(const char* const sbuf, int len) +{ + static char msg[512]; + static int pos = 0; /* position in msg buffer */ + for (int n = 0; n < len; n++) { + msg[pos] = sbuf[n]; + if ((n > 0 && sbuf[n] == '\n' && sbuf[n - 1] == '\r') ) { /* If we got a full message */ + write(PARENT_WRITE, msg, n); + msg[pos - 1] = '\0'; + printf("<<< %s\n", msg); + pos = 0; /* we reinitialise pos for the next run */ + } else if (pos == sizeof(msg)) { /* If we got a full buffer without finding a \r\n */ + fprintf(stderr, "We got a full buffer without finding a \r\n"); + return 2; + } else { /* Nothing to do otherwise but roll the next char */ + pos++; + } + } + + return 0; +} |