Code:
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdbool.h>
#define PORT 1337
#define BACKLOG 10
/* Structure declarations */
struct Ssocket
{
int fd; /* File descriptor */
char *buffer;
int buffer_length;
struct Ssocket *next;
struct Ssocket *prev;
};
/* Function delarations */
int main(int argc, char *argv[]);
int init();
void get_input();
struct Ssocket* add_socket(int fd);
void remove_socket(struct Ssocket *socket);
int update_buffer(struct Ssocket *socket, char *buffer, int nbytes);
char* find_html_command(struct Ssocket *socket);
/* Global variables */
int sin_size;
int fdmax; /* The largest file descriptor number being used */
struct sockaddr_in my_address; /* Server address */
struct sockaddr_in their_address; /* Client address */
int listener_fd; /* Listening */
fd_set master_fd_set; /* Master file descriptor list */
fd_set read_fd_set; /* Temp list for select() */
struct Ssocket *first_socket; /* Pointer to first socket in the linked list */
int main(int argc, char *argv[])
{
bool running = false;
int i;
char *html_command;
struct Ssocket *current_socket;
/* Initialize stuff */
if (init() == -1)
{
printf("Failed to init.\n");
exit(1);
}
else
running = true;
/* Listen for connections */
if (listen(listener_fd, BACKLOG) == -1)
{
printf("Problem listening for connections\n");
exit(1);
}
FD_SET(listener_fd, &master_fd_set); /* Add the new socket to the set */
fdmax = listener_fd; /* set the biggest fd as the current one */
while (running == true)
{
/* Check the socket set for input */
get_input();
/* Check the socket's buffers for whole commands */
current_socket = first_socket;
while (current_socket != NULL)
{
while ((html_command = find_html_command(current_socket)) != NULL)
{
printf("q%s\n",html_command);
free(html_command);
}
current_socket = current_socket->next;
}
}
/* Tidy up before we go */
/* close(new_fd); */
for (i = 0; i <= fdmax; i++)
close(i);
FD_ZERO(&master_fd_set);
FD_ZERO(&read_fd_set);
close(listener_fd);
}
int init()
{
/* Start the socket file descriptor */
if ((listener_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
printf("Couldn't open the socket!\n");
return(-1);
}
/* Assign the stuff */
my_address.sin_family = AF_INET;
my_address.sin_port = htons(PORT); /* Set the port to the one defined */
my_address.sin_addr.s_addr = htonl(INADDR_ANY); /* Set the sockets IP to local */
memset(&(my_address.sin_zero), '\0', 8); /* Zero the rest */
/* Bind the socket to the port */
if (bind(listener_fd, (struct sockaddr *)&my_address, sizeof(struct sockaddr)) == -1)
{
printf("Couldn't bind the socket's port!\n");
return(-1);
}
/* Figure this out to save complication later */
sin_size = sizeof(struct sockaddr_in);
/* Zero the socket sets */
FD_ZERO(&master_fd_set); /* Clear the */
FD_ZERO(&read_fd_set); /* sets */
return 0;
}
void get_input()
{
char buffer[100];
int i, addrlen, nbytes, new_fd;
struct Ssocket *current_socket;
struct Ssocket *new_socket;
struct Ssocket *socket;
read_fd_set = master_fd_set; /* Copy it */
if (select(fdmax + 1, &read_fd_set, NULL, NULL, NULL) == -1)
{
printf("Problem with the socket set select watsit\n");
exit(1);
}
for (i = 0; i <= fdmax; i++)
if (FD_ISSET(i, &read_fd_set)) /* loop through each socket */
if (i == listener_fd) /* Its a new connection */
{
addrlen = sizeof(their_address);
if ((new_fd = accept(listener_fd, (struct sockaddr *)&their_address, &addrlen)) == -1)
{
printf("Problem accepting the connection");
exit(1);
}
else
{
/* Add the socket */
if ((new_socket = add_socket(new_fd)) == NULL)
exit(1);
else
printf("New connecton (%d) from %s\n", new_fd, inet_ntoa(their_address.sin_addr));
}
}
else /* Its data from an already connected client */
{
nbytes = recv(i, buffer, sizeof(buffer), 0);
/* Get the pointer of the socket structure */
current_socket = first_socket;
while (current_socket != NULL)
{
if (current_socket->fd == i)
{
socket = current_socket;
break;
}
current_socket = current_socket->next;
}
switch (nbytes)
{
case 0: /* Client quit*/
remove_socket(socket);
printf("Socket quit (%d)\n", i);
break;
case -1: /* Error recieving */
remove_socket(socket);
printf("Error recieving so kicking (%d)\n", i);
break;
default: /* Incoming stuff */
/* Add the incoming stuff to the sockets buffer */
if (update_buffer(socket, buffer, nbytes) == -1)
exit(1);
break;
}
}
}
struct Ssocket* add_socket(int fd)
{
struct Ssocket *new_socket;
/* Sort out the actual socket */
FD_SET(fd, &master_fd_set);
if (fd > fdmax)
fdmax = fd; /* Keep the max the max */
/* Allocate memory */
if ((new_socket = malloc(sizeof(struct Ssocket))) == NULL)
{
printf("Could not allocate memory for new socket structure\n");
return NULL;
}
/* Assign the data */
new_socket->fd = fd;
new_socket->buffer = NULL;
new_socket->buffer_length = 0;
/* Sort out the linked list pointers */
new_socket->next = first_socket;
new_socket->prev = NULL;
if (first_socket != NULL)
first_socket->prev = new_socket;
first_socket = new_socket;
return new_socket;
}
void remove_socket(struct Ssocket *socket)
{
/* Close the socket and remove it from the set */
close(socket->fd);
FD_CLR(socket->fd, &master_fd_set);
/* Sort out the linked list pointers */
if (socket->next != NULL)
socket->next->prev = socket->prev;
if (socket->prev != NULL)
socket->prev->next = socket->next;
if (socket == first_socket)
first_socket = first_socket->next;
/* Free up the stuff */
if (socket->buffer != NULL)
free(socket->buffer);
free(socket);
}
int update_buffer(struct Ssocket *socket, char *buffer, int nbytes)
{
int i;
char *temp;
/* Allocate space in the sockets buffer */
if (socket->buffer_length <= 0)
{
if ((socket->buffer = malloc(nbytes+1)) == NULL)
{
printf("Error allocating space for socket's buffer\n");
return(-1);
}
else
{
if ((realloc(socket->buffer, socket->buffer_length + nbytes + 1)) == NULL)
{
printf("Error reallocating the sockets buffer\n");
return(-1);
}
else
socket->buffer = temp;
}
}
/* Put the recieved guff in the sockets buffer */
for (i = socket->buffer_length; i < socket->buffer_length + nbytes; i++)
socket->buffer[i] = buffer[i - socket->buffer_length];
socket->buffer[i + 1] = '\0';
socket->buffer_length += nbytes;
return 0;
}
char* find_html_command(struct Ssocket *socket)
{
char *html_command, *temp;
int i, html_command_size;
html_command_size = -1;
/* Find the first new line */
for (i = 0; i < socket->buffer_length; i++)
{
if (socket->buffer[i] == '\n' || socket->buffer[i] == '\r')
{
html_command_size = i;
break;
}
}
/* If no new lines found return NULL, otherwise deal with it */
if (html_command_size == -1)
return NULL;
/* Get the html command buffer the right size */
if ((html_command = malloc(html_command_size + 1)) == NULL)
return NULL;
/* Copy the stuff into the html command bufer */
for (i = 0; i < html_command_size; i++)
{
printf(".%c\n", socket->buffer[i]);
html_command[i] = socket->buffer[i];
}
html_command[i + 1] = '\0';
printf(",%s,/n", html_command);
/* Remove the dealt with stuff from the sockets buffer */
socket->buffer_length -= (html_command_size + 2); /* + 2 to get rid of the '\n' and stuff */
if (socket->buffer_length <= 0)
{
free(socket->buffer);
socket->buffer = NULL;
}
else
{
for (i = 0; i < socket->buffer_length; i++)
socket->buffer[i] = socket->buffer[i+html_command_size];
socket->buffer[i+1] = '\0';
if ((realloc(socket->buffer, socket->buffer_length)) == NULL)
{
printf("Error reallocating the sockets buffer\n");
exit(1);
}
else
socket->buffer = temp;
}
return html_command;
}