From 219b8523ce20106a93053505b5b719c4f0f86853 Mon Sep 17 00:00:00 2001 From: Nishi Date: Fri, 13 Sep 2024 17:41:07 +0000 Subject: [PATCH] module system kinda works git-svn-id: file:///raid/svn-personal/tewi/trunk@17 8739d7e6-ffea-ec47-b151-bdff447c6205 --- Makefile | 10 +++++--- Module/Makefile | 17 +++++++++++++ Module/mod_example.c | 8 ++++++ Platform/generic.mk | 1 + Platform/win64.mk | 1 + Server/Makefile | 2 +- Server/config.c | 23 ++++++++++++++++++ Server/http.c | 8 +++++- Server/module.c | 58 ++++++++++++++++++++++++++++++++++++++++++++ Server/server.c | 2 ++ Server/tw_config.h | 1 + Server/tw_http.h | 2 -- Server/tw_module.h | 19 +++++++++++++++ example.conf | 2 ++ 14 files changed, 147 insertions(+), 7 deletions(-) create mode 100644 Module/Makefile create mode 100644 Module/mod_example.c create mode 100644 Server/module.c create mode 100644 Server/tw_module.h diff --git a/Makefile b/Makefile index 34e6226..490eddb 100644 --- a/Makefile +++ b/Makefile @@ -6,19 +6,23 @@ PREFIX = /usr/local 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) + ./Common:: $(MAKE) -C $@ $(FLAGS) 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 diff --git a/Module/Makefile b/Module/Makefile new file mode 100644 index 0000000..acc6102 --- /dev/null +++ b/Module/Makefile @@ -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 diff --git a/Module/mod_example.c b/Module/mod_example.c new file mode 100644 index 0000000..d170fd0 --- /dev/null +++ b/Module/mod_example.c @@ -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; +} diff --git a/Platform/generic.mk b/Platform/generic.mk index aa21474..5e45edb 100644 --- a/Platform/generic.mk +++ b/Platform/generic.mk @@ -6,3 +6,4 @@ CFLAGS = -g -std=c99 -DPREFIX=\"$(PREFIX)\" -I $(PWD)/Common LDFLAGS = LIBS = EXEC = +LIB = .so diff --git a/Platform/win64.mk b/Platform/win64.mk index a374bf7..0871d40 100644 --- a/Platform/win64.mk +++ b/Platform/win64.mk @@ -6,3 +6,4 @@ CFLAGS = -g -std=c99 -DPREFIX=\"$(PREFIX)\" -I $(PWD)/Common -I $(PWD)/openssl/i LDFLAGS = -L $(PWD)/openssl/lib LIBS = -lws2_32 EXEC = .exe +LIB = .dll diff --git a/Server/Makefile b/Server/Makefile index 0053402..077da44 100644 --- a/Server/Makefile +++ b/Server/Makefile @@ -5,7 +5,7 @@ include $(PWD)/Platform/$(PLATFORM).mk .PHONY: all clean .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) diff --git a/Server/config.c b/Server/config.c index 1920627..df91aaa 100644 --- a/Server/config.c +++ b/Server/config.c @@ -3,6 +3,7 @@ #define SOURCE #include "tw_config.h" +#include "tw_module.h" #include #include @@ -37,6 +38,7 @@ void tw_config_init(void) { config.root.sslkey = NULL; config.root.sslcert = NULL; config.vhost_count = 0; + config.server_root = cm_strdup(PREFIX); gethostname(config.hostname, 1024); } @@ -125,6 +127,27 @@ int tw_config_read(const char* path) { if(current->sslcert != NULL) free(current->sslcert); 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) { cm_log("Config", "Unknown directive `%s' at line %d", r[0], ln); diff --git a/Server/http.c b/Server/http.c index 0462d3d..b630591 100644 --- a/Server/http.c +++ b/Server/http.c @@ -11,7 +11,13 @@ #include #include -#include +#include + +#ifdef __MINGW32__ +#include +#else +#include +#endif void tw_free_request(struct tw_http_request* req) { if(req->method != NULL) free(req->method); diff --git a/Server/module.c b/Server/module.c new file mode 100644 index 0000000..ec793ed --- /dev/null +++ b/Server/module.c @@ -0,0 +1,58 @@ +/* $Id$ */ + +#include "tw_module.h" + +#include "tw_config.h" + +#include +#include + +#include +#include + +#ifdef __MINGW32__ +#include +#else +#include +#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); + } +} diff --git a/Server/server.c b/Server/server.c index 3f4d45d..6f9cd01 100644 --- a/Server/server.c +++ b/Server/server.c @@ -160,6 +160,8 @@ void tw_server_pass(int sock, bool ssl, int port) { } struct tw_http_request req; int ret = tw_http_parse(s, sock, &req); + if(ret == 0) { + } cleanup: if(sslworks) { SSL_shutdown(s); diff --git a/Server/tw_config.h b/Server/tw_config.h index 2aa1bb5..030d06e 100644 --- a/Server/tw_config.h +++ b/Server/tw_config.h @@ -22,6 +22,7 @@ struct tw_config { struct tw_config_entry root; struct tw_config_entry vhosts[MAX_VHOSTS]; int vhost_count; + char* server_root; }; void tw_config_init(void); diff --git a/Server/tw_http.h b/Server/tw_http.h index 2818c65..79c0377 100644 --- a/Server/tw_http.h +++ b/Server/tw_http.h @@ -15,8 +15,6 @@ struct tw_http_response { char** headers; }; -struct tw_http_tool {}; - #ifdef SOURCE #include int tw_http_parse(SSL* ssl, int sock, struct tw_http_request* req); diff --git a/Server/tw_module.h b/Server/tw_module.h new file mode 100644 index 0000000..fe2a4c4 --- /dev/null +++ b/Server/tw_module.h @@ -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 diff --git a/example.conf b/example.conf index 74c4248..351fcf9 100644 --- a/example.conf +++ b/example.conf @@ -1,6 +1,8 @@ # $Id$ # This is an example config +LoadModule /home/nishi/SVN/tewi/trunk/Module/mod_example.so + Listen 8000 8001 8002 8003 8004 ListenSSL 8443 8444 8445 8446 8447