aboutsummaryrefslogtreecommitdiff
path: root/src/server.c
diff options
context:
space:
mode:
authorkartofen <mladenovnasko0@gmail.com>2023-01-26 14:58:09 +0200
committerkartofen <mladenovnasko0@gmail.com>2023-01-26 14:58:09 +0200
commit5e1ae8b33873661b669eda509fcd000f8a964126 (patch)
tree6099bee318d9f0033949d23a3eeded6974d34b35 /src/server.c
very simple work withs html based on file path
Diffstat (limited to 'src/server.c')
-rw-r--r--src/server.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/src/server.c b/src/server.c
new file mode 100644
index 0000000..73a8d59
--- /dev/null
+++ b/src/server.c
@@ -0,0 +1,122 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+
+#include "log.h"
+#include "server.h"
+
+struct sock_t {
+ int sockfd;
+ char ip[INET6_ADDRSTRLEN];
+};
+
+static void *get_in_addr(struct sockaddr *sa)
+{
+ if (sa->sa_family == AF_INET) {
+ return &(((struct sockaddr_in*)sa)->sin_addr);
+ }
+
+ return &(((struct sockaddr_in6*)sa)->sin6_addr);
+}
+
+int server_start(char *port, sock_t *sock)
+{
+ struct addrinfo hints, *servinfo;
+ int rv;
+
+ memset(&hints, 0, sizeof hints);
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_PASSIVE; // use my IP
+
+ if ((rv = getaddrinfo(NULL, port, &hints, &servinfo)) != 0) {
+ err("getaddrinfo: %s", gai_strerror(rv));
+ return 1;
+ }
+
+ // loop through all the results and bind to the first we can
+ struct addrinfo *p = NULL;
+ for(p = servinfo; p != NULL; p = p->ai_next) {
+ if ((sock->sockfd = socket(p->ai_family, p->ai_socktype,
+ p->ai_protocol)) == -1) {
+ err("socker: %s", strerror(errno));
+ continue;
+ }
+
+ int yes=1;
+ if (setsockopt(sock->sockfd, SOL_SOCKET, SO_REUSEADDR, &yes,
+ sizeof(int)) == -1) {
+ err("setsockopt: %s", strerror(errno));
+ return 1;
+ }
+
+ if (bind(sock->sockfd, p->ai_addr, p->ai_addrlen) == -1) {
+ close(sock->sockfd);
+ err("bind: %s", strerror(errno));
+ continue;
+ }
+
+ break;
+ }
+
+ if (p == NULL) {
+ err("server: failed to bind");
+ return 1;
+ }
+
+ freeaddrinfo(servinfo);
+
+ if(listen(sock->sockfd, 10) == -1) {
+ err("listen: %s", strerror(errno));
+ return 1;
+ }
+ return 0;
+}
+
+int server_accept(sock_t *sock, sock_t *conn)
+{
+ struct sockaddr_storage conn_addr;
+ socklen_t sz = sizeof(conn_addr);
+ conn->sockfd = accept(sock->sockfd, (struct sockaddr *)&conn_addr, &sz);
+ if(conn->sockfd == -1) {
+ err("accept: %s", strerror(errno));
+ return 1;
+ }
+
+ inet_ntop(conn_addr.ss_family,
+ get_in_addr((struct sockaddr *)&conn_addr),
+ conn->ip, sizeof(conn->ip));
+
+ return 0;
+}
+
+ssize_t server_send(sock_t *sock, char *buf, size_t sz)
+{
+ return send(sock->sockfd, buf, sz, 0);
+}
+
+ssize_t server_recv(sock_t *sock, char *buf, size_t sz)
+{
+ return recv(sock->sockfd, buf, sz, 0);
+}
+
+char *server_connection_ip(sock_t *conn)
+{
+ return conn->ip;
+}
+
+sock_t *server_sock_create()
+{
+ return (sock_t *)malloc(sizeof(sock_t));
+}
+
+void server_sock_close(sock_t *s)
+{
+ close(s->sockfd);
+ free(s);
+}