Index: /trunk/Module/Makefile
===================================================================
--- /trunk/Module/Makefile	(revision 17)
+++ /trunk/Module/Makefile	(revision 18)
@@ -9,5 +9,5 @@
 
 .o.so:
-	$(CC) $(LDFLAGS) -shared -o $@ $< $(LIBS)
+	$(CC) $(LDFLAGS) -shared -o $@ $< ../Common/common.a $(LIBS)
 
 .c.o:
Index: /trunk/Module/mod_example.c
===================================================================
--- /trunk/Module/mod_example.c	(revision 17)
+++ /trunk/Module/mod_example.c	(revision 18)
@@ -5,4 +5,5 @@
 int mod_init(struct tw_config* config, struct tw_tool* tools) {
 	tools->log("Example", "This is an example module");
+	tools->add_version("Example/0.0");
 	return 0;
 }
Index: /trunk/Server/config.c
===================================================================
--- /trunk/Server/config.c	(revision 17)
+++ /trunk/Server/config.c	(revision 18)
@@ -39,4 +39,6 @@
 	config.root.sslcert = NULL;
 	config.vhost_count = 0;
+	config.module_count = 0;
+	config.extension = NULL;
 	config.server_root = cm_strdup(PREFIX);
 	gethostname(config.hostname, 1024);
