Skip to content

Commit

Permalink
new skeletonized
Browse files Browse the repository at this point in the history
  • Loading branch information
Beej Jorgensen committed Sep 28, 2018
1 parent 8fab31e commit fa9fc69
Show file tree
Hide file tree
Showing 15 changed files with 1,129 additions and 257 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
.vscode
*.dSYM
src/server
src/data.txt
src/data.txt
*.o
32 changes: 30 additions & 2 deletions src/Makefile
Original file line number Diff line number Diff line change
@@ -1,2 +1,30 @@
server: server.c
gcc -Wall -Wextra -g -o $@ $^
OBJS=server.o net.o file.o mime.o cache.o hashtable.o llist.o

server: $(OBJS)
gcc -Wall -Wextra -o $@ $^

net.o: net.c net.h
gcc -Wall -Wextra -c $<

server.o: server.c net.h
gcc -Wall -Wextra -c $<

file.o: file.c file.h
gcc -Wall -Wextra -c $<

mime.o: mime.c mime.h
gcc -Wall -Wextra -c $<

cache.o: cache.c cache.h
gcc -Wall -Wextra -c $<

hashtable.o: hashtable.c hashtable.h
gcc -Wall -Wextra -c $<

llist.o: llist.c llist.h
gcc -Wall -Wextra -c $<

.PHONY: clean

clean:
rm -f $(OBJS)
121 changes: 121 additions & 0 deletions src/cache.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "hashtable.h"
#include "cache.h"

/**
* Allocate a cache entry
*/
struct cache_entry *alloc_entry(char *path, char *content_type, void *content, int content_length)
{
///////////////////
// IMPLEMENT ME! //
///////////////////
}

/**
* Deallocate a cache entry
*/
void free_entry(void *v_ent, void *varg)
{
///////////////////
// IMPLEMENT ME! //
///////////////////
}

/**
* Insert a cache entry at the head of the linked list
*/
void dllist_insert_head(struct cache *cache, struct cache_entry *ce)
{
// Insert at the head of the list
if (cache->head == NULL) {
cache->head = cache->tail = ce;
ce->prev = ce->next = NULL;
} else {
cache->head->prev = ce;
ce->next = cache->head;
ce->prev = NULL;
cache->head = ce;
}
}

/**
* Move a cache entry to the head of the list
*/
void dllist_move_to_head(struct cache *cache, struct cache_entry *ce)
{
if (ce != cache->head) {
if (ce == cache->tail) {
// We're the tail
cache->tail = ce->prev;
cache->tail->next = NULL;

} else {
// We're neither the head nor the tail
ce->prev->next = ce->next;
ce->next->prev = ce->prev;
}

ce->next = cache->head;
cache->head->prev = ce;
ce->prev = NULL;
cache->head = ce;
}
}


/**
* Removes the tail from the list and returns it
*
* NOTE: does not deallocate the tail
*/
struct cache_entry *dllist_remove_tail(struct cache *cache)
{
struct cache_entry *oldtail = cache->tail;

cache->tail = oldtail->prev;
cache->tail->next = NULL;

cache->cur_size--;

return oldtail;
}

/**
* Create a new cache
*
* max_size: maximum number of entries in the cache
* hashsize: hashtable size (0 for default)
*/
struct cache *cache_create(int max_size, int hashsize)
{
///////////////////
// IMPLEMENT ME! //
///////////////////
}

/**
* Store an entry in the cache
*
* This will also remove the least-recently-used items as necessary.
*
* NOTE: doesn't check for duplicate cache entries
*/
void cache_put(struct cache *cache, char *path, char *content_type, void *content, int content_length)
{
///////////////////
// IMPLEMENT ME! //
///////////////////
}

/**
* Retrieve an entry from the cache
*/
struct cache_entry *cache_get(struct cache *cache, char *path)
{
///////////////////
// IMPLEMENT ME! //
///////////////////
}
25 changes: 25 additions & 0 deletions src/cache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef _WEBCACHE_H_
#define _WEBCACHE_H_

// Individual hash table entry
struct cache_entry {
///////////////////
// IMPLEMENT ME! //
///////////////////

struct cache_entry *prev, *next; // Doubly-linked list
};

// A cache
struct cache {
struct hashtable *index;
struct cache_entry *head, *tail; // Doubly-linked list
int max_size; // Maxiumum number of entries
int cur_size; // Current number of entries
};

extern struct cache *cache_create(int max_size, int hashsize);
extern void cache_put(struct cache *cache, char *path, char *content_type, void *content, int content_length);
extern struct cache_entry *cache_get(struct cache *cache, char *path);

#endif
75 changes: 75 additions & 0 deletions src/file.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include "file.h"

/**
* Loads a file into memory and returns a pointer to the data.
*
* Buffer is not NUL-terminated.
*/
struct file_data *file_load(char *filename)
{
char *buffer, *p;
struct stat buf;
int bytes_read, bytes_remaining, total_bytes = 0;

// Get the file size
if (stat(filename, &buf) == -1) {
return NULL;
}

// Make sure it's a regular file
if (!(buf.st_mode & S_IFREG)) {
return NULL;
}

// Open the file for reading
FILE *fp = fopen(filename, "rb");

if (fp == NULL) {
return NULL;
}

// Allocate that many bytes
bytes_remaining = buf.st_size;
p = buffer = malloc(bytes_remaining);

if (buffer == NULL) {
return NULL;
}

// Read in the entire file
while (bytes_read = fread(p, 1, bytes_remaining, fp), bytes_read != 0 && bytes_remaining > 0) {
if (bytes_read == -1) {
free(buffer);
return NULL;
}

bytes_remaining -= bytes_read;
p += bytes_read;
total_bytes += bytes_read;
}

// Allocate the file data struct
struct file_data *filedata = malloc(sizeof *filedata);

if (filedata == NULL) {
free(buffer);
return NULL;
}

filedata->data = buffer;
filedata->size = total_bytes;

return filedata;
}

/**
* Frees memory allocated by file_load().
*/
void file_free(struct file_data *filedata)
{
free(filedata->data);
free(filedata);
}
12 changes: 12 additions & 0 deletions src/file.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef _FILE_H_
#define _FILE_H_

struct file_data {
int size;
void *data;
};

extern struct file_data *file_load(char *filename);
extern void file_free(struct file_data *filedata);

#endif
Loading

0 comments on commit fa9fc69

Please sign in to comment.