Commits

Daniel Poelzleithner committed 1098f78

added plugin loading
started http plugin

Comments (0)

Files changed (7)

     option 'enabled' 'off'
     option 'port' '54'
 
+config 'plugin' 'http'
+    option 'enabled' 'on'
+    option 'port' '54'
 
 config 'backend' 'tests'
     option 'enabled' 'off'

src/CMakeLists.txt

 add_library(libbackend STATIC file_backend.c tc_backend.c backends.c)
 target_link_libraries(libbackend tokyocabinet pthread uci)
 
-target_link_libraries(dssd dnet libhash libbackend ${LUA_LIBRARIES})
+target_link_libraries(dssd dnet libhash libbackend ${LUA_LIBRARIES})
+
+add_subdirectory (plugins)
 #include <string.h>
 #include <time.h>
 #include <pthread.h>
+#include <dlfcn.h>
 
 #include <netinet/in.h>
 
 	struct list_head *p;
     struct uci_backend_config *backend;
     struct lua_thread_param *param;
-    
+
 	list_for_each(p, &dssd_config_backend) {
         backend = list_entry(p, struct uci_backend_config, list);
         if(backend->thread)
     }
 }
 
+void *dssd_plugin_start(void *param) {
+    struct uci_plugins_config *plugin = param;
+    if(!plugin->init(plugin))
+        dssd_log(DNET_LOG_INFO, "error running in: %s\n", plugin->name);
+
+}
+
+
+struct uci_plugins_config *dssd_load_plugin(const char *name, struct uci_plugins_config *plugin) {
+	struct list_head *p;
+    char *filename = malloc(50);
+	//struct uci_plugins_config *plugin;
+	const struct uci_plugin_ops *ops;
+    int rv;
+
+	void *dlh;
+
+    if(plugin->thread)
+        return;
+
+
+    dssd_log(DNET_LOG_INFO, "load plugin: %s\n", name);
+
+    snprintf(filename, 50, "plugins/lib%s.so", name);
+
+	dlh = dlopen(filename, RTLD_GLOBAL|RTLD_NOW);
+	if (!dlh) {
+        dssd_log(DNET_LOG_INFO, "could not load plugin: %s\n", filename);
+        free(filename);
+       return NULL;
+    }
+     
+
+	//ops = dlsym(dlh, "dssd_plugin");
+    ops = dlsym(dlh, "dssd_plugin");
+
+	if (!ops || !ops->attach) {
+		if (!ops)
+			fprintf(stderr, "No ops\n");
+		else if (!ops->attach)
+			fprintf(stderr, "No attach\n");
+		else
+			fprintf(stderr, "Other weirdness\n");
+		dlclose(dlh);
+	}
+
+    if(!plugin) {
+        //uci_list_add(&ctx->plugins, &p->e.list);
+        list_for_each(p, &dssd_config_plugin) {
+            plugin = list_entry(p, struct uci_plugins_config, list);
+            if(!strcmp(plugin->name, name)) {
+                plugin->dlh = dlh;
+                plugin->init = ops;
+                //*(void **)(int)ops();
+                break;
+            }
+        }
+    }
+    if(strcmp(plugin->name, name))
+        plugin = NULL;
+
+    if(!plugin) {
+        plugin = malloc(sizeof(struct uci_plugins_config));
+        memset(plugin, 0, sizeof(struct uci_plugins_config));
+    }
+    
+    plugin->init = ops;
+	plugin->dlh = dlh;
+    plugin->name = name;
+    plugin->enabled = 1;
+    plugin->thread = malloc(sizeof(pthread_t));
+    
+    if(!&plugin->list)
+        list_add(&plugin->list, &dssd_config_plugin);
+
+    
+    rv = pthread_create(plugin->thread, NULL, dssd_plugin_start, plugin);
+    if(rv)
+        dssd_fatal("can't start lua thread: %d", rv);
+
+    free(filename);
+	return plugin;
+}
+
+int start_all_plugins() {
+    //pthread_create(pthread_t *thread, const pthread_attr_t *attr,
+    //void *(*start_routine)(void*), void *arg);
+    int rv;
+	struct list_head *p;
+	struct uci_basic_config *cfg;
+	struct uci_plugins_config *plugin;
+    struct lua_thread_param *param;
+    
+	list_for_each(p, &dssd_config_plugin) {
+        plugin = list_entry(p, struct uci_plugins_config, list);
+        if(!plugin->enabled)
+            continue;
+        dssd_load_plugin(plugin->name, plugin);
+    
+    }
+}
+
 
 int main(int argc, char *argv[])
 {
 	char *historyf = NULL, *root = NULL, *removef = NULL, *config_path = NULL;
     char *config_name = NULL;
 	unsigned char trans_id[DNET_ID_SIZE], *id = NULL;
-
     dssd_do_exit = 0;
 	FILE *log = NULL;
     pthread_t lua_thread;
 		}
 	}
 	
