/* * Copyright (c) 2017-2022 Joris Vink * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include #include "kore.h" #if !defined(KORE_NO_HTTP) #include "http.h" #endif #if defined(KORE_USE_PYTHON) #include "python_api.h" #endif #if defined(KORE_USE_LUA) #include "lua_api.h" #endif static void native_runtime_execute(void *); static int native_runtime_onload(void *, int); static void native_runtime_signal(void *, int); static void native_runtime_connect(void *, struct connection *); static void native_runtime_configure(void *, int, char **); #if !defined(KORE_NO_HTTP) static int native_runtime_http_request(void *, struct http_request *); static void native_runtime_http_request_free(void *, struct http_request *); static void native_runtime_http_body_chunk(void *, struct http_request *, const void *, size_t); static int native_runtime_validator(void *, struct http_request *, const void *); static void native_runtime_wsmessage(void *, struct connection *, u_int8_t, const void *, size_t); #endif struct kore_runtime kore_native_runtime = { KORE_RUNTIME_NATIVE, #if !defined(KORE_NO_HTTP) .http_request = native_runtime_http_request, .http_request_free = native_runtime_http_request_free, .http_body_chunk = native_runtime_http_body_chunk, .validator = native_runtime_validator, .wsconnect = native_runtime_connect, .wsmessage = native_runtime_wsmessage, .wsdisconnect = native_runtime_connect, #endif .onload = native_runtime_onload, .signal = native_runtime_signal, .connect = native_runtime_connect, .execute = native_runtime_execute, .configure = native_runtime_configure }; static struct kore_runtime *runtimes[] = { #if defined(KORE_USE_PYTHON) &kore_python_runtime, #endif #if defined(KORE_USE_LUA) &kore_lua_runtime, #endif NULL }; size_t kore_runtime_count(void) { return ((sizeof(runtimes) / sizeof(runtimes[0])) - 1); } void kore_runtime_resolve(const char *module, const struct stat *st) { int i; if (runtimes[0] == NULL) return; for (i = 0; runtimes[i] != NULL; i++) { if (runtimes[i]->resolve == NULL) continue; if (runtimes[i]->resolve(module, st)) break; } if (runtimes[i] == NULL) fatal("No runtime available to run '%s'", module); } struct kore_runtime_call * kore_runtime_getcall(const char *symbol) { void *ptr; struct kore_runtime_call *rcall; struct kore_runtime *runtime; ptr = kore_module_getsym(symbol, &runtime); if (ptr == NULL) return (NULL); rcall = kore_malloc(sizeof(*rcall)); rcall->addr = ptr; rcall->runtime = runtime; return (rcall); } void kore_runtime_execute(struct kore_runtime_call *rcall) { rcall->runtime->execute(rcall->addr); } void kore_runtime_configure(struct kore_runtime_call *rcall, int argc, char **argv) { rcall->runtime->configure(rcall->addr, argc, argv); } int kore_runtime_onload(struct kore_runtime_call *rcall, int action) { return (rcall->runtime->onload(rcall->addr, action)); } void kore_runtime_connect(struct kore_runtime_call *rcall, struct connection *c) { rcall->runtime->connect(rcall->addr, c); } void kore_runtime_signal(struct kore_runtime_call *rcall, int sig) { rcall->runtime->signal(rcall->addr, sig); } #if !defined(KORE_NO_HTTP) int kore_runtime_http_request(struct kore_runtime_call *rcall, struct http_request *req) { return (rcall->runtime->http_request(rcall->addr, req)); } void kore_runtime_http_request_free(struct kore_runtime_call *rcall, struct http_request *req) { rcall->runtime->http_request_free(rcall->addr, req); } void kore_runtime_http_body_chunk(struct kore_runtime_call *rcall, struct http_request *req, const void *data, size_t len) { rcall->runtime->http_body_chunk(rcall->addr, req, data, len); } int kore_runtime_validator(struct kore_runtime_call *rcall, struct http_request *req, const void *data) { return (rcall->runtime->validator(rcall->addr, req, data)); } void kore_runtime_wsconnect(struct kore_runtime_call *rcall, struct connection *c) { rcall->runtime->wsconnect(rcall->addr, c); } void kore_runtime_wsmessage(struct kore_runtime_call *rcall, struct connection *c, u_int8_t op, const void *data, size_t len) { rcall->runtime->wsmessage(rcall->addr, c, op, data, len); } void kore_runtime_wsdisconnect(struct kore_runtime_call *rcall, struct connection *c) { rcall->runtime->wsdisconnect(rcall->addr, c); } #endif static void native_runtime_execute(void *addr) { void (*cb)(void); *(void **)&(cb) = addr; cb(); } static void native_runtime_configure(void *addr, int argc, char **argv) { void (*cb)(int, char **); *(void **)&(cb) = addr; cb(argc, argv); } static void native_runtime_connect(void *addr, struct connection *c) { void (*cb)(struct connection *); *(void **)&(cb) = addr; cb(c); } static int native_runtime_onload(void *addr, int action) { int (*cb)(int); *(void **)&(cb) = addr; return (cb(action)); } static void native_runtime_signal(void *addr, int sig) { void (*cb)(int); *(void **)&(cb) = addr; cb(sig); } #if !defined(KORE_NO_HTTP) static int native_runtime_http_request(void *addr, struct http_request *req) { int (*cb)(struct http_request *); *(void **)&(cb) = addr; return (cb(req)); } static void native_runtime_http_request_free(void *addr, struct http_request *req) { int (*cb)(struct http_request *); *(void **)&(cb) = addr; cb(req); } static void native_runtime_http_body_chunk(void *addr, struct http_request *req, const void *data, size_t len) { void (*cb)(struct http_request *, const void *, size_t); *(void **)&(cb) = addr; cb(req, data, len); } static int native_runtime_validator(void *addr, struct http_request *req, const void *data) { int (*cb)(struct http_request *, const void *); *(void **)&(cb) = addr; return (cb(req, data)); } static void native_runtime_wsmessage(void *addr, struct connection *c, u_int8_t op, const void *data, size_t len) { void (*cb)(struct connection *, u_int8_t, const void *, size_t); *(void **)&(cb) = addr; cb(c, op, data, len); } #endif