diff options
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 53 |
1 files changed, 41 insertions, 12 deletions
@@ -14,6 +14,7 @@ #include <unistd.h> #include "log.h" +#include "gopher.h" #ifndef OPEN_MAX #define OPEN_MAX 1024 @@ -21,12 +22,15 @@ #define PORT "3000" #define BUFSIZE 1024 +#define HOSTMAX 1025 +#define SERVMAX 256 static int create_server(const char *port) { int fd, yes = 1; struct addrinfo *res, *p, hints; + char host[HOSTMAX], serv[SERVMAX]; memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; @@ -56,38 +60,55 @@ create_server(const char *port) } if (bind(fd, p->ai_addr, p->ai_addrlen) == -1) { perror("bind"); + close(fd); continue; } break; } - freeaddrinfo(res); - if (p == NULL) { + freeaddrinfo(res); fprintf(stderr, "failed to bind\n"); return -1; } if (listen(fd, 32) == -1) { + freeaddrinfo(res); perror("listen"); return -1; } - logmsg(LOG_INFO, "listening on %s", port); + if (getnameinfo(p->ai_addr, p->ai_addrlen, host, sizeof(host), serv, + sizeof(serv), NI_NUMERICHOST) != 0) { + freeaddrinfo(res); + perror("getaddrinfo"); + return -1; + } + freeaddrinfo(res); + + logmsg(LOG_INFO, "listening on %s:%s", host, serv); return fd; } static int accept_connection(int s_fd) { + struct sockaddr_storage sa; + socklen_t salen; + char host[HOSTMAX]; int c_fd; - if ((c_fd = accept(s_fd, NULL, NULL)) == -1) { + if ((c_fd = accept(s_fd, (struct sockaddr *) & sa, &salen)) == -1) { if (errno != EWOULDBLOCK || errno != EAGAIN) { perror("accept"); exit(1); } return -1; } - logmsg(LOG_INFO, "connection accepted"); + if (getnameinfo((struct sockaddr *) & sa, salen, host, sizeof(host), + NULL, 0, NI_NUMERICHOST) != 0) { + perror("gethostname"); + return -1; + } + logmsg(LOG_INFO, "connection accepted from %s", host); return c_fd; } @@ -97,6 +118,7 @@ handle_client(int c_fd) { int n; char buf[BUFSIZE]; + char *lf; n = recv(c_fd, &buf, BUFSIZE - 1, 0); switch (n) { @@ -104,13 +126,20 @@ handle_client(int c_fd) if (errno != EWOULDBLOCK || errno != EAGAIN) { perror("recv"); } + break; case 0: logmsg(LOG_INFO, "connection closed by client"); + break; default: - buf[n] = '\0'; - if (send(c_fd, buf, n, 0) == -1) { - perror("send"); + lf = strchr(buf, '\r'); + if (lf == NULL || *lf != buf[n-2]) { + logmsg(LOG_INFO, "invalid request"); + break; } + *lf = '\0'; + + logmsg(LOG_INFO, "path: %s", buf); + handle_path(c_fd, buf); } close(c_fd); } @@ -166,14 +195,14 @@ main_loop(int s_fd) int main() { - int s_fd; + int fd; - s_fd = create_server(PORT); - if (s_fd == -1) { + fd = create_server(PORT); + if (fd == -1) { fprintf(stderr, "failed to create server\n"); exit(0); } - main_loop(s_fd); + main_loop(fd); return 0; } |