Index: /trunk/Makefile
===================================================================
--- /trunk/Makefile	(revision 16)
+++ /trunk/Makefile	(revision 17)
@@ -7,9 +7,12 @@
 FLAGS = PWD=$(PWD) PLATFORM=$(PLATFORM) PREFIX=$(PREFIX)
 
-.PHONY: all format clean ./Server ./Common
+.PHONY: all format clean ./Server ./Common ./Module
 
-all: ./Server
+all: ./Server ./Module
 
 ./Server:: ./Common
+	$(MAKE) -C $@ $(FLAGS)
+
+./Module:: ./Common
 	$(MAKE) -C $@ $(FLAGS)
 
@@ -18,7 +21,8 @@
 
 format:
-	clang-format --verbose -i `find ./Server ./Common -name "*.c" -or -name "*.h"`
+	clang-format --verbose -i `find ./Server ./Common ./Module -name "*.c" -or -name "*.h"`
 
 clean:
 	$(MAKE) -C ./Server $(FLAGS) clean
+	$(MAKE) -C ./Module $(FLAGS) clean
 	$(MAKE) -C ./Common $(FLAGS) clean
Index: /trunk/Module/Makefile
===================================================================
--- /trunk/Module/Makefile	(revision 17)
+++ /trunk/Module/Makefile	(revision 17)
@@ -0,0 +1,17 @@
+# $Id$
+
+include $(PWD)/Platform/$(PLATFORM).mk
+
+.PHONY: all clean
+.SUFFIXES: .c .o .so
+
+all: mod_example.so
+
+.o.so:
+	$(CC) $(LDFLAGS) -shared -o $@ $< $(LIBS)
+
+.c.o:
+	$(CC) $(CFLAGS) -fPIC -c -o $@ $<
+
+clean:
+	rm -f *.o *.so *.a
Index: /trunk/Module/mod_example.c
===================================================================
--- /trunk/Module/mod_example.c	(revision 17)
+++ /trunk/Module/mod_example.c	(revision 17)
@@ -0,0 +1,8 @@
+/* $Id$ */
+
+#include "../Server/tw_module.h"
+
+int mod_init(struct tw_config* config, struct tw_tool* tools) {
+	tools->log("Example", "This is an example module");
+	return 0;
+}
Index: /trunk/Platform/generic.mk
===================================================================
--- /trunk/Platform/generic.mk	(revision 16)
+++ /trunk/Platform/generic.mk	(revision 17)
@@ -7,2 +7,3 @@
 LIBS =
 EXEC =
+LIB = .so
Index: /trunk/Platform/win64.mk
===================================================================
--- /trunk/Platform/win64.mk	(revision 16)
+++ /trunk/Platform/win64.mk	(revision 17)
@@ -7,2 +7,3 @@
 LIBS = -lws2_32
 EXEC = .exe
+LIB = .dll
Index: /trunk/Server/Makefile
===================================================================
--- /trunk/Server/Makefile	(revision 16)
+++ /trunk/Server/Makefile	(revision 17)
@@ -6,5 +6,5 @@
 .SUFFIXES: .c .o
 
-OBJS = version.o main.o config.o server.o ssl.o http.o
+OBJS = version.o main.o config.o server.o ssl.o http.o module.o
 
 all: tewi$(EXEC)
Index: /trunk/Server/config.c
===================================================================
--- /trunk/Server/config.c	(revision 16)
+++ /trunk/Server/config.c	(revision 17)
@@ -4,4 +4,5 @@
 
 #include "tw_config.h"
+#include "tw_module.h"
 
 #include <stdio.h>
@@ -38,4 +39,5 @@
 	config.root.sslcert = NULL;
 	config.vhost_count = 0;
+	config.server_root = cm_strdup(PREFIX);
 	gethostname(config.hostname, 1024);
 }
@@ -126,4 +128,25 @@
 							current->sslcert = cm_strdup(r[1]);
 						}
