aboutsummaryrefslogtreecommitdiff
path: root/server.c
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2023-07-21 01:07:57 +0200
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2023-07-21 01:40:55 +0200
commit7fe639b3ba7a253627d2cd34f3b97bd95b0a90b3 (patch)
treeab50067686bfdc87b35ddfa29112af5ca0440574 /server.c
parent1d4480c0f36f9d4e75c00e58c065b4c43e53b4f3 (diff)
downloadslcl-7fe639b3ba7a253627d2cd34f3b97bd95b0a90b3.tar.gz
Remove files now provided by slweb
Diffstat (limited to 'server.c')
-rw-r--r--server.c373
1 files changed, 0 insertions, 373 deletions
diff --git a/server.c b/server.c
deleted file mode 100644
index 22615b2..0000000
--- a/server.c
+++ /dev/null
@@ -1,373 +0,0 @@
-#define _POSIX_C_SOURCE 200809L
-
-#include "server.h"
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <poll.h>
-#include <unistd.h>
-#include <errno.h>
-#include <signal.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-struct server
-{
- int fd;
-
- struct server_client
- {
- int fd;
- bool write;
- struct server_client *prev, *next;
- } *c;
-};
-
-int server_close(struct server *const s)
-{
- int ret = 0;
-
- if (!s)
- return 0;
- else if (s->fd >= 0)
- ret = close(s->fd);
-
- free(s);
- return ret;
-}
-
-int server_client_close(struct server *const s, struct server_client *const c)
-{
- int ret = 0;
-
- for (struct server_client *ref = s->c; ref; ref = ref->next)
- {
- if (c == ref)
- {
- struct server_client *const next = ref->next;
-
- if ((ret = close(c->fd)))
- {
- fprintf(stderr, "%s: close(2): %s\n",
- __func__, strerror(errno));
- return -1;
- }
- else if (ref->prev)
- ref->prev->next = next;
- else
- s->c = next;
-
- if (next)
- next->prev = ref->prev;
-
- free(ref);
- break;
- }
- }
-
- return ret;
-}
-
-int server_read(void *const buf, const size_t n, struct server_client *const c)
-{
- const ssize_t r = read(c->fd, buf, n);
-
- if (r < 0)
- fprintf(stderr, "%s: read(2): %s\n", __func__, strerror(errno));
-
- return r;
-}
-
-int server_write(const void *const buf, const size_t n,
- struct server_client *const c)
-{
- const ssize_t w = write(c->fd, buf, n);
-
- if (w < 0)
- fprintf(stderr, "%s: write(2): %s\n", __func__, strerror(errno));
-
- return w;
-}
-
-static struct server_client *alloc_client(struct server *const s)
-{
- struct sockaddr_in addr;
- socklen_t sz = sizeof addr;
- const int fd = accept(s->fd, (struct sockaddr *)&addr, &sz);
-
- if (fd < 0)
- {
- fprintf(stderr, "%s: accept(2): %s\n",
- __func__, strerror(errno));
- return NULL;
- }
-
- const int flags = fcntl(fd, F_GETFL);
-
- if (flags < 0)
- {
- fprintf(stderr, "%s: fcntl(2) F_GETFL: %s\n",
- __func__, strerror(errno));
- return NULL;
- }
- else if (fcntl(fd, F_SETFL, flags | O_NONBLOCK))
- {
- fprintf(stderr, "%s: fcntl(2) F_SETFL: %s\n",
- __func__, strerror(errno));
- return NULL;
- }
-
- struct server_client *const c = malloc(sizeof *c);
-
- if (!c)
- {
- fprintf(stderr, "%s: malloc(3): %s\n", __func__, strerror(errno));
- return NULL;
- }
-
- *c = (const struct server_client)
- {
- .fd = fd
- };
-
- if (!s->c)
- s->c = c;
- else
- for (struct server_client *ref = s->c; ref; ref = ref->next)
- if (!ref->next)
- {
- ref->next = c;
- c->prev = ref;
- break;
- }
-
- return c;
-}
-
-void server_client_write_pending(struct server_client *const c,
- const bool write)
-{
- c->write = write;
-}
-
-static volatile sig_atomic_t do_exit;
-
-static void handle_signal(const int signum)
-{
- switch (signum)
- {
- case SIGINT:
- /* Fall through. */
- case SIGTERM:
- do_exit = 1;
- break;
-
- default:
- break;
- }
-}
-
-static size_t get_clients(const struct server *const s)
-{
- size_t ret = 0;
-
- for (const struct server_client *c = s->c; c; c = c->next)
- ret++;
-
- return ret;
-}
-
-struct server_client *server_poll(struct server *const s, bool *const io,
- bool *const exit)
-{
- struct server_client *ret = NULL;
- const size_t n_clients = get_clients(s);
- const nfds_t n = n_clients + 1;
- struct pollfd *const fds = malloc(n * sizeof *fds);
-
- if (!fds)
- {
- fprintf(stderr, "%s: malloc(3): %s\n", __func__, strerror(errno));
- goto end;
- }
-
- struct pollfd *const sfd = &fds[0];
-
- *io = *exit = false;
- *sfd = (const struct pollfd)
- {
- .fd = s->fd,
- .events = POLLIN
- };
-
- for (struct {const struct server_client *c; size_t j;}
- _ = {.c = s->c, .j = 1}; _.c; _.c = _.c->next, _.j++)
- {
- struct pollfd *const p = &fds[_.j];
- const int fd = _.c->fd;
-
- *p = (const struct pollfd)
- {
- .fd = fd,
- .events = POLLIN
- };
-
- if (_.c->write)
- p->events |= POLLOUT;
- }
-
- int res;
-
-again:
-
- res = poll(fds, n, -1);
-
- if (res < 0)
- {
- if (do_exit)
- {
- *exit = true;
- goto end;
- }
-
- switch (errno)
- {
- case EAGAIN:
- /* Fall through. */
- case EINTR:
- goto again;
-
- default:
- fprintf(stderr, "%s: poll(2): %s\n", __func__, strerror(errno));
- break;
- }
-
- goto end;
- }
- else if (!res)
- {
- fprintf(stderr, "%s: poll(2) returned zero\n", __func__);
- goto end;
- }
- else if (sfd->revents)
- {
- ret = alloc_client(s);
- goto end;
- }
-
- for (struct {struct server_client *c; size_t j;}
- _ = {.c = s->c, .j = 1}; _.c; _.c = _.c->next, _.j++)
- {
- const struct pollfd *const p = &fds[_.j];
-
- if (p->revents)
- {
- *io = true;
- ret = _.c;
- goto end;
- }
- }
-
- fprintf(stderr, "%s: unlisted fd\n", __func__);
-
-end:
- free(fds);
- return ret;
-}
-
-static int init_signals(void)
-{
- struct sigaction sa =
- {
- .sa_handler = handle_signal,
- .sa_flags = SA_RESTART
- };
-
- sigemptyset(&sa.sa_mask);
-
- if (sigaction(SIGINT, &sa, NULL))
- {
- fprintf(stderr, "%s: sigaction(2) SIGINT: %s\n",
- __func__, strerror(errno));
- return -1;
- }
- else if (sigaction(SIGTERM, &sa, NULL))
- {
- fprintf(stderr, "%s: sigaction(2) SIGTERM: %s\n",
- __func__, strerror(errno));
- return -1;
- }
- else if (sigaction(SIGPIPE, &sa, NULL))
- {
- fprintf(stderr, "%s: sigaction(2) SIGPIPE: %s\n",
- __func__, strerror(errno));
- return -1;
- }
-
- return 0;
-}
-
-struct server *server_init(const unsigned short port)
-{
- struct server *const s = malloc(sizeof *s);
-
- if (!s)
- {
- fprintf(stderr, "%s: malloc(3): %s\n", __func__, strerror(errno));
- goto failure;
- }
-
- *s = (const struct server)
- {
- .fd = socket(AF_INET, SOCK_STREAM, 0)
- };
-
- if (s->fd < 0)
- {
- fprintf(stderr, "%s: socket(2): %s\n", __func__, strerror(errno));
- goto failure;
- }
- else if (init_signals())
- {
- fprintf(stderr, "%s: init_signals failed\n", __func__);
- goto failure;
- }
-
- const struct sockaddr_in addr =
- {
- .sin_family = AF_INET,
- .sin_port = htons(port)
- };
-
- enum {QUEUE_LEN = 10};
-
- if (bind(s->fd, (const struct sockaddr *)&addr, sizeof addr))
- {
- fprintf(stderr, "%s: bind(2): %s\n", __func__, strerror(errno));
- goto failure;
- }
- else if (listen(s->fd, QUEUE_LEN))
- {
- fprintf(stderr, "%s: listen(2): %s\n", __func__, strerror(errno));
- goto failure;
- }
-
- struct sockaddr_in in;
- socklen_t sz = sizeof in;
-
- if (getsockname(s->fd, (struct sockaddr *)&in, &sz))
- {
- fprintf(stderr, "%s: getsockname(2): %s\n", __func__, strerror(errno));
- goto failure;
- }
-
- printf("Listening on port %hu\n", ntohs(in.sin_port));
- return s;
-
-failure:
- server_close(s);
- return NULL;
-}