/*
 * This code is GPL.
 * 2012-11-17 (1391-08-27)
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <libgen.h>

#define BUFSIZE 65535
#define BACKLOG 10		/* pending connections queue length */
#define PORT "8181"

int main(int argc, char **argv)
{
	int i, len, status, listen_fd, accept_fd, file_fd, yes = 1;
	socklen_t addr_size;
	char buffer[BUFSIZE + 1];
	char *me = basename(argv[0]);
	char *filename = basename(argv[1]);
	char *file_addr = argv[1];
	struct addrinfo hints, *servinfo;
	/* Static variables will fill with zeros */
	static struct sockaddr_storage client_addr;

	/* Load up address structs */
	memset(&hints, 0, sizeof hints);	/* make sure the struct is empty */
	hints.ai_family = AF_INET;	/* use IPv4 */
	hints.ai_socktype = SOCK_STREAM;	/* TCP stream sockets */
	hints.ai_flags = AI_PASSIVE;	/* fill in my IP */
	status = getaddrinfo(NULL, PORT, &hints, &servinfo);
	if (status != 0) {
		fprintf(stderr, "getaddrinfo error: %s\n",
			gai_strerror(status));
		exit(EXIT_FAILURE);
	}

	/* Setup a network socket */
	listen_fd = socket(servinfo->ai_family, servinfo->ai_socktype,
			   servinfo->ai_protocol);
	if (listen_fd == -1) {
		perror("socket error: ");
		exit(EXIT_FAILURE);
	}

	/* if port is in the TIME_WAIT state, go ahead and reuse it anyway. */
	status = setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR,
			    &yes, sizeof yes);
	if (status == -1) {
		perror("setsockopt error: ");
		exit(EXIT_FAILURE);
	}

	/* Bind it to the port */
	status = bind(listen_fd, servinfo->ai_addr, servinfo->ai_addrlen);
	if (status == -1) {
		perror("bind error: ");
		exit(EXIT_FAILURE);
	}

	/* Start listening to the port */
	status = listen(listen_fd, BACKLOG);
	if (status == -1) {
		perror("listen error: ");
		exit(EXIT_FAILURE);
	}

	while (1) {

		/* Accept an incoming connection */
		addr_size = sizeof(client_addr);
		accept_fd = accept(listen_fd, (struct sockaddr *)&client_addr,
				   &addr_size);
		if (accept_fd == -1) {
			perror("accept error: ");
			exit(EXIT_FAILURE);
		}

		/* Read browser request */
		len = recv(accept_fd, buffer, BUFSIZE, 0);
		if (len == 0 || len == -1) {
			fprintf(stderr, "Failed to read browser request");
			exit(EXIT_FAILURE);
		}
		if (len > 0 && len < BUFSIZE)
			buffer[len] = 0;
		else
			buffer[0] = 0;

		/* Check HTTP method */
		if (strncmp(buffer, "GET ", 4) && strncmp(buffer, "get ", 4))
			continue;

		/* buffer shuold look like 'GET URL HTTP/1.0' */
		/* remove everything after URL */
		for (i = 4; i < BUFSIZE; i++) {
			if (buffer[i] == ' ') {
				buffer[i] = 0;
				break;
			}
		}

		/* Show URL */
		/*printf("LEN:\n%d\n",strlen(&buffer[5])); */
		/*printf("URL:\n"); */
		printf("%s\n", &buffer[5]);
		fflush(stdout);

		/* Send http response */
		/*
		   sprintf(buffer, "HTTP/1.1 404 Not Found\r\n"
		   "Server: nginx\r\n"
		   "Content-Type: text/html\r\n\r\n"
		   "<html>\n"
		   "<head><title>404 Not Found</title></head>\n"
		   "<body bgcolor=\"white\">\n"
		   "<center><h1>404 Not Found</h1></center>\n"
		   "<hr><center>nginx</center>\n"
		   "</body>\n"
		   "</html>\n\r\n");
		 */
		sprintf(buffer, "HTTP/1.0 200 OK\r\n"
			"Content-Type: text/html\r\n\r\n"
			"<HTML><BODY>"
			"<b>It Works !!!</b>" "</BODY></HTML>\r\n");
		send(accept_fd, buffer, strlen(buffer), 0);

		/* Cleanup */
		close(accept_fd);

	}

	/* Cleanup */
	close(listen_fd);
	close(file_fd);
}