diff --git a/bbs.h b/bbs.h index 86471ac..fccaf38 100644 --- a/bbs.h +++ b/bbs.h @@ -200,8 +200,10 @@ extern void lua_push_cfunctions(lua_State *L); extern void load_strings(); extern char *get_string(int offset); +extern void chomp(char *string); #if defined(ENABLE_WWW) +extern void www_init(); extern int www_handler(void * cls, struct MHD_Connection * connection, const char * url, const char * method, const char * version, const char * upload_data, size_t * upload_data_size, void ** ptr); #endif diff --git a/main.c b/main.c index 699cc46..210f7f5 100644 --- a/main.c +++ b/main.c @@ -696,6 +696,7 @@ void server(int port) { #if defined(ENABLE_WWW) if (conf.www_server && conf.www_path != NULL) { + www_init(); www_daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, conf.www_port, NULL, NULL, &www_handler, NULL, MHD_OPTION_END); } #endif diff --git a/www.c b/www.c index c468ba7..7cd2869 100644 --- a/www.c +++ b/www.c @@ -4,10 +4,176 @@ #include #include #include +#include #include "bbs.h" extern struct bbs_config conf; +struct mime_type { + char *ext; + char *mime; +}; + +static struct mime_type **mime_types; +static int mime_types_count; + +void www_init() { + FILE *fptr; + char buffer[4096]; + int i; + + mime_types_count = 0; + + sprintf(buffer, "%s/mime.types", conf.www_path); + + fptr = fopen(buffer, "r"); + if (!fptr) { + return; + } + fgets(buffer, 4096, fptr); + while (!feof(fptr)) { + chomp(buffer); + + for (i=0;imime = strdup(buffer); + mime_types[mime_types_count]->ext = strdup(&buffer[i+1]); + + mime_types_count++; + break; + } + } + + fgets(buffer, 4096, fptr); + } + + fclose(fptr); +} + +char *www_get_mime_type(const char *extension) { + int i; + static char default_mime_type[] = "application/octet-stream"; + + + for (i=0;iext) == 0) { + return mime_types[i]->mime; + } + } + return default_mime_type; +} + +int www_404(char *header, char *footer, struct MHD_Connection * connection) { + char buffer[4096]; + char *page; + struct stat s; + char *whole_page; + struct MHD_Response *response; + int ret; + FILE *fptr; + + snprintf(buffer, 4096, "%s/404.tpl", conf.www_path); + + page = NULL; + + if (stat(buffer, &s) == 0) { + page = (char *)malloc(s.st_size + 1); + if (page == NULL) { + return -1; + } + memset(page, 0, s.st_size + 1); + fptr = fopen(buffer, "r"); + if (fptr) { + fread(page, s.st_size, 1, fptr); + fclose(fptr); + } else { + free(page); + page = NULL; + } + } + + if (page == NULL) { + page = (char *)malloc(16); + if (page == NULL) { + return -1; + } + sprintf(page, "Missing Content"); + } + + whole_page = (char *)malloc(strlen(header) + strlen(page) + strlen(footer) + 1); + + sprintf(whole_page, "%s%s%s", header, page, footer); + + response = MHD_create_response_from_buffer (strlen(whole_page), (void*)whole_page, MHD_RESPMEM_PERSISTENT); + + ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response); + MHD_destroy_response (response); + free(whole_page); + free(page); + + return 0; +} + +int www_403(char *header, char *footer, struct MHD_Connection * connection) { + char buffer[4096]; + char *page; + struct stat s; + char *whole_page; + struct MHD_Response *response; + int ret; + FILE *fptr; + + snprintf(buffer, 4096, "%s/403.tpl", conf.www_path); + + page = NULL; + + if (stat(buffer, &s) == 0) { + page = (char *)malloc(s.st_size + 1); + if (page == NULL) { + return -1; + } + memset(page, 0, s.st_size + 1); + fptr = fopen(buffer, "r"); + if (fptr) { + fread(page, s.st_size, 1, fptr); + fclose(fptr); + } else { + free(page); + page = NULL; + } + } + + if (page == NULL) { + page = (char *)malloc(16); + if (page == NULL) { + return -1; + } + sprintf(page, "Missing Content"); + } + + whole_page = (char *)malloc(strlen(header) + strlen(page) + strlen(footer) + 1); + + sprintf(whole_page, "%s%s%s", header, page, footer); + + response = MHD_create_response_from_buffer (strlen(whole_page), (void*)whole_page, MHD_RESPMEM_PERSISTENT); + + ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response); + MHD_destroy_response (response); + free(whole_page); + free(page); + + return 0; +} + int www_handler(void * cls, struct MHD_Connection * connection, const char * url, const char * method, const char * version, const char * upload_data, size_t * upload_data_size, void ** ptr) { struct MHD_Response *response; @@ -19,6 +185,9 @@ int www_handler(void * cls, struct MHD_Connection * connection, const char * url char *footer; char *whole_page; FILE *fptr; + char *mime; + int i; + int fno; snprintf(buffer, 4096, "%s/header.tpl", conf.www_path); @@ -29,6 +198,7 @@ int www_handler(void * cls, struct MHD_Connection * connection, const char * url if (header == NULL) { return MHD_NO; } + memset(header, 0, s.st_size + 1); fptr = fopen(buffer, "r"); if (fptr) { fread(header, s.st_size, 1, fptr); @@ -57,6 +227,7 @@ int www_handler(void * cls, struct MHD_Connection * connection, const char * url free(header); return MHD_NO; } + memset(footer, 0, s.st_size + 1); fptr = fopen(buffer, "r"); if (fptr) { fread(footer, s.st_size, 1, fptr); @@ -90,6 +261,7 @@ int www_handler(void * cls, struct MHD_Connection * connection, const char * url free(footer); return MHD_NO; } + memset(page, 0, s.st_size + 1); fptr = fopen(buffer, "r"); if (fptr) { fread(page, s.st_size, 1, fptr); @@ -115,12 +287,59 @@ int www_handler(void * cls, struct MHD_Connection * connection, const char * url sprintf(whole_page, "%s%s%s", header, page, footer); } else if (strncasecmp(url, "/static/", 8) == 0) { // sanatize path - + if (strstr(url, "/..") != NULL) { + return MHD_NO; + } + // get mimetype + for (i=strlen(url);i>0;--i) { + if (url[i] == '.') { + mime = www_get_mime_type(&url[i+1]); + break; + } + } // load file + + sprintf(buffer, "%s%s", conf.www_path, url); + if (stat(buffer, &s) == 0 && S_ISREG(s.st_mode)) { + fno = open(buffer, O_RDONLY); + if (fno != -1) { + response = MHD_create_response_from_fd(s.st_size, fno); + MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_TYPE, mime); + ret = MHD_queue_response (connection, MHD_HTTP_OK, response); + MHD_destroy_response (response); + free(header); + free(footer); + return MHD_YES; + } else { + if (www_403(header, footer, connection) != 0) { + free(header); + free(footer); + return MHD_NO; + } + free(header); + free(footer); + return MHD_YES; + } + } else { + if (www_404(header, footer, connection) != 0) { + free(header); + free(footer); + return MHD_NO; + } + free(header); + free(footer); + return MHD_YES; + } + } else { + if (www_404(header, footer, connection) != 0) { + free(header); + free(footer); + return MHD_NO; + } free(header); free(footer); - return MHD_NO; + return MHD_YES; } } else if (strcmp(method, "POST") == 0) { free(header); diff --git a/www/403.tpl b/www/403.tpl new file mode 100644 index 0000000..9bd457e --- /dev/null +++ b/www/403.tpl @@ -0,0 +1,2 @@ +

