summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c53
1 files changed, 41 insertions, 12 deletions
diff --git a/main.c b/main.c
index 466ab83..0d45d46 100644
--- a/main.c
+++ b/main.c
@@ -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;
}