diff --git a/Makefile b/Makefile index 251d27b..4296cc8 100644 --- a/Makefile +++ b/Makefile @@ -12,9 +12,9 @@ ifeq ($(UNAME_S),Darwin) endif #-lsocket -PLUGINS= dummy.$(EXT) fileman.$(EXT) pluginsman.$(EXT) wterm.$(EXT) +PLUGINS= dummy.$(EXT) fileman.$(EXT) pluginsman.$(EXT) wterm.$(EXT) nodedaemon.$(EXT) -PLUGINSDEP = plugins/plugin.o plugins/dbhelper.o plugins/dictionary.o plugins/utils.o plugins/list.o +PLUGINSDEP = plugins/ini.o plugins/plugin.o plugins/dbhelper.o plugins/dictionary.o plugins/utils.o plugins/list.o PLUGINLIBS = -lsqlite3 main: httpd plugins @@ -40,7 +40,7 @@ clean: sclean pclean sclean: rm -f *.o build/httpd pclean: - rm -f $(BUILDIRD)/plugins/* plugins/*.o + rm -rf $(BUILDIRD)/plugins/* plugins/*.o -for file in plugins/* ;do \ if [ -d "$$file" ]; then \ rm "$$file"/*.o; \ diff --git a/build/.DS_Store b/build/.DS_Store index 4f524db..dec238f 100755 Binary files a/build/.DS_Store and b/build/.DS_Store differ diff --git a/build/config.ini b/build/config.ini index 25cea7c..0458dae 100755 --- a/build/config.ini +++ b/build/config.ini @@ -4,4 +4,10 @@ plugins=/Users/mrsang/Google Drive/ushare/cwp/ant-http/build/plugins/ ; plugins plugins_ext=.dylib ; plugins extensions database=/Users/mrsang/Google Drive/ushare/cwp/ant-http/build/databases/ htdocs=/Users/mrsang/Google Drive/ushare/cwp/ant-http/build/htdocs -tmpdir=/Users/mrsang/Google Drive/ushare/cwp/ant-http/build/tmp/ \ No newline at end of file +tmpdir=/Users/mrsang/Google Drive/ushare/cwp/ant-http/build/tmp/ + +; This enable some plugins to be initialised at server startup +[AUTOSTART] +plugin = nodedaemon +;plugin=ffvm +;plugin=dummy \ No newline at end of file diff --git a/build/httpd b/build/httpd index fa086d8..a05e189 100755 Binary files a/build/httpd and b/build/httpd differ diff --git a/build/httpd.dSYM/Contents/Resources/DWARF/httpd b/build/httpd.dSYM/Contents/Resources/DWARF/httpd index 4ae4747..afb69e2 100644 Binary files a/build/httpd.dSYM/Contents/Resources/DWARF/httpd and b/build/httpd.dSYM/Contents/Resources/DWARF/httpd differ diff --git a/build/plugins/dummy.dylib b/build/plugins/dummy.dylib index bfca39c..6f36cdd 100755 Binary files a/build/plugins/dummy.dylib and b/build/plugins/dummy.dylib differ diff --git a/build/plugins/fileman.dylib b/build/plugins/fileman.dylib index d122eb1..02e8dc3 100755 Binary files a/build/plugins/fileman.dylib and b/build/plugins/fileman.dylib differ diff --git a/build/plugins/nodedaemon.dylib b/build/plugins/nodedaemon.dylib new file mode 100755 index 0000000..8d20978 Binary files /dev/null and b/build/plugins/nodedaemon.dylib differ diff --git a/build/plugins/pluginsman.dylib b/build/plugins/pluginsman.dylib index 7a5c4fb..294e841 100755 Binary files a/build/plugins/pluginsman.dylib and b/build/plugins/pluginsman.dylib differ diff --git a/build/plugins/wterm.dylib b/build/plugins/wterm.dylib index 5efd641..828731b 100755 Binary files a/build/plugins/wterm.dylib and b/build/plugins/wterm.dylib differ diff --git a/httpd.c b/httpd.c index 494813e..a67e63d 100644 --- a/httpd.c +++ b/httpd.c @@ -9,7 +9,7 @@ static int config_handler(void* conf, const char* section, const char* name, const char* value) { config_t* pconfig = (config_t*)conf; - + char * ppath = NULL; if (MATCH("SERVER", "port")) { pconfig->port = atoi(value); } else if (MATCH("SERVER", "plugins")) { @@ -22,7 +22,11 @@ static int config_handler(void* conf, const char* section, const char* name, pconfig->htdocs = strdup(value); } else if(MATCH("SERVER", "tmpdir")) { pconfig->tmpdir = strdup(value); - }else { + }else if(strcmp(section,"AUTOSTART")==0){ + // The server section must be added before the autostart section + // auto start plugin + plugin_load(value); + } else { return 0; /* unknown section/name, error */ } return 1; diff --git a/plugin_manager.c b/plugin_manager.c index e6c9e24..a4a5298 100644 --- a/plugin_manager.c +++ b/plugin_manager.c @@ -391,7 +391,7 @@ void * plugin_from_file(char* name) void *lib_handle; char* error; char* path = __s("%s%s%s",server_config.plugins_dir,name,server_config.plugins_ext); - void (*fn)(const char*,const char*,const char*,const char*); + void (*fn)(const char*,const char*,const char*,const char*,int); lib_handle = dlopen(path, RTLD_LAZY); if (!lib_handle) { @@ -399,45 +399,70 @@ void * plugin_from_file(char* name) return NULL; } // set database path - fn = (void (*)(const char *, const char *, const char *, const char *))dlsym(lib_handle, "__init_plugin__"); + fn = (void (*)(const char *, const char *, const char *, const char *,int))dlsym(lib_handle, "__init_plugin__"); if ((error = dlerror()) != NULL) LOG("Problem when setting data path for %s : %s \n", name,error); else - (*fn)(name,server_config.db_path, server_config.htdocs,server_config.plugins_dir); + (*fn)(name,server_config.db_path, server_config.htdocs,server_config.plugins_dir,server_config.port); free(path); return lib_handle; } - - +void unload_plugin(struct plugin_entry* np) +{ + char* error; + void (*fn)() = NULL; + // find and execute the exit function + fn = (void (*)())dlsym(np->handle, "pexit"); + if ((error = dlerror()) != NULL) + { + LOG("Cant not find exit method from %s : %s \n", np->pname,error); + } + else + { + // execute it + (*fn)(); + } + dlclose(np->handle); + //free((void *) np->handle); + free((void *) np->pname); +} +/* + Unload a plugin by its name +*/ +void unload_plugin_by_name(const char* name) +{ + LOG("%s\n","Unloading thing"); + struct plugin_entry *np; + int hasval = hash(name, HASHSIZE); + np = plugin_table[hasval]; + if(strcmp(np->pname,name) == 0) + { + unload_plugin(np); + plugin_table[hasval] = np->next; + } + else + { + for (np; np != NULL; np = np->next) + if (np->next != NULL && strcmp(name, np->next->pname) == 0) + break; + if(np == NULL) return; // the plugin is is not loaded + unload_plugin(np->next); + np->next = np->next->next; + } +} /** * Unload all the plugin loaded on the plugin table */ void unload_all_plugin() { LOG("Unload all plugins\n"); - void (*fn)(); - char* error; for(int i=0;inext) { - // execute the exit function if exists - // load the function - fn = (void (*)())dlsym(np->handle, "pexit"); - if ((error = dlerror()) != NULL) - { - LOG("Cant not find exit method from %s : %s \n", np->pname,error); - } - else - { - // execute it - (*fn)(); - } - dlclose(np->handle); - //free((void *) np->handle); - free((void *) np->pname); + unload_plugin(np); } plugin_table[i] = NULL; } diff --git a/plugin_manager.h b/plugin_manager.h index d7f719d..3451284 100644 --- a/plugin_manager.h +++ b/plugin_manager.h @@ -18,6 +18,8 @@ struct plugin_entry *plugin_lookup(char *s); /* install: put (name, defn) in hashtab */ struct plugin_entry *plugin_load(char *name); void unload_all_plugin(); +void unload_plugin(struct plugin_entry*); +void unload_plugin_by_name(const char*); void * plugin_from_file(char* name); char* post_url_decode(int client,int len); dictionary decode_url_request(const char* query); diff --git a/plugins/dummy/dummy.c b/plugins/dummy/dummy.c index 057bcca..5d8cd79 100644 --- a/plugins/dummy/dummy.c +++ b/plugins/dummy/dummy.c @@ -15,7 +15,10 @@ void init() dbquery(db,sql,NULL); printf("Finish init\n"); } - +void pexit() +{ + LOG("%s\n","Plugin DUMMY is exited"); +} void execute(int client,const char* method,dictionary rq) { @@ -50,7 +53,6 @@ void execute(int client,const char* method,dictionary rq) __t(client, "],\"total\":%d}",records->idx); free(records); //__t(client, query); - } // delete record diff --git a/plugins/fileman/fileman.c.o b/plugins/fileman/fileman.c.o index e0b69de..8014b39 100644 Binary files a/plugins/fileman/fileman.c.o and b/plugins/fileman/fileman.c.o differ diff --git a/plugins/nodedaemon/nodedaemon.c b/plugins/nodedaemon/nodedaemon.c new file mode 100644 index 0000000..8d46919 --- /dev/null +++ b/plugins/nodedaemon/nodedaemon.c @@ -0,0 +1,145 @@ +// network support +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../plugin.h" +#define RQ +#define REQUEST_PATTERN "POST /node_register HTTP/1.0\r\nHost: antd\r\nUser-Agent: antd\r\nContent-Type: application/json\r\nContent-Length: %d\r\n\r\n%s" +#define JSON_MSG "{\"ip\":\"%s\",\"port\":\"%d\"}" +void init(); +struct master_conf_t{ + int port; + char* ip; +} ; + +struct master_conf_t mconfig; + +call __init__ = init; +int request_socket(const char* ip, int port) +{ + int sockfd = -1; + struct sockaddr_in dest; + char* request; + // time out setting + struct timeval timeout; + timeout.tv_sec = 3; + timeout.tv_usec = 0; + if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) + { + perror("Socket"); + return -1; + } + if (setsockopt (sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout,sizeof(timeout)) < 0) + perror("setsockopt failed\n"); + + //if (setsockopt (sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout,sizeof(timeout)) < 0) + // perror("setsockopt failed\n"); + + bzero(&dest, sizeof(dest)); + dest.sin_family = AF_INET; + dest.sin_port = htons(port); + if ( inet_aton(ip, &dest.sin_addr.s_addr) == 0 ) + { + perror(ip); + close(sockfd); + return -1; + } + if ( connect(sockfd, (struct sockaddr*)&dest, sizeof(dest)) != 0 ) + { + close(sockfd); + //perror("Connect"); + return -1; + } + return sockfd; +} + +char* get_ip_address() +{ + struct ifaddrs* addrs; + getifaddrs(&addrs); + struct ifaddrs* tmp = addrs; + char* ip; + while (tmp) + { + if (tmp->ifa_addr && tmp->ifa_addr->sa_family == AF_INET) + { + struct sockaddr_in *pAddr = (struct sockaddr_in *)tmp->ifa_addr; + ip = inet_ntoa(pAddr->sin_addr); + if(strcmp(ip,"127.0.0.1") != 0) + return ip; + } + tmp = tmp->ifa_next; + } + freeifaddrs(addrs); + return "127.0.0.1"; +} +int inform_master() +{ + int sockfd; + //rpc_response_t* rdata = NULL; + char* request; + char* data = __s(JSON_MSG,get_ip_address(),__plugin__.sport); + while((sockfd = request_socket(mconfig.ip, mconfig.port)) == -1) + { + // wait for 3s and then request to server + usleep(3000000); + } + request = __s(REQUEST_PATTERN, strlen(data), data); + send(sockfd,request, strlen(request),0); + //rdata = parse_response(sockfd); + close(sockfd); + LOG("%s","OK, master registered \n"); + free(request); + return 0; +} +static int config_handler(void* conf, const char* section, const char* name, + const char* value) +{ + struct master_conf_t* pconfig = (struct master_conf_t*)conf; + char * ppath = NULL; + if (strcmp(name, "port") == 0) { + pconfig->port = atoi(value); + } else if (strcmp(name, "ip") == 0) { + pconfig->ip = strdup(value); + } else { + return 0; + } + return 1; +} +void read_config() +{ + mconfig.ip = "127.0.0.1"; + mconfig.port = 8080; + char* file = __s("%s%s%s.ini",config_dir(), DIR_SEP, __plugin__.name); + if (ini_parse(file, config_handler, &mconfig) < 0) { + LOG("Can't load '%s'\n. Used defaut configuration", file); + } + printf("%s %d\n",mconfig.ip, mconfig.port ); +} +void init() +{ + read_config(); + pthread_t newthread; + if (pthread_create(&newthread , NULL,(void(*)()) inform_master, NULL) != 0) + perror("pthread_create: cannot create daemon for finding master"); + else + { + //reclaim the stack data when thread finish + pthread_detach(newthread) ; + } +} +void pexit() +{ + LOG("%s","EXIT daemon"); +} +void execute(int c, const char* m, dictionary d) +{ + text(c); + __t(c,"This is a system plugin. It cant be acessed from the web"); +} \ No newline at end of file diff --git a/plugins/plugin.c b/plugins/plugin.c index 8939d4b..6ceb607 100644 --- a/plugins/plugin.c +++ b/plugins/plugin.c @@ -1,16 +1,18 @@ #include "plugin.h" plugin_header __plugin__; -call __init__; // private function +call __init__; -void __init_plugin__(const char* pl,const char*ph,const char* htdocs, const char* pdir){ +void __init_plugin__(const char* pl,const char*ph,const char* htdocs, const char* pdir,int port){ __plugin__.name = strdup(pl); __plugin__.dbpath= strdup(ph); __plugin__.htdocs = strdup(htdocs); __plugin__.pdir = strdup(pdir); + __plugin__.sport = port; if(__init__ != NULL) __init__(); }; + #ifdef USE_DB sqldb getdb() { @@ -240,4 +242,12 @@ void set_cookie(int client,dictionary dic) __t(client,"Set-Cookie: %s=%s",assoc->key, (char*)assoc->value); } response(client,""); +} +char* config_dir() +{ + struct stat st; + char* path = __s("%s%s%s", __plugin__.pdir,DIR_SEP, __plugin__.name); + if (stat(path, &st) == -1) + mkdir(path, 0755); + return path; } \ No newline at end of file diff --git a/plugins/plugin.h b/plugins/plugin.h index c27ab89..deafbf3 100644 --- a/plugins/plugin.h +++ b/plugins/plugin.h @@ -22,6 +22,7 @@ typedef struct { char *dbpath; char * htdocs; char*pdir; + int *sport; } plugin_header; @@ -49,6 +50,7 @@ int __b(int, const unsigned char*, int); int __f(int, const char*); int __fb(int, const char*); int upload(const char*, const char*); +char* config_dir(); char* route(const char*); char* htdocs(const char*); #ifdef USE_DB diff --git a/plugins/pluginsman/pluginsman.c.o b/plugins/pluginsman/pluginsman.c.o index 7c26e86..ff9cbab 100644 Binary files a/plugins/pluginsman/pluginsman.c.o and b/plugins/pluginsman/pluginsman.c.o differ