diff options
-rw-r--r-- | ingest.c | 70 |
1 files changed, 69 insertions, 1 deletions
diff --git a/ingest.c b/ingest.c index dde890a..d0b8bca 100644 --- a/ingest.c +++ b/ingest.c @@ -14,11 +14,79 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <assert.h> #include <err.h> +#include <fcntl.h> +#include <poll.h> +#include <stdint.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/un.h> #include <sysexits.h> +#include <unistd.h> int main(void) { - // TODO: Read info, listen on socket, emulate terminal. + int error; + + // TODO: Read info from file. + const char *path = "example.sock"; + + int sock = socket(PF_LOCAL, SOCK_STREAM, 0); + if (sock < 0) err(EX_OSERR, "socket"); + + struct sockaddr_un addr = { .sun_family = AF_LOCAL }; + strncpy(addr.sun_path, path, sizeof(addr.sun_path)); + error = bind(sock, (struct sockaddr *)&addr, SUN_LEN(&addr)); + if (error) err(EX_CANTCREAT, "%s", path); + + error = listen(sock, 0); + if (error) err(EX_OSERR, "listen"); + + uint32_t clients[8] = {0}; + + struct pollfd fds[2] = { + { .events = POLLIN, .fd = STDIN_FILENO }, + { .events = POLLIN, .fd = sock }, + }; + while (0 < poll(fds, 2, -1)) { + if (fds[0].revents) { + char buf[4096]; + ssize_t rlen = read(STDIN_FILENO, buf, sizeof(buf)); + if (rlen < 0) err(EX_IOERR, "read"); + + // TODO: Update local terminal. + + for (int i = 0; i < 8; ++i) { + if (!clients[i]) continue; + for (int j = 0; j < 32; ++j) { + if (!(clients[i] & 1UL << j)) continue; + int fd = 32 * i + j; + + ssize_t wlen = write(fd, buf, rlen); + if (wlen < 0) { + close(fd); + clients[i] &= ~(1UL << j); + } + } + } + } + + if (fds[1].revents) { + int fd = accept(sock, NULL, NULL); + if (fd < 0) err(EX_IOERR, "accept"); + fcntl(fd, F_SETFL, O_NONBLOCK); + + int yes = 1; + error = setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &yes, sizeof(yes)); + if (error) err(EX_IOERR, "setsockopt"); + + assert(fd < 256); + clients[fd / 64] |= 1 << (fd % 64); + + // TODO: Send snapshot. + } + } + err(EX_IOERR, "poll"); } |