403 - Forbidden

+The page you are looking for can not be accessed. diff --git a/www/404.tpl b/www/404.tpl new file mode 100644 index 0000000..0c731a1 --- /dev/null +++ b/www/404.tpl @@ -0,0 +1,2 @@ +

404 - Page not found

+The page you are looking for can not be found. diff --git a/www/footer.tpl b/www/footer.tpl index e04310f..45d0706 100644 --- a/www/footer.tpl +++ b/www/footer.tpl @@ -1,2 +1,4 @@ +
+ diff --git a/www/header.tpl b/www/header.tpl index ef464c5..ec7efc2 100644 --- a/www/header.tpl +++ b/www/header.tpl @@ -1,4 +1,11 @@ + Magicka BBS + +
+ Magicka BBS +
+
+ diff --git a/www/index.tpl b/www/index.tpl index 6128ddd..0de5d06 100644 --- a/www/index.tpl +++ b/www/index.tpl @@ -1,3 +1,3 @@

Welcome to another Magicka BBS!

-The sysop should customize this file with what he wants on the front page! +The sysop should customize this file with what he/she wants on the front page! diff --git a/www/mime.types b/www/mime.types new file mode 100644 index 0000000..b46d302 --- /dev/null +++ b/www/mime.types @@ -0,0 +1 @@ +image/png png diff --git a/www/static/header.png b/www/static/header.png new file mode 100644 index 0000000..64ccadf Binary files /dev/null and b/www/static/header.png differ diff --git a/www/static/style.css b/www/static/style.css new file mode 100644 index 0000000..4dabd27 --- /dev/null +++ b/www/static/style.css @@ -0,0 +1,3 @@ +.footer { + font-size: small; +}