+					} else if(cm_strcaseequ(r[0], "ServerRoot")) {
+						if(r[1] == NULL) {
+							cm_log("Config", "Missing path at line %d", ln);
+							stop = 1;
+						} else {
+							if(config.server_root != NULL) free(config.server_root);
+							config.server_root = cm_strdup(r[1]);
+						}
+					} else if(cm_strcaseequ(r[0], "LoadModule")) {
+						for(i = 1; r[i] != NULL; i++) {
+							void* mod = tw_module_load(r[i]);
+							if(mod != NULL) {
+								if(tw_module_init(mod) != 0) {
+									stop = 1;
+									break;
+								}
+							} else {
+								stop = 1;
+								break;
+							}
+						}
 					} else {
 						if(r[0] != NULL) {
Index: /trunk/Server/http.c
===================================================================
--- /trunk/Server/http.c	(revision 16)
+++ /trunk/Server/http.c	(revision 17)
@@ -12,5 +12,11 @@
 #include <stdbool.h>
 #include <stdlib.h>
-#include <sys/socket.h>
+#include <string.h>
+
+#ifdef __MINGW32__
+#include <winsock2.h>
+#else
+#include <sys/select.h>
+#endif
 
 void tw_free_request(struct tw_http_request* req) {
Index: /trunk/Server/module.c
===================================================================
--- /trunk/Server/module.c	(revision 17)
+++ /trunk/Server/module.c	(revision 17)
@@ -0,0 +1,58 @@
+/* $Id$ */
+
+#include "tw_module.h"
+
+#include "tw_config.h"
+
+#include <cm_string.h>
+#include <cm_log.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+
+#ifdef __MINGW32__
+#include <windows.h>
+#else
+#include <dlfcn.h>
+#endif
+
+extern struct tw_config config;
+
+void* tw_module_load(const char* path) {
+	char* p = getcwd(NULL, 0);
+	chdir(config.server_root);
+	void* lib;
+#ifdef __MINGW32__
+	lib = LoadLibraryA(path);
+#else
+	lib = dlopen(path, DL_LAZY);
+#endif
+	if(lib == NULL) {
+		cm_log("Module", "Could not load %s", path);
+	}
+	chdir(p);
+	free(p);
+	return lib;
+}
+
+void* tw_module_symbol(void* mod, const char* sym) {
+#ifdef __MINGW32__
+	return GetProcAddress(mod, sym);
+#else
+	return dlsym(mod, sym);
+#endif
+}
+
+void tw_init_tools(struct tw_tool* tools) { tools->log = cm_log; }
+
+int tw_module_init(void* mod) {
+	tw_mod_init_t mod_init = (tw_mod_init_t)tw_module_symbol(mod, "mod_init");
+	if(mod_init == NULL) {
+		cm_log("Module", "Could not init a module");
+		return 1;
+	} else {
+		struct tw_tool tools;
+		tw_init_tools(&tools);
+		return mod_init(&config, &tools);
+	}
+}
Index: /trunk/Server/server.c
===================================================================
--- /trunk/Server/server.c	(revision 16)
+++ /trunk/Server/server.c	(revision 17)
@@ -161,4 +161,6 @@
 	struct tw_http_request req;
 	int ret = tw_http_parse(s, sock, &req);
+	if(ret == 0) {
+	}
 cleanup:
 	if(sslworks) {
Index: /trunk/Server/tw_config.h
===================================================================
--- /trunk/Server/tw_config.h	(revision 16)
+++ /trunk/Server/tw_config.h	(revision 17)
@@ -23,4 +23,5 @@
 	struct tw_config_entry vhosts[MAX_VHOSTS];
 	int vhost_count;
+	char* server_root;
 };
 
Index: /trunk/Server/tw_http.h
===================================================================
--- /trunk/Server/tw_http.h	(revision 16)
+++ /trunk/Server/tw_http.h	(revision 17)
@@ -16,6 +16,4 @@
 };
 
-struct tw_http_tool {};
-
 #ifdef SOURCE
 #include <openssl/ssl.h>
Index: /trunk/Server/tw_module.h
===================================================================
--- /trunk/Server/tw_module.h	(revision 17)
+++ /trunk/Server/tw_module.h	(revision 17)
@@ -0,0 +1,19 @@
+/* $Id$ */
+
+#ifndef __TW_MODULE_H__
+#define __TW_MODULE_H__
+
+#include "tw_config.h"
+
+struct tw_tool {
+	void (*log)(const char* name, const char* log, ...);
+};
+
+typedef int (*tw_mod_init_t)(struct tw_config* config, struct tw_tool* tools);
+
+void* tw_module_load(const char* path);
+void* tw_module_symbol(void* mod, const char* sym);
+void tw_init_tools(struct tw_tool* tools);
+int tw_module_init(void* mod);
+
+#endif
Index: /trunk/example.conf
===================================================================
--- /trunk/example.conf	(revision 16)
+++ /trunk/example.conf	(revision 17)
@@ -1,4 +1,6 @@
 # $Id$
 # This is an example config
+
+LoadModule /home/nishi/SVN/tewi/trunk/Module/mod_example.so
 
 Listen 8000 8001 8002 8003 8004
