From ed2b3a38ec05c566c645dc2aabfd513edff8d63b Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Sun, 25 Dec 2016 22:55:21 +0100 Subject: Plugins --- .gitignore | 1 + Makefile | 8 ++++- main.c | 76 +++++++++++++++++++++++++++++++++++++++------ plugin.h | 18 +++++++++++ plugins/Makefile | 39 +++++++++++++++++++++++ plugins/echoback/echoback.c | 25 +++++++++++++++ util.c | 4 +-- util.h | 4 +-- 8 files changed, 160 insertions(+), 15 deletions(-) create mode 100644 plugin.h create mode 100644 plugins/Makefile create mode 100644 plugins/echoback/echoback.c diff --git a/.gitignore b/.gitignore index 7304726..ffa1d4b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ cserver *.o *.dSYM +*.dylib diff --git a/Makefile b/Makefile index 1583287..078b0a0 100644 --- a/Makefile +++ b/Makefile @@ -7,12 +7,18 @@ else endif BIN = cserver +PLUGINDIR = plugins + +PLUGINS = $(patsubst $(PLUGINDIR)/%,%,$(shell find $(PLUGINDIR)/ -maxdepth 1 -type d)) + .PHONY: all clean remake all: $(BIN) + for pl in $(PLUGINS); do make -C $(PLUGINDIR) $@ PLUGINNAME=$$pl; done clean: rm -rf $(BIN) *.o *.dSYM + for pl in $(PLUGINS); do make -C $(PLUGINDIR) $@ PLUGINNAME=$$pl; done remake: clean all @@ -20,5 +26,5 @@ remake: clean all $(BIN): $(patsubst %.c,%.o,$(wildcard *.c)) $(CC) -o $@ $^ -%.o: %.cpp $(wildcard *.h) +%.o: %.c $(wildcard $(dir %.o)*.h) $(CC) $(CFLAGS) -c -o $@ $< diff --git a/main.c b/main.c index 60b9584..52d10bd 100644 --- a/main.c +++ b/main.c @@ -7,9 +7,11 @@ #include #include #include +#include #include #include "http.h" #include "memory.h" +#include "plugin.h" #include "util.h" @@ -37,27 +39,81 @@ static void signal_handler(int sig){ } +typedef struct Plugin{ + char *name; + Handler handler; + struct Plugin *next; +} Plugin; + +Plugin *pluginlist=NULL,*pluginlist_last=NULL; + +static void plugin_register_callback(const char *name,Handler handler){ + if(pluginlist==NULL){ + pluginlist=pluginlist_last=malloc(1,Plugin); + pluginlist->name=copy_str(name); + pluginlist->handler=handler; + pluginlist->next=NULL; + } else { + Plugin *newplugin=malloc(1,Plugin); + newplugin->name=copy_str(name); + newplugin->handler=handler; + newplugin->next=NULL; + pluginlist_last->next=newplugin; + pluginlist_last=newplugin; + } + printf("Registered plugin '%s' (handler %p)\n",name,handler); +} + +typedef void (*register_function)(register_callback_t callback); + +static void load_plugin(const char *name){ + void *lib=dlopen(name,RTLD_NOW|RTLD_LOCAL); + if(lib==NULL){ + fprintf(stderr,"dlopen(%s): %s\n",name,dlerror()); + exit(1); + } + register_function regfunc=(register_function)dlsym(lib,"plugin_register_yourself"); + if(regfunc==NULL){ + fprintf(stderr,"Cannot find plugin_register_yourself symbol in library '%s'\n",name); + exit(1); + } + regfunc(&plugin_register_callback); +} + + static void connection_handler(int sock){ Headers *headers=http_get_headers(sock); if(headers==NULL){ return; } - sendall(sock,"HTTP/1.1 200 OK\r\n" - "Content-Type: text/plain; charset=UTF-8\r\n" - "Server: cserver\r\n" - "\r\n",-1); + for(Plugin *pl=pluginlist;pl!=NULL;pl=pl->next){ + switch(pl->handler(sock,headers)){ + case HR_HANDLED: + printf("Request handled by %s\n",pl->name); + break; + + case HR_NEXT: + continue; - sendallf(sock,"Method: %s\n",headers->method); - sendallf(sock,"URL: %s\n",headers->url); - sendallf(sock,"Version: %s\n",headers->version); - for(int i=0;inheaders;i++){ - sendallf(sock,"Header '%s': '%s'\n",headers->headers[i][0],headers->headers[i][1]); + case HR_ERROR: + printf("Request handler '%s' threw error\n",pl->name); + break; + } + break; } } -int main(void){ +int main(int argc,char **argv){ + if(argc==1){ + printf("Loading no plugin files\n"); + } else { + for(int i=1;i +#include "plugin.h" +#include "util.h" + + +static Handler_ret_t connection_handler(int sock,Headers *headers){ + sendall(sock,"HTTP/1.1 200 OK\r\n" + "Content-Type: text/plain; charset=UTF-8\r\n" + "Server: cserver\r\n" + "\r\n",-1); + + sendallf(sock,"Method: %s\n",headers->method); + sendallf(sock,"URL: %s\n",headers->url); + sendallf(sock,"Version: %s\n",headers->version); + sendall(sock,"\n",1); + for(int i=0;inheaders;i++){ + sendallf(sock,"Header '%s': '%s'\n",headers->headers[i][0],headers->headers[i][1]); + } + + return HR_HANDLED; +} + +void plugin_register_yourself(register_callback_t callback){ + callback("echoback",&connection_handler); +} diff --git a/util.c b/util.c index 9d9c5d3..5116347 100644 --- a/util.c +++ b/util.c @@ -10,14 +10,14 @@ #include "util.h" -char* copy_buf(char *buf,int len){ +char* copy_buf(const char *buf,int len){ char *dst=malloc(len+1,char); memcpy(dst,buf,len); dst[len]='\0'; return dst; } -char* copy_str(char *str){ +char* copy_str(const char *str){ return copy_buf(str,strlen(str)); } diff --git a/util.h b/util.h index 5831b95..1124982 100644 --- a/util.h +++ b/util.h @@ -1,8 +1,8 @@ #pragma once -char* copy_buf(char *buf,int len); -char* copy_str(char *str); +char* copy_buf(const char *buf,int len); +char* copy_str(const char *str); void str_toupper(char *str); -- cgit v1.2.3-54-g00ecf