-	if (!logfile)
+	if (!logfile) {
 		fprintf(stderr, "No log file found, logging will be disabled.\n");
-
-	if (logfile) {
+    } else {
         if (!strcmp(logfile, "-")) {
             log = stdout;
         } else {
                 return err;
             }
         }
+
 		dssd_server_config->log_private = log;
 		dssd_server_config->log = dnet_common_log;
 	}
 	if (daemon)
 		dnet_background();
 
+    start_all_plugins();
     start_lua_threads();
 
     while (!dssd_do_exit)
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/syscall.h>
+#include <stdlib.h>
 
 #include "dnet/packet.h"
 #include "dnet/interface.h"
 
     lua_State *lua_state;
     pthread_t *thread;
+    const void *dlh;
+    const void *ops;
+    int (*init)(struct uci_plugins_config *);
 };
 
 struct uci_backend_config {

src/plugins/CMakeLists.txt

+#TARGET_LINK_LIBRARIES( ${DNET} )
+
+IF (CMAKE_C_FLAGS_DEBUG)
+    add_definitions(-DDEBUG)
+ENDIF (CMAKE_C_FLAGS_DEBUG)
+
+add_library(http SHARED http.c)
+INCLUDE_DIRECTORIES(${CMAKE_HOME_DIRECTORY}/src)
+
+target_link_libraries(http uci ${LUA_LIBRARIES} event)

src/plugins/http.c

+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/queue.h>
+#include <stdlib.h>
+#include "dssd.h"
+
+#include <err.h>
+#include <event.h>
+#include <evhttp.h>
+
+void generic_handler(struct evhttp_request *req, void *arg)
+{
+        struct evbuffer *buf;
+        buf = evbuffer_new();
+
+        if (buf == NULL)
+            err(1, "failed to create response buffer");
+
+        evbuffer_add_printf(buf, "Requested: %sn", evhttp_request_uri(req));
+        evhttp_send_reply(req, HTTP_OK, "OK", buf);
+}
+
+int dssd_plugin(struct uci_plugins_config *plugin)
+{
+    struct evhttp *httpd;
+
+    event_init();
+    httpd = evhttp_start("0.0.0.0", 8080);
+
+    printf("running http\n");
+
+    /* Set a callback for requests to "/specific". */
+    /* evhttp_set_cb(httpd, "/specific", another_handler, NULL); */
+
+    /* Set a callback for all other requests. */
+    evhttp_set_gencb(httpd, generic_handler, NULL);
+
+    event_dispatch();
+
+    /* Not reached in this code as it is now. */
+    evhttp_free(httpd);
+
+    return 0;
+}
 uci_parse_strategy(void *section, struct uci_optmap *om, union ucimap_data *data, const char *str)
 {
 	
+
     if(!strcmp(str, "prefer_network"))
         data->i = DNET_MERGE_PREFER_NETWORK;
     else if (!strcmp(str, "prefer_local"))
         data->i = PF_INET6;
     else
         return -1;
-
 	return 0;
 }
 
     data->ptr = entry;
 
 	return 0;
-
 }
 
 static void
 uci_format_mapping(void *sction, struct uci_optmap *om, union ucimap_data *data, char **str)
 {
 	static char buf[16];
-    struct uci_mapping_entry *entry = *data->data;
+    struct uci_mapping_entry *entry = data->ptr;
 
 	*str = entry->str;
  	return 0;
 dssd_add_mapping(struct uci_map *map, void *section)
 {
 	struct uci_mapping *m = section;
+
     list_add(&m->list, &dssd_config_mappings);
 
 	return 0;
 	{
 		.map = {
 			UCIMAP_OPTION(struct uci_basic_config, proto),
-			.type = UCIMAP_CUSTOM,
+			.type = UCIMAP_STRING,
 			.name = "proto",
-			.parse = uci_parse_proto,
-			.format = uci_format_proto,
+			.data.s.maxlen = 32,
 		}
 	},
 	{