@@ -140,4 +142,5 @@
 							void* mod = tw_module_load(r[i]);
 							if(mod != NULL) {
+								config.modules[config.module_count++] = mod;
 								if(tw_module_init(mod) != 0) {
 									stop = 1;
Index: /trunk/Server/main.c
===================================================================
--- /trunk/Server/main.c	(revision 17)
+++ /trunk/Server/main.c	(revision 18)
@@ -17,8 +17,11 @@
 
 extern bool cm_do_log;
+extern struct tw_config config;
+
+char tw_server[2048];
 
 int main(int argc, char** argv) {
 	int i;
-	const char* config = PREFIX "/etc/tewi.conf";
+	const char* confpath = PREFIX "/etc/tewi.conf";
 	for(i = 1; i < argc; i++) {
 		if(argv[i][0] == '-') {
@@ -36,5 +39,5 @@
 					return 1;
 				}
-				config = argv[i];
+				confpath = argv[i];
 			} else {
 				fprintf(stderr, "Unknown option: %s\n", argv[i]);
@@ -44,5 +47,5 @@
 	}
 	tw_config_init();
-	if(tw_config_read(config) != 0) {
+	if(tw_config_read(confpath) != 0) {
 		fprintf(stderr, "Could not read the config\n");
 		return 1;
@@ -52,4 +55,5 @@
 		return 1;
 	}
+	sprintf(tw_server, "Tewi/%s (%s)%s", tw_get_version(), tw_get_platform(), config.extension == NULL ? "" : config.extension);
 	cm_log("Daemon", "Ready");
 #ifndef __MINGW32__
Index: /trunk/Server/module.c
===================================================================
--- /trunk/Server/module.c	(revision 17)
+++ /trunk/Server/module.c	(revision 18)
@@ -1,3 +1,5 @@
 /* $Id$ */
+
+#define SOURCE
 
 #include "tw_module.h"
@@ -44,5 +46,18 @@
 }
 
-void tw_init_tools(struct tw_tool* tools) { tools->log = cm_log; }
+void tw_add_version(const char* string) {
+	if(config.extension == NULL) {
+		config.extension = cm_strcat(" ", string);
+	} else {
+		char* tmp = config.extension;
+		config.extension = cm_strcat3(tmp, " ", string);
+		free(tmp);
+	}
+}
+
+void tw_init_tools(struct tw_tool* tools) {
+	tools->log = cm_log;
+	tools->add_version = tw_add_version;
+}
 
 int tw_module_init(void* mod) {
Index: /trunk/Server/server.c
===================================================================
--- /trunk/Server/server.c	(revision 17)
+++ /trunk/Server/server.c	(revision 18)
@@ -8,4 +8,6 @@
 #include "tw_config.h"
 #include "tw_http.h"
+#include "tw_module.h"
+#include "tw_version.h"
 
 #include <unistd.h>
@@ -13,4 +15,5 @@
 #include <stdbool.h>
 
+#include <cm_string.h>
 #include <cm_log.h>
 
@@ -28,4 +31,5 @@
 
 extern struct tw_config config;
+extern char tw_server[];
 
 fd_set fdset;
@@ -130,4 +134,113 @@
 		return SSL_write(ssl, data, len);
 	}
+}
+
+#define ERROR_400 \
+	"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n" \
+	"<html>\n" \
+	"	<head>\n" \
+	"		<title>400 Bad Request</title>" \
+	"	</head>\n" \
+	"	<body>\n" \
+	"		<h1>Bad Request</h1>\n" \
+	"		<hr>\n" \
+	"		", \
+	    address, \
+	    "\n" \
+	    "	</body>\n" \
+	    "</html>\n"
+
+#define ERROR_401 \
+	"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n" \
+	"<html>\n" \
+	"	<head>\n" \
+	"		<title>401 Unauthorized</title>" \
+	"	</head>\n" \
+	"	<body>\n" \
+	"		<h1>Unauthorized</h1>\n" \
+	"		<hr>\n" \
+	"		", \
+	    address, \
+	    "\n" \
+	    "	</body>\n" \
+	    "</html>\n"
+
+#define ERROR_403 \
+	"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n" \
+	"<html>\n" \
+	"	<head>\n" \
+	"		<title>403 Forbidden</title>" \
+	"	</head>\n" \
+	"	<body>\n" \
+	"		<h1>Forbidden</h1>\n" \
+	"		<hr>\n" \
+	"		", \
+	    address, \
+	    "\n" \
+	    "	</body>\n" \
+	    "</html>\n"
+
+#define ERROR_404 \
+	"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n" \
+	"<html>\n" \
+	"	<head>\n" \
+	"		<title>404 Not Found</title>" \
+	"	</head>\n" \
+	"	<body>\n" \
+	"		<h1>Not Found</h1>\n" \
+	"		<hr>\n" \
+	"		", \
+	    address, \
+	    "\n" \
+	    "	</body>\n" \
+	    "</html>\n"
+
+void tw_process_page(SSL* ssl, int sock, const char* status, const char* type, const unsigned char* doc, size_t size) {
+	char construct[512];
+	sprintf(construct, "%llu", (unsigned long long)size);
+	tw_write(ssl, sock, "HTTP/1.1 ", 9);
+	tw_write(ssl, sock, (char*)status, strlen(status));
+	tw_write(ssl, sock, "\r\n", 2);
+	tw_write(ssl, sock, "Content-Type: ", 7 + 5 + 2);
+	tw_write(ssl, sock, (char*)type, strlen(type));
+	tw_write(ssl, sock, "\r\n", 2);
+	tw_write(ssl, sock, "Server: ", 6 + 2);
+	tw_write(ssl, sock, tw_server, strlen(tw_server));
+	tw_write(ssl, sock, "\r\n", 2);
+	tw_write(ssl, sock, "Content-Length: ", 7 + 7 + 2);
+	tw_write(ssl, sock, construct, strlen(construct));
+	tw_write(ssl, sock, "\r\n", 2);
+	tw_write(ssl, sock, "\r\n", 2);
+	size_t incr = 0;
+	while(1) {
+		tw_write(ssl, sock, (unsigned char*)doc + incr, size < 128 ? size : 128);
+		incr += 128;
+		size -= 128;
+		if(size <= 0) break;
+	}
+}
+
+const char* tw_http_status(int code) {
+	if(code == 400) {
+		return "400 Bad Request";
+	} else {
+		return "400 Bad Request";
+	}
+}
+
+char* tw_http_default_error(int code, char* name, int port) {
+	char address[1024];
+	sprintf(address, "<address>%s Server at %s Port %d</address>", tw_server, name, port);
+	if(code == 400) {
+		return cm_strcat3(ERROR_400);
+	} else {
+		return cm_strcat3(ERROR_400);
+	}
+}
+
+void tw_http_error(SSL* ssl, int sock, int error, char* name, int port) {
+	char* str = tw_http_default_error(error, name, port);
+	tw_process_page(ssl, sock, tw_http_status(error), "text/html", str, strlen(str));
+	free(str);
 }
 
@@ -162,4 +275,6 @@
 	int ret = tw_http_parse(s, sock, &req);
 	if(ret == 0) {
+	} else {
+		tw_http_error(s, sock, 400, name, port);
 	}
 cleanup:
Index: /trunk/Server/tw_config.h
===================================================================
--- /trunk/Server/tw_config.h	(revision 17)
+++ /trunk/Server/tw_config.h	(revision 18)
@@ -7,6 +7,6 @@
 
 #define MAX_PORTS 1024
-
 #define MAX_VHOSTS 1024
+#define MAX_MODULES 1024
 
 struct tw_config_entry {
@@ -22,6 +22,9 @@
 	struct tw_config_entry root;
 	struct tw_config_entry vhosts[MAX_VHOSTS];
+	void* modules[MAX_MODULES];
+	int module_count;
 	int vhost_count;
 	char* server_root;
+	char* extension;
 };
 
Index: /trunk/Server/tw_module.h
===================================================================
--- /trunk/Server/tw_module.h	(revision 17)
+++ /trunk/Server/tw_module.h	(revision 18)
@@ -5,10 +5,19 @@
 
 #include "tw_config.h"
+#include "tw_http.h"
 
 struct tw_tool {
 	void (*log)(const char* name, const char* log, ...);
+	void (*add_version)(const char* string);
+};
+
+enum TW_MODULE_RETURN {
+	TW_MODULE_PASS = 0, /* Pass to the next module. */
+	TW_MODULE_STOP,	    /* Do not pass to the next module. */
+	TW_MODULE_ERROR	    /* Error, and do not pass to the next module. */
 };
 
 typedef int (*tw_mod_init_t)(struct tw_config* config, struct tw_tool* tools);
+typedef int (*tw_mod_request_t)(struct tw_tool* tools, struct tw_http_request* req, struct tw_http_response* res);
 
 void* tw_module_load(const char* path);
Index: /trunk/Server/tw_version.h
===================================================================
--- /trunk/Server/tw_version.h	(revision 17)
+++ /trunk/Server/tw_version.h	(revision 18)
@@ -5,4 +5,5 @@
 
 const char* tw_get_version(void);
+const char* tw_get_platform(void);
 
 #endif
Index: /trunk/Server/version.c
===================================================================
--- /trunk/Server/version.c	(revision 17)
+++ /trunk/Server/version.c	(revision 18)
@@ -7,3 +7,16 @@
 const char* tw_version = "0.00";
 
+const char* tw_platform =
+#if defined(PLATFORM)
+    PLATFORM
+#elif defined(__NetBSD__)
+    "NetBSD"
+#elif defined(__MINGW32__)
+    "Windows"
+#else
+    "Unix"
+#endif
+    ;
+
 const char* tw_get_version(void) { return tw_version; }
+const char* tw_get_platform(void) { return tw_platform; }
