runtime.c (6761B)
1 /*
2 * Copyright (c) 2017-2022 Joris Vink <joris@coders.se>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17 #include <sys/param.h>
18 #include <sys/types.h>
19
20 #include "kore.h"
21
22 #if !defined(KORE_NO_HTTP)
23 #include "http.h"
24 #endif
25
26 #if defined(KORE_USE_PYTHON)
27 #include "python_api.h"
28 #endif
29
30 #if defined(KORE_USE_LUA)
31 #include "lua_api.h"
32 #endif
33
34 static void native_runtime_execute(void *);
35 static int native_runtime_onload(void *, int);
36 static void native_runtime_signal(void *, int);
37 static void native_runtime_connect(void *, struct connection *);
38 static void native_runtime_configure(void *, int, char **);
39 #if !defined(KORE_NO_HTTP)
40 static int native_runtime_http_request(void *, struct http_request *);
41 static void native_runtime_http_request_free(void *, struct http_request *);
42 static void native_runtime_http_body_chunk(void *, struct http_request *,
43 const void *, size_t);
44 static int native_runtime_validator(void *, struct http_request *,
45 const void *);
46
47 static void native_runtime_wsmessage(void *, struct connection *, u_int8_t,
48 const void *, size_t);
49 #endif
50
51 struct kore_runtime kore_native_runtime = {
52 KORE_RUNTIME_NATIVE,
53 #if !defined(KORE_NO_HTTP)
54 .http_request = native_runtime_http_request,
55 .http_request_free = native_runtime_http_request_free,
56 .http_body_chunk = native_runtime_http_body_chunk,
57 .validator = native_runtime_validator,
58 .wsconnect = native_runtime_connect,
59 .wsmessage = native_runtime_wsmessage,
60 .wsdisconnect = native_runtime_connect,
61 #endif
62 .onload = native_runtime_onload,
63 .signal = native_runtime_signal,
64 .connect = native_runtime_connect,
65 .execute = native_runtime_execute,
66 .configure = native_runtime_configure
67 };
68
69 static struct kore_runtime *runtimes[] = {
70 #if defined(KORE_USE_PYTHON)
71 &kore_python_runtime,
72 #endif
73 #if defined(KORE_USE_LUA)
74 &kore_lua_runtime,
75 #endif
76 NULL
77 };
78
79 size_t
80 kore_runtime_count(void)
81 {
82 return ((sizeof(runtimes) / sizeof(runtimes[0])) - 1);
83 }
84
85 void
86 kore_runtime_resolve(const char *module, const struct stat *st)
87 {
88 int i;
89
90 if (runtimes[0] == NULL)
91 return;
92
93 for (i = 0; runtimes[i] != NULL; i++) {
94 if (runtimes[i]->resolve == NULL)
95 continue;
96 if (runtimes[i]->resolve(module, st))
97 break;
98 }
99
100 if (runtimes[i] == NULL)
101 fatal("No runtime available to run '%s'", module);
102 }
103
104 struct kore_runtime_call *
105 kore_runtime_getcall(const char *symbol)
106 {
107 void *ptr;
108 struct kore_runtime_call *rcall;
109 struct kore_runtime *runtime;
110
111 ptr = kore_module_getsym(symbol, &runtime);
112 if (ptr == NULL)
113 return (NULL);
114
115 rcall = kore_malloc(sizeof(*rcall));
116 rcall->addr = ptr;
117 rcall->runtime = runtime;
118
119 return (rcall);
120 }
121
122 void
123 kore_runtime_execute(struct kore_runtime_call *rcall)
124 {
125 rcall->runtime->execute(rcall->addr);
126 }
127
128 void
129 kore_runtime_configure(struct kore_runtime_call *rcall, int argc, char **argv)
130 {
131 rcall->runtime->configure(rcall->addr, argc, argv);
132 }
133
134 int
135 kore_runtime_onload(struct kore_runtime_call *rcall, int action)
136 {
137 return (rcall->runtime->onload(rcall->addr, action));
138 }
139
140 void
141 kore_runtime_connect(struct kore_runtime_call *rcall, struct connection *c)
142 {
143 rcall->runtime->connect(rcall->addr, c);
144 }
145
146 void
147 kore_runtime_signal(struct kore_runtime_call *rcall, int sig)
148 {
149 rcall->runtime->signal(rcall->addr, sig);
150 }
151
152 #if !defined(KORE_NO_HTTP)
153 int
154 kore_runtime_http_request(struct kore_runtime_call *rcall,
155 struct http_request *req)
156 {
157 return (rcall->runtime->http_request(rcall->addr, req));
158 }
159
160 void
161 kore_runtime_http_request_free(struct kore_runtime_call *rcall,
162 struct http_request *req)
163 {
164 rcall->runtime->http_request_free(rcall->addr, req);
165 }
166
167 void
168 kore_runtime_http_body_chunk(struct kore_runtime_call *rcall,
169 struct http_request *req, const void *data, size_t len)
170 {
171 rcall->runtime->http_body_chunk(rcall->addr, req, data, len);
172 }
173
174 int
175 kore_runtime_validator(struct kore_runtime_call *rcall,
176 struct http_request *req, const void *data)
177 {
178 return (rcall->runtime->validator(rcall->addr, req, data));
179 }
180
181 void
182 kore_runtime_wsconnect(struct kore_runtime_call *rcall, struct connection *c)
183 {
184 rcall->runtime->wsconnect(rcall->addr, c);
185 }
186
187 void
188 kore_runtime_wsmessage(struct kore_runtime_call *rcall, struct connection *c,
189 u_int8_t op, const void *data, size_t len)
190 {
191 rcall->runtime->wsmessage(rcall->addr, c, op, data, len);
192 }
193
194 void
195 kore_runtime_wsdisconnect(struct kore_runtime_call *rcall, struct connection *c)
196 {
197 rcall->runtime->wsdisconnect(rcall->addr, c);
198 }
199 #endif
200
201 static void
202 native_runtime_execute(void *addr)
203 {
204 void (*cb)(void);
205
206 *(void **)&(cb) = addr;
207 cb();
208 }
209
210 static void
211 native_runtime_configure(void *addr, int argc, char **argv)
212 {
213 void (*cb)(int, char **);
214
215 *(void **)&(cb) = addr;
216 cb(argc, argv);
217 }
218
219 static void
220 native_runtime_connect(void *addr, struct connection *c)
221 {
222 void (*cb)(struct connection *);
223
224 *(void **)&(cb) = addr;
225 cb(c);
226 }
227
228 static int
229 native_runtime_onload(void *addr, int action)
230 {
231 int (*cb)(int);
232
233 *(void **)&(cb) = addr;
234 return (cb(action));
235 }
236
237 static void
238 native_runtime_signal(void *addr, int sig)
239 {
240 void (*cb)(int);
241
242 *(void **)&(cb) = addr;
243 cb(sig);
244 }
245
246 #if !defined(KORE_NO_HTTP)
247 static int
248 native_runtime_http_request(void *addr, struct http_request *req)
249 {
250 int (*cb)(struct http_request *);
251
252 *(void **)&(cb) = addr;
253 return (cb(req));
254 }
255
256 static void
257 native_runtime_http_request_free(void *addr, struct http_request *req)
258 {
259 int (*cb)(struct http_request *);
260
261 *(void **)&(cb) = addr;
262 cb(req);
263 }
264
265 static void
266 native_runtime_http_body_chunk(void *addr, struct http_request *req,
267 const void *data, size_t len)
268 {
269 void (*cb)(struct http_request *, const void *, size_t);
270
271 *(void **)&(cb) = addr;
272
273 cb(req, data, len);
274 }
275
276 static int
277 native_runtime_validator(void *addr, struct http_request *req, const void *data)
278 {
279 int (*cb)(struct http_request *, const void *);
280
281 *(void **)&(cb) = addr;
282 return (cb(req, data));
283 }
284
285 static void
286 native_runtime_wsmessage(void *addr, struct connection *c, u_int8_t op,
287 const void *data, size_t len)
288 {
289 void (*cb)(struct connection *, u_int8_t, const void *, size_t);
290
291 *(void **)&(cb) = addr;
292 cb(c, op, data, len);
293
294 }
295 #endif