Blame


1 c734c0e9 2021-08-03 op /*
2 c734c0e9 2021-08-03 op * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
3 c734c0e9 2021-08-03 op *
4 c734c0e9 2021-08-03 op * Permission to use, copy, modify, and distribute this software for any
5 c734c0e9 2021-08-03 op * purpose with or without fee is hereby granted, provided that the above
6 c734c0e9 2021-08-03 op * copyright notice and this permission notice appear in all copies.
7 c734c0e9 2021-08-03 op *
8 c734c0e9 2021-08-03 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 c734c0e9 2021-08-03 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 c734c0e9 2021-08-03 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 c734c0e9 2021-08-03 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 c734c0e9 2021-08-03 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 c734c0e9 2021-08-03 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 c734c0e9 2021-08-03 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 c734c0e9 2021-08-03 op */
16 c734c0e9 2021-08-03 op
17 c734c0e9 2021-08-03 op #include "compat.h"
18 c734c0e9 2021-08-03 op
19 9820edbf 2021-08-06 op #include <sys/socket.h>
20 9820edbf 2021-08-06 op #include <sys/stat.h>
21 9820edbf 2021-08-06 op #include <sys/wait.h>
22 9820edbf 2021-08-06 op
23 c734c0e9 2021-08-03 op #include <assert.h>
24 9820edbf 2021-08-06 op #include <endian.h>
25 9820edbf 2021-08-06 op #include <errno.h>
26 9820edbf 2021-08-06 op #include <fcntl.h>
27 c734c0e9 2021-08-03 op #include <inttypes.h>
28 9820edbf 2021-08-06 op #include <poll.h>
29 9820edbf 2021-08-06 op #include <pwd.h>
30 32b8add4 2021-12-14 op #include <regex.h>
31 9820edbf 2021-08-06 op #include <signal.h>
32 c734c0e9 2021-08-03 op #include <stdio.h>
33 c734c0e9 2021-08-03 op #include <stdlib.h>
34 c734c0e9 2021-08-03 op #include <string.h>
35 c734c0e9 2021-08-03 op #include <syslog.h>
36 dd1d2343 2021-08-05 op #include <unistd.h>
37 c734c0e9 2021-08-03 op
38 9820edbf 2021-08-06 op #include "client.h"
39 c734c0e9 2021-08-03 op #include "log.h"
40 58329cc1 2021-08-06 op #include "script.h"
41 58329cc1 2021-08-06 op #include "utils.h"
42 c734c0e9 2021-08-03 op
43 c734c0e9 2021-08-03 op #define DEBUG 0
44 c734c0e9 2021-08-03 op
45 9820edbf 2021-08-06 op #ifndef INFTIM
46 9820edbf 2021-08-06 op #define INFTIM -1
47 9820edbf 2021-08-06 op #endif
48 9820edbf 2021-08-06 op
49 9820edbf 2021-08-06 op static const char *argv0;
50 9820edbf 2021-08-06 op
51 9820edbf 2021-08-06 op static uint8_t *lastmsg;
52 9820edbf 2021-08-06 op
53 9820edbf 2021-08-06 op static struct imsgbuf ibuf;
54 9820edbf 2021-08-06 op static int ibuf_inuse;
55 370b4f2e 2021-08-07 op static int child_out = -1;
56 9820edbf 2021-08-06 op
57 c734c0e9 2021-08-03 op static struct procs procs = TAILQ_HEAD_INITIALIZER(procs);
58 c734c0e9 2021-08-03 op static struct tests tests = TAILQ_HEAD_INITIALIZER(tests);
59 d728769d 2021-08-07 op
60 d728769d 2021-08-07 op static int ntests;
61 c734c0e9 2021-08-03 op
62 d9d02161 2021-08-04 op static struct opstacks blocks = TAILQ_HEAD_INITIALIZER(blocks);
63 d9d02161 2021-08-04 op static struct opstacks args = TAILQ_HEAD_INITIALIZER(args);
64 c734c0e9 2021-08-03 op
65 5de2d36f 2021-08-04 op #define STACK_HEIGHT 64
66 c734c0e9 2021-08-03 op static struct value vstack[STACK_HEIGHT];
67 c734c0e9 2021-08-03 op static int stackh;
68 c734c0e9 2021-08-03 op
69 f9cd3e06 2021-08-04 op static struct envs envs = TAILQ_HEAD_INITIALIZER(envs);
70 f9cd3e06 2021-08-04 op
71 c734c0e9 2021-08-03 op static struct value v_false = {.type = V_NUM, .v = {.num = 0}};
72 c734c0e9 2021-08-03 op static struct value v_true = {.type = V_NUM, .v = {.num = 1}};
73 6019438a 2021-08-05 op
74 6019438a 2021-08-05 op static uint8_t lasttag;
75 dd1d2343 2021-08-05 op
76 dd1d2343 2021-08-05 op static int debug;
77 4315b20a 2021-08-05 op static int syntaxcheck;
78 c734c0e9 2021-08-03 op
79 f3289b7e 2021-08-06 op static const char *filler;
80 f3289b7e 2021-08-06 op
81 f9cd3e06 2021-08-04 op static inline void
82 f3289b7e 2021-08-06 op before_printing(void)
83 f3289b7e 2021-08-06 op {
84 f3289b7e 2021-08-06 op if (filler != NULL) {
85 f3289b7e 2021-08-06 op printf("%s", filler);
86 f3289b7e 2021-08-06 op filler = NULL;
87 f3289b7e 2021-08-06 op }
88 f3289b7e 2021-08-06 op }
89 f3289b7e 2021-08-06 op
90 f3289b7e 2021-08-06 op static inline void
91 370b4f2e 2021-08-07 op check_for_output(void)
92 370b4f2e 2021-08-07 op {
93 370b4f2e 2021-08-07 op static char buf[BUFSIZ];
94 370b4f2e 2021-08-07 op struct pollfd pfd;
95 370b4f2e 2021-08-07 op ssize_t r;
96 370b4f2e 2021-08-07 op
97 370b4f2e 2021-08-07 op pfd.fd = child_out;
98 370b4f2e 2021-08-07 op pfd.events = POLLIN;
99 370b4f2e 2021-08-07 op if (poll(&pfd, 1, 0) == -1)
100 370b4f2e 2021-08-07 op fatal("poll");
101 370b4f2e 2021-08-07 op
102 370b4f2e 2021-08-07 op if (!(pfd.revents & POLLIN))
103 370b4f2e 2021-08-07 op return;
104 370b4f2e 2021-08-07 op
105 370b4f2e 2021-08-07 op for (;;) {
106 2305d578 2021-08-07 op if ((r = read(child_out, buf, sizeof(buf))) == -1) {
107 2305d578 2021-08-07 op if (errno == EAGAIN)
108 2305d578 2021-08-07 op break;
109 370b4f2e 2021-08-07 op fatal("read");
110 2305d578 2021-08-07 op }
111 370b4f2e 2021-08-07 op if (r == 0)
112 370b4f2e 2021-08-07 op break;
113 370b4f2e 2021-08-07 op before_printing();
114 370b4f2e 2021-08-07 op fwrite(buf, 1, r, stdout);
115 370b4f2e 2021-08-07 op }
116 370b4f2e 2021-08-07 op }
117 370b4f2e 2021-08-07 op
118 370b4f2e 2021-08-07 op static inline void
119 54736a95 2021-08-04 op peekn(int depth, struct value *v)
120 54736a95 2021-08-04 op {
121 54736a95 2021-08-04 op if (depth > stackh)
122 54736a95 2021-08-04 op errx(1, "can't peek the stack at %d: underflow",
123 54736a95 2021-08-04 op depth);
124 54736a95 2021-08-04 op memcpy(v, &vstack[stackh - depth], sizeof(*v));
125 54736a95 2021-08-04 op
126 54736a95 2021-08-04 op #if DEBUG
127 54736a95 2021-08-04 op printf("peeking(%d) ", depth); pp_val(v); printf("\n");
128 54736a95 2021-08-04 op #endif
129 54736a95 2021-08-04 op }
130 54736a95 2021-08-04 op
131 54736a95 2021-08-04 op static inline void
132 f9cd3e06 2021-08-04 op popv(struct value *v)
133 f9cd3e06 2021-08-04 op {
134 f9cd3e06 2021-08-04 op if (stackh == 0)
135 f9cd3e06 2021-08-04 op errx(1, "can't pop the stack: underflow");
136 f9cd3e06 2021-08-04 op memcpy(v, &vstack[--stackh], sizeof(*v));
137 f9cd3e06 2021-08-04 op
138 f9cd3e06 2021-08-04 op #if DEBUG
139 f9cd3e06 2021-08-04 op printf("popping "); pp_val(v); printf("\n");
140 f9cd3e06 2021-08-04 op #endif
141 f9cd3e06 2021-08-04 op }
142 f9cd3e06 2021-08-04 op
143 f9cd3e06 2021-08-04 op static inline void
144 54736a95 2021-08-04 op popvn(int n)
145 54736a95 2021-08-04 op {
146 54736a95 2021-08-04 op struct value v;
147 54736a95 2021-08-04 op
148 54736a95 2021-08-04 op while (n-- > 0)
149 54736a95 2021-08-04 op popv(&v);
150 54736a95 2021-08-04 op }
151 54736a95 2021-08-04 op
152 54736a95 2021-08-04 op static inline void
153 f9cd3e06 2021-08-04 op pushv(struct value *v)
154 f9cd3e06 2021-08-04 op {
155 f9cd3e06 2021-08-04 op if (stackh == STACK_HEIGHT)
156 f9cd3e06 2021-08-04 op errx(1, "can't push the stack: overflow");
157 f9cd3e06 2021-08-04 op
158 f9cd3e06 2021-08-04 op #if DEBUG
159 f9cd3e06 2021-08-04 op printf("pushing "); pp_val(v); printf("\n");
160 f9cd3e06 2021-08-04 op #endif
161 f9cd3e06 2021-08-04 op
162 f9cd3e06 2021-08-04 op memcpy(&vstack[stackh++], v, sizeof(*v));
163 f9cd3e06 2021-08-04 op }
164 f9cd3e06 2021-08-04 op
165 f9cd3e06 2021-08-04 op static inline void
166 f9cd3e06 2021-08-04 op pushbool(int n)
167 f9cd3e06 2021-08-04 op {
168 f9cd3e06 2021-08-04 op pushv(n ? &v_true : &v_false);
169 a9e9e3f7 2021-08-07 op }
170 a9e9e3f7 2021-08-07 op
171 a9e9e3f7 2021-08-07 op static inline void
172 a9e9e3f7 2021-08-07 op pushnum(int64_t n)
173 a9e9e3f7 2021-08-07 op {
174 a9e9e3f7 2021-08-07 op struct value v;
175 a9e9e3f7 2021-08-07 op
176 a9e9e3f7 2021-08-07 op v.type = V_NUM;
177 a9e9e3f7 2021-08-07 op v.v.num = n;
178 a9e9e3f7 2021-08-07 op pushv(&v);
179 f9cd3e06 2021-08-04 op }
180 f9cd3e06 2021-08-04 op
181 d9d02161 2021-08-04 op static inline struct opstack *
182 d9d02161 2021-08-04 op pushstack(struct opstacks *stack)
183 d9d02161 2021-08-04 op {
184 d9d02161 2021-08-04 op struct opstack *ops;
185 d9d02161 2021-08-04 op
186 d9d02161 2021-08-04 op ops = xcalloc(1, sizeof(*ops));
187 d9d02161 2021-08-04 op TAILQ_INSERT_HEAD(stack, ops, entry);
188 d9d02161 2021-08-04 op return ops;
189 d9d02161 2021-08-04 op }
190 d9d02161 2021-08-04 op
191 d9d02161 2021-08-04 op static inline struct opstack *
192 d9d02161 2021-08-04 op peek(struct opstacks *stack)
193 d9d02161 2021-08-04 op {
194 d9d02161 2021-08-04 op if (TAILQ_EMPTY(stack))
195 d9d02161 2021-08-04 op errx(1, "%s: args underflow", __func__);
196 d9d02161 2021-08-04 op
197 d9d02161 2021-08-04 op return TAILQ_FIRST(stack);
198 d9d02161 2021-08-04 op }
199 d9d02161 2021-08-04 op
200 d9d02161 2021-08-04 op static inline struct op *
201 d9d02161 2021-08-04 op finalize(struct opstacks *stack, int *argc)
202 d9d02161 2021-08-04 op {
203 d9d02161 2021-08-04 op struct opstack *ops;
204 d9d02161 2021-08-04 op struct op *op;
205 d9d02161 2021-08-04 op
206 d9d02161 2021-08-04 op if (TAILQ_EMPTY(stack))
207 d9d02161 2021-08-04 op errx(1, "%s: args underflow", __func__);
208 d9d02161 2021-08-04 op
209 d9d02161 2021-08-04 op ops = peek(stack);
210 d9d02161 2021-08-04 op TAILQ_REMOVE(&args, ops, entry);
211 d9d02161 2021-08-04 op op = ops->base.next;
212 d9d02161 2021-08-04 op
213 d9d02161 2021-08-04 op if (argc != NULL)
214 d9d02161 2021-08-04 op *argc = ops->counter;
215 d9d02161 2021-08-04 op
216 d9d02161 2021-08-04 op free(ops);
217 d9d02161 2021-08-04 op return op;
218 d9d02161 2021-08-04 op }
219 d9d02161 2021-08-04 op
220 d9d02161 2021-08-04 op static inline void
221 d9d02161 2021-08-04 op push(struct opstacks *stack, struct op *op)
222 d9d02161 2021-08-04 op {
223 d9d02161 2021-08-04 op struct opstack *ops;
224 d9d02161 2021-08-04 op
225 d9d02161 2021-08-04 op ops = peek(stack);
226 d9d02161 2021-08-04 op if (ops->last == NULL) {
227 d9d02161 2021-08-04 op ops->base.next = op;
228 d9d02161 2021-08-04 op ops->last = op;
229 d9d02161 2021-08-04 op } else {
230 d9d02161 2021-08-04 op ops->last->next = op;
231 d9d02161 2021-08-04 op ops->last = op;
232 d9d02161 2021-08-04 op }
233 d9d02161 2021-08-04 op
234 d9d02161 2021-08-04 op ops->counter++;
235 d9d02161 2021-08-04 op }
236 d9d02161 2021-08-04 op
237 f9cd3e06 2021-08-04 op static inline void
238 f9cd3e06 2021-08-04 op pushenv(void)
239 f9cd3e06 2021-08-04 op {
240 f9cd3e06 2021-08-04 op struct env *e;
241 f9cd3e06 2021-08-04 op
242 f9cd3e06 2021-08-04 op e = xcalloc(1, sizeof(*e));
243 f9cd3e06 2021-08-04 op TAILQ_INSERT_HEAD(&envs, e, entry);
244 f9cd3e06 2021-08-04 op }
245 f9cd3e06 2021-08-04 op
246 f9cd3e06 2021-08-04 op static inline struct env *
247 f9cd3e06 2021-08-04 op currentenv(void)
248 f9cd3e06 2021-08-04 op {
249 f9cd3e06 2021-08-04 op assert(!TAILQ_EMPTY(&envs));
250 f9cd3e06 2021-08-04 op return TAILQ_FIRST(&envs);
251 f9cd3e06 2021-08-04 op }
252 f9cd3e06 2021-08-04 op
253 f9cd3e06 2021-08-04 op static void
254 f9cd3e06 2021-08-04 op popenv(void)
255 f9cd3e06 2021-08-04 op {
256 f9cd3e06 2021-08-04 op struct env *e;
257 f9cd3e06 2021-08-04 op struct binding *b, *tb;
258 f9cd3e06 2021-08-04 op
259 f9cd3e06 2021-08-04 op e = currentenv();
260 f9cd3e06 2021-08-04 op TAILQ_REMOVE(&envs, e, entry);
261 f9cd3e06 2021-08-04 op
262 0b3307f1 2021-08-08 op TAILQ_FOREACH_SAFE(b, &e->bindings, entry, tb)
263 f9cd3e06 2021-08-04 op free(b);
264 f9cd3e06 2021-08-04 op
265 f9cd3e06 2021-08-04 op free(e);
266 f9cd3e06 2021-08-04 op }
267 f9cd3e06 2021-08-04 op
268 f9cd3e06 2021-08-04 op static inline int
269 f9cd3e06 2021-08-04 op setvar(char *sym, struct op *op)
270 f9cd3e06 2021-08-04 op {
271 f9cd3e06 2021-08-04 op struct binding *b;
272 f9cd3e06 2021-08-04 op struct env *e;
273 511b3aa7 2021-08-07 op int ret, height;
274 f9cd3e06 2021-08-04 op
275 511b3aa7 2021-08-07 op height = stackh;
276 f9cd3e06 2021-08-04 op if ((ret = eval(op)) != EVAL_OK)
277 f9cd3e06 2021-08-04 op return ret;
278 f9cd3e06 2021-08-04 op
279 511b3aa7 2021-08-07 op if (stackh != height + 1) {
280 511b3aa7 2021-08-07 op before_printing();
281 511b3aa7 2021-08-07 op printf("trying to assign to `%s' a void value: ", sym);
282 511b3aa7 2021-08-07 op pp_op(op);
283 511b3aa7 2021-08-07 op printf("\n");
284 511b3aa7 2021-08-07 op return EVAL_ERR;
285 511b3aa7 2021-08-07 op }
286 511b3aa7 2021-08-07 op
287 f9cd3e06 2021-08-04 op b = xcalloc(1, sizeof(*b));
288 f9cd3e06 2021-08-04 op b->name = sym;
289 f9cd3e06 2021-08-04 op popv(&b->val);
290 f9cd3e06 2021-08-04 op
291 f9cd3e06 2021-08-04 op e = TAILQ_FIRST(&envs);
292 f9cd3e06 2021-08-04 op TAILQ_INSERT_HEAD(&e->bindings, b, entry);
293 f9cd3e06 2021-08-04 op
294 f9cd3e06 2021-08-04 op return EVAL_OK;
295 f9cd3e06 2021-08-04 op }
296 f9cd3e06 2021-08-04 op
297 6eb34747 2021-08-05 op static inline void
298 6eb34747 2021-08-05 op setvar_raw(char *sym, struct op *op)
299 6eb34747 2021-08-05 op {
300 6eb34747 2021-08-05 op struct binding *b;
301 6eb34747 2021-08-05 op struct env *e;
302 6eb34747 2021-08-05 op
303 6eb34747 2021-08-05 op b = xcalloc(1, sizeof(*b));
304 6eb34747 2021-08-05 op b->name = sym;
305 6eb34747 2021-08-05 op b->raw = op;
306 6eb34747 2021-08-05 op
307 6eb34747 2021-08-05 op e = TAILQ_FIRST(&envs);
308 6eb34747 2021-08-05 op TAILQ_INSERT_HEAD(&e->bindings, b, entry);
309 6eb34747 2021-08-05 op }
310 6eb34747 2021-08-05 op
311 f9cd3e06 2021-08-04 op static inline int
312 f9cd3e06 2021-08-04 op getvar(const char *sym, struct value *v)
313 f9cd3e06 2021-08-04 op {
314 f9cd3e06 2021-08-04 op struct env *e;
315 f9cd3e06 2021-08-04 op struct binding *b;
316 f9cd3e06 2021-08-04 op
317 f9cd3e06 2021-08-04 op TAILQ_FOREACH(e, &envs, entry) {
318 f9cd3e06 2021-08-04 op TAILQ_FOREACH(b, &e->bindings, entry) {
319 f9cd3e06 2021-08-04 op if (!strcmp(sym, b->name)) {
320 f9cd3e06 2021-08-04 op memcpy(v, &b->val, sizeof(*v));
321 f9cd3e06 2021-08-04 op return EVAL_OK;
322 f9cd3e06 2021-08-04 op }
323 f9cd3e06 2021-08-04 op }
324 f9cd3e06 2021-08-04 op }
325 f9cd3e06 2021-08-04 op
326 f3289b7e 2021-08-06 op before_printing();
327 f9cd3e06 2021-08-04 op fprintf(stderr, "unbound variable %s\n", sym);
328 f9cd3e06 2021-08-04 op return EVAL_ERR;
329 f9cd3e06 2021-08-04 op }
330 f9cd3e06 2021-08-04 op
331 6eb34747 2021-08-05 op static inline int
332 6eb34747 2021-08-05 op getvar_raw(const char *sym, struct op **raw)
333 6eb34747 2021-08-05 op {
334 6eb34747 2021-08-05 op struct env *e;
335 6eb34747 2021-08-05 op struct binding *b;
336 6eb34747 2021-08-05 op
337 6eb34747 2021-08-05 op TAILQ_FOREACH(e, &envs, entry) {
338 6eb34747 2021-08-05 op TAILQ_FOREACH(b, &e->bindings, entry) {
339 6eb34747 2021-08-05 op if (!strcmp(sym, b->name)) {
340 6eb34747 2021-08-05 op *raw = b->raw;
341 6eb34747 2021-08-05 op return EVAL_OK;
342 6eb34747 2021-08-05 op }
343 6eb34747 2021-08-05 op }
344 6eb34747 2021-08-05 op }
345 6eb34747 2021-08-05 op
346 6eb34747 2021-08-05 op return EVAL_ERR;
347 6eb34747 2021-08-05 op }
348 6eb34747 2021-08-05 op
349 f9cd3e06 2021-08-04 op int
350 c734c0e9 2021-08-03 op global_set(char *sym, struct op *op)
351 c734c0e9 2021-08-03 op {
352 f9cd3e06 2021-08-04 op struct binding *b;
353 f9cd3e06 2021-08-04 op struct env *e;
354 f9cd3e06 2021-08-04 op
355 f9cd3e06 2021-08-04 op /* TODO: check for duplicates */
356 f9cd3e06 2021-08-04 op
357 e599ffc4 2021-08-04 op if (op->type != OP_LITERAL &&
358 e599ffc4 2021-08-04 op (op->type == OP_CAST && op->v.cast.expr->type != OP_LITERAL))
359 f9cd3e06 2021-08-04 op return 0;
360 f9cd3e06 2021-08-04 op
361 f9cd3e06 2021-08-04 op b = xcalloc(1, sizeof(*b));
362 f9cd3e06 2021-08-04 op b->name = sym;
363 e599ffc4 2021-08-04 op
364 e599ffc4 2021-08-04 op /* it's only a cast on a literal! */
365 3a74f37a 2021-08-04 op if (op->type == OP_CAST) {
366 3a74f37a 2021-08-04 op if (eval(op) != EVAL_OK) {
367 3a74f37a 2021-08-04 op free(b);
368 3a74f37a 2021-08-04 op return 0;
369 3a74f37a 2021-08-04 op }
370 3a74f37a 2021-08-04 op popv(&b->val);
371 3a74f37a 2021-08-04 op } else
372 e599ffc4 2021-08-04 op memcpy(&b->val, &op->v.literal, sizeof(b->val));
373 f9cd3e06 2021-08-04 op
374 f9cd3e06 2021-08-04 op e = TAILQ_LAST(&envs, envs);
375 f9cd3e06 2021-08-04 op TAILQ_INSERT_HEAD(&e->bindings, b, entry);
376 f9cd3e06 2021-08-04 op
377 f9cd3e06 2021-08-04 op return 1;
378 c734c0e9 2021-08-03 op }
379 c734c0e9 2021-08-03 op
380 c734c0e9 2021-08-03 op struct op *
381 c734c0e9 2021-08-03 op newop(int type)
382 c734c0e9 2021-08-03 op {
383 c734c0e9 2021-08-03 op struct op *op;
384 c734c0e9 2021-08-03 op
385 f53af81c 2021-08-04 op op = xcalloc(1, sizeof(*op));
386 c734c0e9 2021-08-03 op op->type = type;
387 c734c0e9 2021-08-03 op
388 c734c0e9 2021-08-03 op return op;
389 c734c0e9 2021-08-03 op }
390 c734c0e9 2021-08-03 op
391 c734c0e9 2021-08-03 op void
392 8a2def82 2021-08-12 op free_op_rec(struct op *op)
393 8a2def82 2021-08-12 op {
394 8a2def82 2021-08-12 op struct op *n;
395 8a2def82 2021-08-12 op
396 8a2def82 2021-08-12 op while (op != NULL) {
397 8a2def82 2021-08-12 op n = op->next;
398 8a2def82 2021-08-12 op free_op(op);
399 8a2def82 2021-08-12 op op = n;
400 8a2def82 2021-08-12 op }
401 8a2def82 2021-08-12 op }
402 8a2def82 2021-08-12 op
403 8a2def82 2021-08-12 op void
404 c734c0e9 2021-08-03 op free_op(struct op *op)
405 c734c0e9 2021-08-03 op {
406 8a2def82 2021-08-12 op if (op == NULL)
407 8a2def82 2021-08-12 op return;
408 8a2def82 2021-08-12 op
409 8a2def82 2021-08-12 op switch (op->type) {
410 8a2def82 2021-08-12 op case OP_REST:
411 8a2def82 2021-08-12 op case OP_LITERAL:
412 8a2def82 2021-08-12 op case OP_VARGS:
413 8a2def82 2021-08-12 op break;
414 8a2def82 2021-08-12 op case OP_ASSIGN:
415 8a2def82 2021-08-12 op free(op->v.assign.name);
416 8a2def82 2021-08-12 op free_op_rec(op->v.assign.expr);
417 8a2def82 2021-08-12 op break;
418 8a2def82 2021-08-12 op case OP_ASSERT:
419 8a2def82 2021-08-12 op free_op_rec(op->v.assert);
420 8a2def82 2021-08-12 op break;
421 8a2def82 2021-08-12 op case OP_FUNCALL:
422 8a2def82 2021-08-12 op free_op_rec(op->v.funcall.argv);
423 8a2def82 2021-08-12 op break;
424 8a2def82 2021-08-12 op case OP_VAR:
425 8a2def82 2021-08-12 op free(op->v.var);
426 8a2def82 2021-08-12 op break;
427 8a2def82 2021-08-12 op case OP_CAST:
428 8a2def82 2021-08-12 op free_op_rec(op->v.cast.expr);
429 8a2def82 2021-08-12 op break;
430 8a2def82 2021-08-12 op case OP_CMP_EQ:
431 8a2def82 2021-08-12 op free_op_rec(op->v.cmp_eq.a);
432 8a2def82 2021-08-12 op free_op_rec(op->v.cmp_eq.b);
433 8a2def82 2021-08-12 op break;
434 8a2def82 2021-08-12 op case OP_FACCESS:
435 8a2def82 2021-08-12 op free_op_rec(op->v.faccess.expr);
436 8a2def82 2021-08-12 op free(op->v.faccess.field);
437 8a2def82 2021-08-12 op break;
438 8a2def82 2021-08-12 op case OP_SFAIL:
439 8a2def82 2021-08-12 op free(op->v.sfail.msg);
440 8a2def82 2021-08-12 op free_op_rec(op->v.sfail.expr);
441 8a2def82 2021-08-12 op break;
442 8a2def82 2021-08-12 op default:
443 8a2def82 2021-08-12 op /* unreachable */
444 8a2def82 2021-08-12 op abort();
445 8a2def82 2021-08-12 op }
446 8a2def82 2021-08-12 op
447 c734c0e9 2021-08-03 op free(op);
448 0e62706a 2021-08-04 op }
449 0e62706a 2021-08-04 op
450 0e62706a 2021-08-04 op struct op *
451 0e62706a 2021-08-04 op op_rest(void)
452 0e62706a 2021-08-04 op {
453 0e62706a 2021-08-04 op return newop(OP_REST);
454 c734c0e9 2021-08-03 op }
455 c734c0e9 2021-08-03 op
456 c734c0e9 2021-08-03 op struct op *
457 c734c0e9 2021-08-03 op op_assign(char *sym, struct op *expr)
458 c734c0e9 2021-08-03 op {
459 c734c0e9 2021-08-03 op struct op *op;
460 c734c0e9 2021-08-03 op
461 c734c0e9 2021-08-03 op op = newop(OP_ASSIGN);
462 c734c0e9 2021-08-03 op op->v.assign.name = sym;
463 c734c0e9 2021-08-03 op op->v.assign.expr = expr;
464 c734c0e9 2021-08-03 op
465 c734c0e9 2021-08-03 op return op;
466 c734c0e9 2021-08-03 op }
467 c734c0e9 2021-08-03 op
468 c734c0e9 2021-08-03 op struct op *
469 c734c0e9 2021-08-03 op op_assert(struct op *expr)
470 c734c0e9 2021-08-03 op {
471 c734c0e9 2021-08-03 op struct op *op;
472 c734c0e9 2021-08-03 op
473 c734c0e9 2021-08-03 op op = newop(OP_ASSERT);
474 c734c0e9 2021-08-03 op op->v.assert = expr;
475 c734c0e9 2021-08-03 op
476 c734c0e9 2021-08-03 op return op;
477 c734c0e9 2021-08-03 op }
478 c734c0e9 2021-08-03 op
479 c734c0e9 2021-08-03 op struct op *
480 c734c0e9 2021-08-03 op op_var(char *sym)
481 c734c0e9 2021-08-03 op {
482 c734c0e9 2021-08-03 op struct op *op;
483 c734c0e9 2021-08-03 op
484 c734c0e9 2021-08-03 op op = newop(OP_VAR);
485 c734c0e9 2021-08-03 op op->v.var = sym;
486 c734c0e9 2021-08-03 op
487 c734c0e9 2021-08-03 op return op;
488 c734c0e9 2021-08-03 op }
489 c734c0e9 2021-08-03 op
490 c734c0e9 2021-08-03 op struct op *
491 c734c0e9 2021-08-03 op op_lit_str(char *str)
492 c734c0e9 2021-08-03 op {
493 c734c0e9 2021-08-03 op struct op *op;
494 c734c0e9 2021-08-03 op
495 c734c0e9 2021-08-03 op op = newop(OP_LITERAL);
496 dcb493d2 2021-08-04 op op->v.literal.type = V_STR;
497 c734c0e9 2021-08-03 op op->v.literal.v.str = str;
498 c734c0e9 2021-08-03 op
499 c734c0e9 2021-08-03 op return op;
500 c734c0e9 2021-08-03 op }
501 c734c0e9 2021-08-03 op
502 c734c0e9 2021-08-03 op struct op *
503 c734c0e9 2021-08-03 op op_lit_num(uint64_t n)
504 c734c0e9 2021-08-03 op {
505 c734c0e9 2021-08-03 op struct op *op;
506 c734c0e9 2021-08-03 op
507 c734c0e9 2021-08-03 op op = newop(OP_LITERAL);
508 c734c0e9 2021-08-03 op op->v.literal.type = V_NUM;
509 c734c0e9 2021-08-03 op op->v.literal.v.num = n;
510 c734c0e9 2021-08-03 op
511 c734c0e9 2021-08-03 op return op;
512 c734c0e9 2021-08-03 op }
513 c734c0e9 2021-08-03 op
514 c734c0e9 2021-08-03 op struct op *
515 c734c0e9 2021-08-03 op op_cmp_eq(struct op *a, struct op *b)
516 c734c0e9 2021-08-03 op {
517 c734c0e9 2021-08-03 op struct op *op;
518 c734c0e9 2021-08-03 op
519 c734c0e9 2021-08-03 op op = newop(OP_CMP_EQ);
520 c734c0e9 2021-08-03 op op->v.cmp_eq.a = a;
521 c734c0e9 2021-08-03 op op->v.cmp_eq.b = b;
522 c734c0e9 2021-08-03 op
523 c734c0e9 2021-08-03 op return op;
524 c734c0e9 2021-08-03 op }
525 c734c0e9 2021-08-03 op
526 c734c0e9 2021-08-03 op struct op *
527 c734c0e9 2021-08-03 op op_cast(struct op *expr, int totype)
528 c734c0e9 2021-08-03 op {
529 c734c0e9 2021-08-03 op struct op *op;
530 c734c0e9 2021-08-03 op
531 c734c0e9 2021-08-03 op op = newop(OP_CAST);
532 c734c0e9 2021-08-03 op op->v.cast.expr = expr;
533 c734c0e9 2021-08-03 op op->v.cast.totype = totype;
534 acf1403a 2021-08-05 op
535 acf1403a 2021-08-05 op return op;
536 acf1403a 2021-08-05 op }
537 acf1403a 2021-08-05 op
538 acf1403a 2021-08-05 op struct op *
539 acf1403a 2021-08-05 op op_faccess(struct op *expr, char *field)
540 acf1403a 2021-08-05 op {
541 acf1403a 2021-08-05 op struct op *op;
542 acf1403a 2021-08-05 op
543 acf1403a 2021-08-05 op op = newop(OP_FACCESS);
544 acf1403a 2021-08-05 op op->v.faccess.expr = expr;
545 acf1403a 2021-08-05 op op->v.faccess.field = field;
546 c734c0e9 2021-08-03 op
547 c734c0e9 2021-08-03 op return op;
548 c734c0e9 2021-08-03 op }
549 8250ab19 2021-08-07 op
550 8250ab19 2021-08-07 op struct op *
551 8250ab19 2021-08-07 op op_sfail(struct op *expr, char *msg)
552 8250ab19 2021-08-07 op {
553 8250ab19 2021-08-07 op struct op *op;
554 c734c0e9 2021-08-03 op
555 8250ab19 2021-08-07 op op = newop(OP_SFAIL);
556 8250ab19 2021-08-07 op op->v.sfail.expr = expr;
557 8250ab19 2021-08-07 op op->v.sfail.msg = msg;
558 a9e9e3f7 2021-08-07 op
559 a9e9e3f7 2021-08-07 op return op;
560 a9e9e3f7 2021-08-07 op }
561 a9e9e3f7 2021-08-07 op
562 a9e9e3f7 2021-08-07 op struct op *
563 a9e9e3f7 2021-08-07 op op_vargs(void)
564 a9e9e3f7 2021-08-07 op {
565 a9e9e3f7 2021-08-07 op struct op *op;
566 8250ab19 2021-08-07 op
567 a9e9e3f7 2021-08-07 op op = newop(OP_VARGS);
568 a9e9e3f7 2021-08-07 op
569 8250ab19 2021-08-07 op return op;
570 8250ab19 2021-08-07 op }
571 8250ab19 2021-08-07 op
572 c734c0e9 2021-08-03 op void
573 da4de0c1 2021-08-04 op ppf_val(FILE *f, struct value *val)
574 c734c0e9 2021-08-03 op {
575 9820edbf 2021-08-06 op size_t i;
576 9820edbf 2021-08-06 op
577 c734c0e9 2021-08-03 op switch (val->type) {
578 c734c0e9 2021-08-03 op case V_SYM:
579 da4de0c1 2021-08-04 op fprintf(f, "%s", val->v.str);
580 c734c0e9 2021-08-03 op break;
581 c734c0e9 2021-08-03 op case V_STR:
582 da4de0c1 2021-08-04 op fprintf(f, "\"%s\"", val->v.str);
583 c734c0e9 2021-08-03 op break;
584 c734c0e9 2021-08-03 op case V_NUM:
585 ae3939af 2021-08-04 op fprintf(f, "%"PRIi64, val->v.num);
586 ae3939af 2021-08-04 op break;
587 c734c0e9 2021-08-03 op case V_U8:
588 ae3939af 2021-08-04 op fprintf(f, "%"PRIu8, val->v.u8);
589 ae3939af 2021-08-04 op break;
590 c734c0e9 2021-08-03 op case V_U16:
591 ae3939af 2021-08-04 op fprintf(f, "%"PRIu16, val->v.u16);
592 ae3939af 2021-08-04 op break;
593 c734c0e9 2021-08-03 op case V_U32:
594 ae3939af 2021-08-04 op fprintf(f, "%"PRIu32, val->v.u32);
595 9820edbf 2021-08-06 op break;
596 9820edbf 2021-08-06 op case V_MSG:
597 9820edbf 2021-08-06 op fprintf(f, "(");
598 9820edbf 2021-08-06 op for (i = 0; i < val->v.msg.len; ++i)
599 9820edbf 2021-08-06 op fprintf(f, "%x%s", val->v.msg.msg[i],
600 9820edbf 2021-08-06 op i == val->v.msg.len-1 ? "" : " ");
601 9820edbf 2021-08-06 op fprintf(f, ")");
602 c734c0e9 2021-08-03 op break;
603 983e73a6 2021-08-08 op case V_QIDVEC:
604 983e73a6 2021-08-08 op fprintf(f, "qids[n=%zu]", val->v.qidvec.len);
605 983e73a6 2021-08-08 op break;
606 c734c0e9 2021-08-03 op default:
607 da4de0c1 2021-08-04 op fprintf(f, "<unknown value>");
608 c734c0e9 2021-08-03 op break;
609 c734c0e9 2021-08-03 op }
610 c734c0e9 2021-08-03 op }
611 c734c0e9 2021-08-03 op
612 da4de0c1 2021-08-04 op void
613 da4de0c1 2021-08-04 op pp_val(struct value *val)
614 da4de0c1 2021-08-04 op {
615 da4de0c1 2021-08-04 op ppf_val(stdout, val);
616 da4de0c1 2021-08-04 op }
617 da4de0c1 2021-08-04 op
618 47c583a9 2021-08-07 op const char *
619 47c583a9 2021-08-07 op val_type(struct value *v)
620 47c583a9 2021-08-07 op {
621 47c583a9 2021-08-07 op switch (v->type) {
622 47c583a9 2021-08-07 op case V_SYM: return "symbol";
623 47c583a9 2021-08-07 op case V_STR: return "string";
624 47c583a9 2021-08-07 op case V_NUM: return "number";
625 47c583a9 2021-08-07 op case V_MSG: return "message";
626 47c583a9 2021-08-07 op case V_QID: return "qid";
627 47c583a9 2021-08-07 op case V_U8: return "u8";
628 47c583a9 2021-08-07 op case V_U16: return "u16";
629 47c583a9 2021-08-07 op case V_U32: return "u32";
630 47c583a9 2021-08-07 op default: return "unknown";
631 47c583a9 2021-08-07 op }
632 47c583a9 2021-08-07 op }
633 47c583a9 2021-08-07 op
634 c734c0e9 2021-08-03 op int
635 c734c0e9 2021-08-03 op val_trueish(struct value *a)
636 c734c0e9 2021-08-03 op {
637 8ec0e863 2021-12-02 op if (val_isnum(a))
638 8ec0e863 2021-12-02 op return val_tonum(a);
639 8ec0e863 2021-12-02 op return 1;
640 c734c0e9 2021-08-03 op }
641 c734c0e9 2021-08-03 op
642 7a495cc0 2021-12-02 op int
643 c734c0e9 2021-08-03 op val_isnum(struct value *a)
644 c734c0e9 2021-08-03 op {
645 c734c0e9 2021-08-03 op return a->type == V_NUM
646 c734c0e9 2021-08-03 op || a->type == V_U8
647 c734c0e9 2021-08-03 op || a->type == V_U16
648 c734c0e9 2021-08-03 op || a->type == V_U32;
649 309658f3 2021-08-04 op }
650 309658f3 2021-08-04 op
651 7a495cc0 2021-12-02 op int64_t
652 309658f3 2021-08-04 op val_tonum(struct value *a)
653 309658f3 2021-08-04 op {
654 309658f3 2021-08-04 op switch (a->type) {
655 309658f3 2021-08-04 op case V_NUM: return a->v.num;
656 309658f3 2021-08-04 op case V_U8: return a->v.u8;
657 309658f3 2021-08-04 op case V_U16: return a->v.u16;
658 309658f3 2021-08-04 op case V_U32: return a->v.u32;
659 309658f3 2021-08-04 op default:
660 f3289b7e 2021-08-06 op before_printing();
661 309658f3 2021-08-04 op fprintf(stderr, "%s: given value is not a number\n", __func__);
662 309658f3 2021-08-04 op abort();
663 309658f3 2021-08-04 op }
664 c734c0e9 2021-08-03 op }
665 c734c0e9 2021-08-03 op
666 c734c0e9 2021-08-03 op int
667 c734c0e9 2021-08-03 op val_eq(struct value *a, struct value *b)
668 c734c0e9 2021-08-03 op {
669 c734c0e9 2021-08-03 op if (val_isnum(a) && val_isnum(b))
670 309658f3 2021-08-04 op return val_tonum(a) == val_tonum(b);
671 c734c0e9 2021-08-03 op
672 c734c0e9 2021-08-03 op if (a->type != b->type)
673 c734c0e9 2021-08-03 op return 0;
674 c734c0e9 2021-08-03 op
675 c734c0e9 2021-08-03 op switch (a->type) {
676 c734c0e9 2021-08-03 op case V_STR:
677 c734c0e9 2021-08-03 op case V_SYM:
678 c734c0e9 2021-08-03 op return !strcmp(a->v.str, b->v.str);
679 c734c0e9 2021-08-03 op }
680 c734c0e9 2021-08-03 op
681 c734c0e9 2021-08-03 op return 0;
682 da4de0c1 2021-08-04 op }
683 da4de0c1 2021-08-04 op
684 da4de0c1 2021-08-04 op static inline const char *
685 da4de0c1 2021-08-04 op pp_totype(int totype)
686 da4de0c1 2021-08-04 op {
687 da4de0c1 2021-08-04 op /*
688 da4de0c1 2021-08-04 op * Not all of these are valid cast type thought, including
689 da4de0c1 2021-08-04 op * every possibility only to aid debugging.
690 da4de0c1 2021-08-04 op */
691 da4de0c1 2021-08-04 op switch (totype) {
692 da4de0c1 2021-08-04 op case V_STR: return "str";
693 da4de0c1 2021-08-04 op case V_SYM: return "sym";
694 da4de0c1 2021-08-04 op case V_NUM: return "num";
695 da4de0c1 2021-08-04 op case V_QID: return "qid";
696 da4de0c1 2021-08-04 op case V_U8: return "u8";
697 da4de0c1 2021-08-04 op case V_U16: return "u16";
698 da4de0c1 2021-08-04 op case V_U32: return "u32";
699 da4de0c1 2021-08-04 op default: return "unknown";
700 da4de0c1 2021-08-04 op }
701 da4de0c1 2021-08-04 op }
702 da4de0c1 2021-08-04 op
703 da4de0c1 2021-08-04 op int
704 da4de0c1 2021-08-04 op val_cast(struct value *a, int totype)
705 da4de0c1 2021-08-04 op {
706 ae3939af 2021-08-04 op int64_t v;
707 da4de0c1 2021-08-04 op
708 ae3939af 2021-08-04 op #define NUMCAST(val, t, c, totype, max) do { \
709 ae3939af 2021-08-04 op if (val > max) { \
710 f3289b7e 2021-08-06 op before_printing(); \
711 ae3939af 2021-08-04 op fprintf(stderr, "can't cast %"PRIu64 \
712 ae3939af 2021-08-04 op " to %s\n", val, pp_totype(totype)); \
713 ae3939af 2021-08-04 op return EVAL_ERR; \
714 ae3939af 2021-08-04 op } \
715 ae3939af 2021-08-04 op a->type = totype; \
716 ae3939af 2021-08-04 op a->v.t = (c)val; \
717 ae3939af 2021-08-04 op return EVAL_OK; \
718 da4de0c1 2021-08-04 op } while (0)
719 da4de0c1 2021-08-04 op
720 652f7308 2021-08-07 op if (a->type == totype)
721 652f7308 2021-08-07 op return EVAL_OK;
722 652f7308 2021-08-07 op
723 da4de0c1 2021-08-04 op if (!val_isnum(a)) {
724 f3289b7e 2021-08-06 op before_printing();
725 04a9c38f 2021-08-04 op fprintf(stderr, "can't cast ");
726 da4de0c1 2021-08-04 op ppf_val(stderr, a);
727 da4de0c1 2021-08-04 op fprintf(stderr, " to type %s\n", pp_totype(totype));
728 da4de0c1 2021-08-04 op return EVAL_ERR;
729 da4de0c1 2021-08-04 op }
730 da4de0c1 2021-08-04 op
731 da4de0c1 2021-08-04 op v = a->v.num;
732 da4de0c1 2021-08-04 op switch (totype) {
733 ae3939af 2021-08-04 op case V_U8: NUMCAST(v, u8, uint8_t, totype, UINT8_MAX);
734 ae3939af 2021-08-04 op case V_U16: NUMCAST(v, u16, uint16_t, totype, UINT16_MAX);
735 ae3939af 2021-08-04 op case V_U32: NUMCAST(v, u32, uint32_t, totype, UINT32_MAX);
736 da4de0c1 2021-08-04 op default:
737 f3289b7e 2021-08-06 op before_printing();
738 04a9c38f 2021-08-04 op fprintf(stderr, "can't cast %"PRIu64" to %s\n",
739 da4de0c1 2021-08-04 op v, pp_totype(totype));
740 da4de0c1 2021-08-04 op return EVAL_ERR;
741 da4de0c1 2021-08-04 op }
742 da4de0c1 2021-08-04 op
743 da4de0c1 2021-08-04 op #undef NUMCAST
744 acf1403a 2021-08-05 op }
745 acf1403a 2021-08-05 op
746 acf1403a 2021-08-05 op int
747 acf1403a 2021-08-05 op val_faccess(struct value *a, const char *field, struct value *ret)
748 acf1403a 2021-08-05 op {
749 983e73a6 2021-08-08 op uint8_t mtype;
750 983e73a6 2021-08-08 op uint16_t len;
751 983e73a6 2021-08-08 op const char *errstr;
752 d8d5d55f 2021-08-07 op
753 d8d5d55f 2021-08-07 op #define MSGTYPE(m) *(m.msg + 4) /* skip the length */
754 d8d5d55f 2021-08-07 op
755 acf1403a 2021-08-05 op switch (a->type) {
756 acf1403a 2021-08-05 op case V_QID:
757 acf1403a 2021-08-05 op /* TODO: add path. needs uint64_t values thought! */
758 acf1403a 2021-08-05 op if (!strcmp(field, "vers")) {
759 acf1403a 2021-08-05 op ret->type = V_U32;
760 acf1403a 2021-08-05 op memcpy(&ret->v.u32, a->v.qid+1, 4);
761 47c583a9 2021-08-07 op return EVAL_OK;
762 acf1403a 2021-08-05 op } else if (!strcmp(field, "type")) {
763 acf1403a 2021-08-05 op ret->type = V_U8;
764 acf1403a 2021-08-05 op ret->v.u8 = *a->v.qid;
765 47c583a9 2021-08-07 op return EVAL_OK;
766 47c583a9 2021-08-07 op }
767 acf1403a 2021-08-05 op break;
768 d8d5d55f 2021-08-07 op
769 d1355133 2021-08-07 op case V_MSG:
770 a4273600 2021-08-07 op mtype = MSGTYPE(a->v.msg);
771 d1355133 2021-08-07 op if (!strcmp(field, "type")) {
772 d1355133 2021-08-07 op ret->type = V_U8;
773 d8d5d55f 2021-08-07 op ret->v.u8 = MSGTYPE(a->v.msg);
774 47c583a9 2021-08-07 op return EVAL_OK;
775 2cb7d94c 2021-08-07 op } else if (!strcmp(field, "tag")) {
776 2cb7d94c 2021-08-07 op ret->type = V_U16;
777 2cb7d94c 2021-08-07 op memcpy(&ret->v.u16, &a->v.msg.msg[5], 2);
778 2cb7d94c 2021-08-07 op ret->v.u16 = le16toh(ret->v.u16);
779 d8d5d55f 2021-08-07 op return EVAL_OK;
780 a4273600 2021-08-07 op } else if (!strcmp(field, "msize") && mtype == Rversion) {
781 d8d5d55f 2021-08-07 op ret->type = V_U32;
782 d8d5d55f 2021-08-07 op memcpy(&ret->v.u32, &a->v.msg.msg[7], 4);
783 d8d5d55f 2021-08-07 op ret->v.u32 = le32toh(ret->v.u32);
784 2cb7d94c 2021-08-07 op return EVAL_OK;
785 a4273600 2021-08-07 op } else if (!strcmp(field, "qid") && mtype == Rattach) {
786 a4273600 2021-08-07 op ret->type = V_QID;
787 a4273600 2021-08-07 op memcpy(&ret->v.qid, &a->v.msg.msg[7], QIDSIZE);
788 983e73a6 2021-08-08 op return EVAL_OK;
789 983e73a6 2021-08-08 op } else if (!strcmp(field, "nwqid") && mtype == Rwalk) {
790 983e73a6 2021-08-08 op ret->type = V_U16;
791 983e73a6 2021-08-08 op memcpy(&ret->v.u16, &a->v.msg.msg[7], 2);
792 983e73a6 2021-08-08 op ret->v.u16 = le16toh(ret->v.u16);
793 a4273600 2021-08-07 op return EVAL_OK;
794 983e73a6 2021-08-08 op } else if (!strcmp(field, "wqid") && mtype == Rwalk) {
795 983e73a6 2021-08-08 op ret->type = V_QIDVEC;
796 983e73a6 2021-08-08 op ret->v.qidvec.start = &a->v.msg.msg[9];
797 983e73a6 2021-08-08 op memcpy(&len, &a->v.msg.msg[7], 2);
798 983e73a6 2021-08-08 op len = le16toh(len);
799 983e73a6 2021-08-08 op ret->v.qidvec.len = len;
800 983e73a6 2021-08-08 op return EVAL_OK;
801 47c583a9 2021-08-07 op }
802 d1355133 2021-08-07 op break;
803 983e73a6 2021-08-08 op
804 983e73a6 2021-08-08 op case V_QIDVEC:
805 983e73a6 2021-08-08 op len = strtonum(field, 0, MAXWELEM, &errstr);
806 983e73a6 2021-08-08 op if (errstr != NULL) {
807 983e73a6 2021-08-08 op before_printing();
808 983e73a6 2021-08-08 op printf("can't access qid #%s: %s\n", field, errstr);
809 983e73a6 2021-08-08 op return EVAL_ERR;
810 983e73a6 2021-08-08 op }
811 d8d5d55f 2021-08-07 op
812 983e73a6 2021-08-08 op if (len >= a->v.qidvec.len) {
813 983e73a6 2021-08-08 op before_printing();
814 983e73a6 2021-08-08 op printf("can't access qid #%d: out-of-bound "
815 983e73a6 2021-08-08 op "(max %zu)\n", len, a->v.qidvec.len);
816 983e73a6 2021-08-08 op return EVAL_ERR;
817 983e73a6 2021-08-08 op }
818 983e73a6 2021-08-08 op
819 983e73a6 2021-08-08 op ret->type = V_QID;
820 983e73a6 2021-08-08 op memcpy(&ret->v.qid, a->v.qidvec.start + len * QIDSIZE,
821 983e73a6 2021-08-08 op QIDSIZE);
822 983e73a6 2021-08-08 op
823 983e73a6 2021-08-08 op return EVAL_OK;
824 983e73a6 2021-08-08 op
825 acf1403a 2021-08-05 op default:
826 47c583a9 2021-08-07 op break;
827 acf1403a 2021-08-05 op }
828 acf1403a 2021-08-05 op
829 47c583a9 2021-08-07 op before_printing();
830 47c583a9 2021-08-07 op printf("can't access field `%s' on type %s (", field, val_type(a));
831 47c583a9 2021-08-07 op pp_val(a);
832 47c583a9 2021-08-07 op printf(")\n");
833 47c583a9 2021-08-07 op return EVAL_ERR;
834 d8d5d55f 2021-08-07 op
835 d8d5d55f 2021-08-07 op #undef MSGTYPE
836 c734c0e9 2021-08-03 op }
837 c734c0e9 2021-08-03 op
838 c734c0e9 2021-08-03 op void
839 c734c0e9 2021-08-03 op pp_op(struct op *op)
840 c734c0e9 2021-08-03 op {
841 3e23847c 2021-08-04 op struct op *aux;
842 3e23847c 2021-08-04 op
843 c734c0e9 2021-08-03 op switch (op->type) {
844 0e62706a 2021-08-04 op case OP_REST:
845 0e62706a 2021-08-04 op printf("...");
846 0e62706a 2021-08-04 op break;
847 c734c0e9 2021-08-03 op case OP_ASSIGN:
848 c734c0e9 2021-08-03 op printf("%s = ", op->v.assign.name);
849 c734c0e9 2021-08-03 op pp_op(op->v.assign.expr);
850 c734c0e9 2021-08-03 op break;
851 c734c0e9 2021-08-03 op case OP_ASSERT:
852 c734c0e9 2021-08-03 op printf("assert ");
853 c734c0e9 2021-08-03 op pp_op(op->v.assert);
854 c734c0e9 2021-08-03 op break;
855 c734c0e9 2021-08-03 op case OP_FUNCALL:
856 3e23847c 2021-08-04 op printf("funcall %s(", op->v.funcall.proc->name);
857 3e23847c 2021-08-04 op for (aux = op->v.funcall.argv; aux != NULL; aux = aux->next) {
858 3e23847c 2021-08-04 op pp_op(aux);
859 3e23847c 2021-08-04 op if (aux->next != NULL)
860 3e23847c 2021-08-04 op printf(", ");
861 3e23847c 2021-08-04 op }
862 3e23847c 2021-08-04 op printf(")");
863 c734c0e9 2021-08-03 op break;
864 c734c0e9 2021-08-03 op case OP_LITERAL:
865 c734c0e9 2021-08-03 op pp_val(&op->v.literal);
866 c734c0e9 2021-08-03 op break;
867 c734c0e9 2021-08-03 op case OP_VAR:
868 c734c0e9 2021-08-03 op printf("%s", op->v.var);
869 c734c0e9 2021-08-03 op break;
870 c734c0e9 2021-08-03 op case OP_CAST:
871 c734c0e9 2021-08-03 op pp_op(op->v.cast.expr);
872 c734c0e9 2021-08-03 op printf(":");
873 c734c0e9 2021-08-03 op switch (op->v.cast.totype) {
874 c734c0e9 2021-08-03 op case V_U8: printf("u8"); break;
875 c734c0e9 2021-08-03 op case V_U16: printf("u16"); break;
876 c734c0e9 2021-08-03 op case V_U32: printf("u32"); break;
877 c734c0e9 2021-08-03 op case V_STR: printf("str"); break;
878 c734c0e9 2021-08-03 op default: printf("???"); break;
879 c734c0e9 2021-08-03 op }
880 c734c0e9 2021-08-03 op break;
881 c734c0e9 2021-08-03 op case OP_CMP_EQ:
882 c734c0e9 2021-08-03 op pp_op(op->v.cmp_eq.a);
883 c734c0e9 2021-08-03 op printf(" == ");
884 c734c0e9 2021-08-03 op pp_op(op->v.cmp_eq.b);
885 c734c0e9 2021-08-03 op break;
886 acf1403a 2021-08-05 op case OP_FACCESS:
887 acf1403a 2021-08-05 op pp_op(op->v.faccess.expr);
888 acf1403a 2021-08-05 op printf(".%s", op->v.faccess.field);
889 8250ab19 2021-08-07 op break;
890 8250ab19 2021-08-07 op case OP_SFAIL:
891 8250ab19 2021-08-07 op printf("should-fail ");
892 8250ab19 2021-08-07 op pp_op(op->v.sfail.expr);
893 8250ab19 2021-08-07 op if (op->v.sfail.msg != NULL)
894 8250ab19 2021-08-07 op printf(": \"%s\"", op->v.sfail.msg);
895 acf1403a 2021-08-05 op break;
896 a9e9e3f7 2021-08-07 op case OP_VARGS:
897 a9e9e3f7 2021-08-07 op printf("vargs");
898 a9e9e3f7 2021-08-07 op break;
899 c734c0e9 2021-08-03 op default:
900 c734c0e9 2021-08-03 op printf(" ???[%d] ", op->type);
901 c734c0e9 2021-08-03 op }
902 c734c0e9 2021-08-03 op }
903 c734c0e9 2021-08-03 op
904 c734c0e9 2021-08-03 op void
905 c734c0e9 2021-08-03 op pp_block(struct op *op)
906 c734c0e9 2021-08-03 op {
907 c734c0e9 2021-08-03 op while (op != NULL) {
908 c734c0e9 2021-08-03 op printf("> ");
909 c734c0e9 2021-08-03 op pp_op(op);
910 c734c0e9 2021-08-03 op printf("\n");
911 c734c0e9 2021-08-03 op
912 c734c0e9 2021-08-03 op op = op->next;
913 c734c0e9 2021-08-03 op }
914 c734c0e9 2021-08-03 op }
915 c734c0e9 2021-08-03 op
916 c734c0e9 2021-08-03 op int
917 c734c0e9 2021-08-03 op eval(struct op *op)
918 c734c0e9 2021-08-03 op {
919 c734c0e9 2021-08-03 op struct value a, b;
920 c734c0e9 2021-08-03 op struct proc *proc;
921 29c35556 2021-08-07 op struct op *t, *tnext;
922 c734c0e9 2021-08-03 op int i, ret;
923 c734c0e9 2021-08-03 op
924 c734c0e9 2021-08-03 op #if DEBUG
925 4c5e4e23 2021-08-06 op pp_op(op);
926 c734c0e9 2021-08-03 op printf("\n");
927 c734c0e9 2021-08-03 op #endif
928 c734c0e9 2021-08-03 op
929 c734c0e9 2021-08-03 op switch (op->type) {
930 6eb34747 2021-08-05 op case OP_REST:
931 c31f55f5 2021-08-07 op /*
932 c31f55f5 2021-08-07 op * Try to load the rest argument. Note that it can be
933 c31f55f5 2021-08-07 op * empty!
934 c31f55f5 2021-08-07 op */
935 c31f55f5 2021-08-07 op if ((ret = getvar_raw("...", &t)) == EVAL_OK)
936 c31f55f5 2021-08-07 op if ((ret = eval(t)) != EVAL_OK)
937 c31f55f5 2021-08-07 op return ret;
938 6eb34747 2021-08-05 op break;
939 6eb34747 2021-08-05 op
940 c734c0e9 2021-08-03 op case OP_ASSIGN:
941 f9cd3e06 2021-08-04 op ret = setvar(op->v.assign.name, op->v.assign.expr);
942 f9cd3e06 2021-08-04 op if (ret != EVAL_OK)
943 f9cd3e06 2021-08-04 op return ret;
944 c734c0e9 2021-08-03 op break;
945 c734c0e9 2021-08-03 op
946 c734c0e9 2021-08-03 op case OP_ASSERT:
947 333d8d7d 2021-08-04 op if ((ret = eval(op->v.assert)) != EVAL_OK)
948 c734c0e9 2021-08-03 op return ret;
949 c734c0e9 2021-08-03 op popv(&a);
950 c734c0e9 2021-08-03 op if (!val_trueish(&a)) {
951 f3289b7e 2021-08-06 op before_printing();
952 c734c0e9 2021-08-03 op printf("assertion failed: ");
953 c734c0e9 2021-08-03 op pp_op(op->v.assert);
954 c734c0e9 2021-08-03 op printf("\n");
955 333d8d7d 2021-08-04 op return EVAL_ERR;
956 c734c0e9 2021-08-03 op }
957 c734c0e9 2021-08-03 op break;
958 c734c0e9 2021-08-03 op
959 c734c0e9 2021-08-03 op case OP_FUNCALL:
960 349fd94e 2021-08-05 op /* assume airity matches */
961 f9cd3e06 2021-08-04 op
962 f9cd3e06 2021-08-04 op proc = op->v.funcall.proc;
963 9af2cde2 2021-08-04 op if (proc->nativefn != NULL) {
964 6eb34747 2021-08-05 op /*
965 6eb34747 2021-08-05 op * Push arguments on the stack for builtin
966 6eb34747 2021-08-05 op * functions. Counting the height of the
967 6eb34747 2021-08-05 op * stack is done to compute the correct number
968 6eb34747 2021-08-05 op * in the vararg case. argc only counts the
969 6eb34747 2021-08-05 op * "syntactical" arguments, i.e. foo(x, ...)
970 6eb34747 2021-08-05 op * has argc == 2, but at runtime argc may be
971 6eb34747 2021-08-05 op * 1, 2 or a greater number!
972 6eb34747 2021-08-05 op */
973 6eb34747 2021-08-05 op
974 6eb34747 2021-08-05 op i = stackh;
975 219cbeaa 2021-08-04 op t = op->v.funcall.argv;
976 219cbeaa 2021-08-04 op if (t != NULL && (ret = eval(t)) != EVAL_OK)
977 219cbeaa 2021-08-04 op return ret;
978 6eb34747 2021-08-05 op i = stackh - i;
979 6eb34747 2021-08-05 op
980 6eb34747 2021-08-05 op assert(i >= 0);
981 6eb34747 2021-08-05 op
982 6eb34747 2021-08-05 op if ((ret = proc->nativefn(i))
983 9af2cde2 2021-08-04 op != EVAL_OK)
984 c734c0e9 2021-08-03 op return ret;
985 9af2cde2 2021-08-04 op } else {
986 91cfe5ca 2021-08-06 op if (proc->body == NULL) {
987 91cfe5ca 2021-08-06 op before_printing();
988 91cfe5ca 2021-08-06 op printf("warn: calling the empty proc `%s'\n",
989 91cfe5ca 2021-08-06 op proc->name);
990 91cfe5ca 2021-08-06 op break;
991 91cfe5ca 2021-08-06 op }
992 91cfe5ca 2021-08-06 op
993 9af2cde2 2021-08-04 op pushenv();
994 9af2cde2 2021-08-04 op
995 219cbeaa 2021-08-04 op for (t = op->v.funcall.argv, i = 0;
996 219cbeaa 2021-08-04 op t != NULL;
997 219cbeaa 2021-08-04 op t = t->next, i++) {
998 6eb34747 2021-08-05 op /*
999 6eb34747 2021-08-05 op * Push a pseudo variable `...' (and
1000 6eb34747 2021-08-05 op * don't evaluate it) in the vararg
1001 6eb34747 2021-08-05 op * case. A special case is when the
1002 6eb34747 2021-08-05 op * variable is itself `...'.
1003 6eb34747 2021-08-05 op */
1004 6eb34747 2021-08-05 op if (proc->vararg && i == proc->minargs) {
1005 6eb34747 2021-08-05 op if (t->type != OP_REST)
1006 6eb34747 2021-08-05 op setvar_raw(xstrdup("..."), t);
1007 6eb34747 2021-08-05 op break;
1008 6eb34747 2021-08-05 op }
1009 6eb34747 2021-08-05 op
1010 29c35556 2021-08-07 op /*
1011 29c35556 2021-08-07 op * The arguments are a linked list of
1012 29c35556 2021-08-07 op * ops. Setvar will call eval that
1013 29c35556 2021-08-07 op * will evaluate *all* the arguments.
1014 29c35556 2021-08-07 op * The dance here that sets next to
1015 29c35556 2021-08-07 op * NULL and then restores it is to
1016 29c35556 2021-08-07 op * avoid this behaviour.
1017 29c35556 2021-08-07 op */
1018 29c35556 2021-08-07 op tnext = t->next;
1019 29c35556 2021-08-07 op t->next = NULL;
1020 29c35556 2021-08-07 op ret = setvar(proc->args[i], t);
1021 29c35556 2021-08-07 op t->next = tnext;
1022 29c35556 2021-08-07 op
1023 29c35556 2021-08-07 op if (ret != EVAL_OK)
1024 9af2cde2 2021-08-04 op return ret;
1025 9af2cde2 2021-08-04 op }
1026 9af2cde2 2021-08-04 op
1027 9af2cde2 2021-08-04 op if ((ret = eval(proc->body)) != EVAL_OK)
1028 c734c0e9 2021-08-03 op return ret;
1029 f9cd3e06 2021-08-04 op
1030 9af2cde2 2021-08-04 op popenv();
1031 9af2cde2 2021-08-04 op }
1032 9af2cde2 2021-08-04 op
1033 c734c0e9 2021-08-03 op break;
1034 c734c0e9 2021-08-03 op
1035 c734c0e9 2021-08-03 op case OP_LITERAL:
1036 c734c0e9 2021-08-03 op pushv(&op->v.literal);
1037 c734c0e9 2021-08-03 op break;
1038 c734c0e9 2021-08-03 op
1039 c734c0e9 2021-08-03 op case OP_VAR:
1040 f9cd3e06 2021-08-04 op if ((ret = getvar(op->v.var, &a)) != EVAL_OK)
1041 f9cd3e06 2021-08-04 op return ret;
1042 f9cd3e06 2021-08-04 op pushv(&a);
1043 c734c0e9 2021-08-03 op break;
1044 c734c0e9 2021-08-03 op
1045 c734c0e9 2021-08-03 op case OP_CAST:
1046 da4de0c1 2021-08-04 op if ((ret = eval(op->v.cast.expr)) != EVAL_OK)
1047 da4de0c1 2021-08-04 op return ret;
1048 da4de0c1 2021-08-04 op popv(&a);
1049 da4de0c1 2021-08-04 op if ((ret = val_cast(&a, op->v.cast.totype)) != EVAL_OK)
1050 da4de0c1 2021-08-04 op return ret;
1051 da4de0c1 2021-08-04 op pushv(&a);
1052 c734c0e9 2021-08-03 op break;
1053 c734c0e9 2021-08-03 op
1054 c734c0e9 2021-08-03 op case OP_CMP_EQ:
1055 333d8d7d 2021-08-04 op if ((ret = eval(op->v.cmp_eq.a)) != EVAL_OK)
1056 c734c0e9 2021-08-03 op return ret;
1057 333d8d7d 2021-08-04 op if ((ret = eval(op->v.cmp_eq.b)) != EVAL_OK)
1058 c734c0e9 2021-08-03 op return ret;
1059 c734c0e9 2021-08-03 op
1060 c734c0e9 2021-08-03 op popv(&b);
1061 c734c0e9 2021-08-03 op popv(&a);
1062 c734c0e9 2021-08-03 op pushbool(val_eq(&a, &b));
1063 c734c0e9 2021-08-03 op
1064 c734c0e9 2021-08-03 op break;
1065 c734c0e9 2021-08-03 op
1066 acf1403a 2021-08-05 op case OP_FACCESS:
1067 acf1403a 2021-08-05 op if ((ret = eval(op->v.faccess.expr)) != EVAL_OK)
1068 acf1403a 2021-08-05 op return ret;
1069 acf1403a 2021-08-05 op popv(&a);
1070 acf1403a 2021-08-05 op if ((ret = val_faccess(&a, op->v.faccess.field, &b))
1071 acf1403a 2021-08-05 op != EVAL_OK)
1072 acf1403a 2021-08-05 op return ret;
1073 acf1403a 2021-08-05 op pushv(&b);
1074 8250ab19 2021-08-07 op break;
1075 8250ab19 2021-08-07 op
1076 8250ab19 2021-08-07 op case OP_SFAIL:
1077 8250ab19 2021-08-07 op if ((ret = eval(op->v.sfail.expr)) == EVAL_OK) {
1078 8250ab19 2021-08-07 op before_printing();
1079 8250ab19 2021-08-07 op printf("expecting failure");
1080 8250ab19 2021-08-07 op if (op->v.sfail.msg != NULL)
1081 8250ab19 2021-08-07 op printf(" \"%s\"", op->v.sfail.msg);
1082 8250ab19 2021-08-07 op printf("\n");
1083 8250ab19 2021-08-07 op printf("expression: ");
1084 8250ab19 2021-08-07 op pp_op(op->v.sfail.expr);
1085 8250ab19 2021-08-07 op printf("\n");
1086 8250ab19 2021-08-07 op return EVAL_ERR;
1087 8250ab19 2021-08-07 op }
1088 8250ab19 2021-08-07 op if (ret == EVAL_SKIP)
1089 8250ab19 2021-08-07 op return ret;
1090 acf1403a 2021-08-05 op break;
1091 acf1403a 2021-08-05 op
1092 a9e9e3f7 2021-08-07 op case OP_VARGS:
1093 a9e9e3f7 2021-08-07 op if ((ret = getvar_raw("...", &t)) == EVAL_OK) {
1094 a9e9e3f7 2021-08-07 op for (i = 0; t != NULL; t = t->next)
1095 a9e9e3f7 2021-08-07 op i++;
1096 a9e9e3f7 2021-08-07 op pushnum(i);
1097 a9e9e3f7 2021-08-07 op } else
1098 a9e9e3f7 2021-08-07 op pushnum(0);
1099 a9e9e3f7 2021-08-07 op break;
1100 a9e9e3f7 2021-08-07 op
1101 c734c0e9 2021-08-03 op default:
1102 f3289b7e 2021-08-06 op before_printing();
1103 e9f9c9b1 2021-08-04 op fprintf(stderr, "invalid op, aborting.\n");
1104 c734c0e9 2021-08-03 op abort();
1105 c734c0e9 2021-08-03 op }
1106 c734c0e9 2021-08-03 op
1107 c734c0e9 2021-08-03 op if (op->next)
1108 c734c0e9 2021-08-03 op return eval(op->next);
1109 333d8d7d 2021-08-04 op return EVAL_OK;
1110 c734c0e9 2021-08-03 op }
1111 c734c0e9 2021-08-03 op
1112 c734c0e9 2021-08-03 op void
1113 d9d02161 2021-08-04 op prepare_funcall(void)
1114 c734c0e9 2021-08-03 op {
1115 d9d02161 2021-08-04 op pushstack(&args);
1116 c734c0e9 2021-08-03 op }
1117 c734c0e9 2021-08-03 op
1118 c734c0e9 2021-08-03 op void
1119 c734c0e9 2021-08-03 op push_arg(struct op *op)
1120 c734c0e9 2021-08-03 op {
1121 d9d02161 2021-08-04 op push(&args, op);
1122 c734c0e9 2021-08-03 op }
1123 c734c0e9 2021-08-03 op
1124 c734c0e9 2021-08-03 op struct op *
1125 d9d02161 2021-08-04 op op_funcall(struct proc *proc)
1126 c734c0e9 2021-08-03 op {
1127 d9d02161 2021-08-04 op struct op *op, *argv;
1128 d9d02161 2021-08-04 op int argc;
1129 c734c0e9 2021-08-03 op
1130 d9d02161 2021-08-04 op argv = finalize(&args, &argc);
1131 d9d02161 2021-08-04 op
1132 c734c0e9 2021-08-03 op op = newop(OP_FUNCALL);
1133 c734c0e9 2021-08-03 op op->v.funcall.proc = proc;
1134 d9d02161 2021-08-04 op op->v.funcall.argv = argv;
1135 d9d02161 2021-08-04 op op->v.funcall.argc = argc;
1136 c734c0e9 2021-08-03 op
1137 c734c0e9 2021-08-03 op return op;
1138 c734c0e9 2021-08-03 op }
1139 c734c0e9 2021-08-03 op
1140 c734c0e9 2021-08-03 op void
1141 54736a95 2021-08-04 op add_builtin_proc(const char *name, int (*fn)(int), int argc, int vararg)
1142 c734c0e9 2021-08-03 op {
1143 c734c0e9 2021-08-03 op struct proc *proc;
1144 c734c0e9 2021-08-03 op
1145 c734c0e9 2021-08-03 op proc = xcalloc(1, sizeof(*proc));
1146 c734c0e9 2021-08-03 op proc->name = xstrdup(name);
1147 c734c0e9 2021-08-03 op proc->nativefn = fn;
1148 126080b7 2021-08-04 op proc->minargs = argc;
1149 54736a95 2021-08-04 op proc->vararg = vararg;
1150 c734c0e9 2021-08-03 op
1151 c734c0e9 2021-08-03 op TAILQ_INSERT_HEAD(&procs, proc, entry);
1152 c734c0e9 2021-08-03 op }
1153 c734c0e9 2021-08-03 op
1154 c734c0e9 2021-08-03 op void
1155 d9d02161 2021-08-04 op prepare_proc(void)
1156 c734c0e9 2021-08-03 op {
1157 d9d02161 2021-08-04 op pushstack(&args);
1158 d9d02161 2021-08-04 op }
1159 c734c0e9 2021-08-03 op
1160 d9d02161 2021-08-04 op int
1161 c734c0e9 2021-08-03 op proc_setup_body(void)
1162 c734c0e9 2021-08-03 op {
1163 d9d02161 2021-08-04 op struct opstack *argv;
1164 d9d02161 2021-08-04 op struct op *op;
1165 d9d02161 2021-08-04 op int i;
1166 c734c0e9 2021-08-03 op
1167 d9d02161 2021-08-04 op argv = peek(&args);
1168 d9d02161 2021-08-04 op for (i = 0, op = argv->base.next; op != NULL; i++) {
1169 d9d02161 2021-08-04 op /*
1170 0e62706a 2021-08-04 op * TODO: should free the whole list on error but..,
1171 0e62706a 2021-08-04 op * we're gonna exit real soon(tm)!
1172 d9d02161 2021-08-04 op */
1173 0e62706a 2021-08-04 op if (op->type != OP_VAR && op->type != OP_REST)
1174 d9d02161 2021-08-04 op return 0;
1175 c8878182 2021-08-04 op
1176 c8878182 2021-08-04 op op = op->next;
1177 c734c0e9 2021-08-03 op }
1178 c734c0e9 2021-08-03 op
1179 d9d02161 2021-08-04 op assert(i == argv->counter);
1180 d9d02161 2021-08-04 op pushstack(&blocks);
1181 d9d02161 2021-08-04 op return 1;
1182 c734c0e9 2021-08-03 op }
1183 c734c0e9 2021-08-03 op
1184 c734c0e9 2021-08-03 op void
1185 d9d02161 2021-08-04 op proc_done(char *name)
1186 c734c0e9 2021-08-03 op {
1187 d9d02161 2021-08-04 op struct proc *proc;
1188 d9d02161 2021-08-04 op struct op *op, *next, *argv, *body;
1189 d9d02161 2021-08-04 op int i, argc;
1190 c734c0e9 2021-08-03 op
1191 d9d02161 2021-08-04 op argv = finalize(&args, &argc);
1192 d9d02161 2021-08-04 op body = finalize(&blocks, NULL);
1193 d9d02161 2021-08-04 op
1194 d9d02161 2021-08-04 op proc = xcalloc(1, sizeof(*proc));
1195 d9d02161 2021-08-04 op proc->name = name;
1196 d9d02161 2021-08-04 op proc->minargs = argc;
1197 d9d02161 2021-08-04 op
1198 b99bdaa1 2021-08-04 op for (i = 0, op = argv; op != NULL; ++i) {
1199 0e62706a 2021-08-04 op if (op->type == OP_REST) {
1200 0e62706a 2021-08-04 op proc->vararg = 1;
1201 0e62706a 2021-08-04 op proc->minargs = i;
1202 0e62706a 2021-08-04 op break;
1203 0e62706a 2021-08-04 op }
1204 0e62706a 2021-08-04 op
1205 d9d02161 2021-08-04 op proc->args[i] = xstrdup(op->v.var);
1206 d9d02161 2021-08-04 op
1207 d9d02161 2021-08-04 op next = op->next;
1208 d9d02161 2021-08-04 op free_op(op);
1209 d9d02161 2021-08-04 op op = next;
1210 d9d02161 2021-08-04 op }
1211 0e62706a 2021-08-04 op assert(i == argc || (proc->vararg && i == proc->minargs));
1212 d9d02161 2021-08-04 op
1213 d9d02161 2021-08-04 op proc->body = body;
1214 d9d02161 2021-08-04 op
1215 d9d02161 2021-08-04 op TAILQ_INSERT_HEAD(&procs, proc, entry);
1216 c734c0e9 2021-08-03 op }
1217 c734c0e9 2021-08-03 op
1218 c734c0e9 2021-08-03 op void
1219 c734c0e9 2021-08-03 op block_push(struct op *op)
1220 c734c0e9 2021-08-03 op {
1221 d9d02161 2021-08-04 op push(&blocks, op);
1222 c734c0e9 2021-08-03 op }
1223 c734c0e9 2021-08-03 op
1224 c734c0e9 2021-08-03 op struct proc *
1225 c734c0e9 2021-08-03 op proc_by_name(const char *name)
1226 c734c0e9 2021-08-03 op {
1227 c734c0e9 2021-08-03 op struct proc *p;
1228 c734c0e9 2021-08-03 op
1229 c734c0e9 2021-08-03 op TAILQ_FOREACH(p, &procs, entry) {
1230 c734c0e9 2021-08-03 op if (!strcmp(p->name, name))
1231 c734c0e9 2021-08-03 op return p;
1232 c734c0e9 2021-08-03 op }
1233 c734c0e9 2021-08-03 op
1234 c734c0e9 2021-08-03 op return NULL;
1235 c734c0e9 2021-08-03 op }
1236 c734c0e9 2021-08-03 op
1237 c734c0e9 2021-08-03 op void
1238 d9d02161 2021-08-04 op prepare_test(void)
1239 c734c0e9 2021-08-03 op {
1240 d9d02161 2021-08-04 op pushstack(&blocks);
1241 c734c0e9 2021-08-03 op }
1242 c734c0e9 2021-08-03 op
1243 c734c0e9 2021-08-03 op void
1244 0b453b63 2021-08-07 op test_done(int shouldfail, char *name, char *dir)
1245 c734c0e9 2021-08-03 op {
1246 d9d02161 2021-08-04 op struct test *test;
1247 d9d02161 2021-08-04 op
1248 d9d02161 2021-08-04 op test = xcalloc(1, sizeof(*test));
1249 0b453b63 2021-08-07 op test->shouldfail = shouldfail;
1250 d9d02161 2021-08-04 op test->name = name;
1251 d9d02161 2021-08-04 op test->dir = dir;
1252 d9d02161 2021-08-04 op test->body = finalize(&blocks, NULL);
1253 d9d02161 2021-08-04 op
1254 5e5c37b5 2021-08-04 op if (TAILQ_EMPTY(&tests))
1255 5e5c37b5 2021-08-04 op TAILQ_INSERT_HEAD(&tests, test, entry);
1256 5e5c37b5 2021-08-04 op else
1257 5e5c37b5 2021-08-04 op TAILQ_INSERT_TAIL(&tests, test, entry);
1258 d728769d 2021-08-07 op
1259 d728769d 2021-08-07 op ntests++;
1260 c734c0e9 2021-08-03 op }
1261 c734c0e9 2021-08-03 op
1262 c734c0e9 2021-08-03 op static int
1263 54736a95 2021-08-04 op builtin_print(int argc)
1264 c734c0e9 2021-08-03 op {
1265 54736a95 2021-08-04 op struct value v;
1266 54736a95 2021-08-04 op int i;
1267 ce030684 2021-08-04 op
1268 f3289b7e 2021-08-06 op before_printing();
1269 f3289b7e 2021-08-06 op
1270 54736a95 2021-08-04 op for (i = argc; i > 0; --i) {
1271 54736a95 2021-08-04 op peekn(i, &v);
1272 54736a95 2021-08-04 op if (v.type == V_STR)
1273 54736a95 2021-08-04 op printf("%s", v.v.str);
1274 54736a95 2021-08-04 op else
1275 54736a95 2021-08-04 op pp_val(&v);
1276 54736a95 2021-08-04 op printf(" ");
1277 54736a95 2021-08-04 op }
1278 54736a95 2021-08-04 op
1279 ce030684 2021-08-04 op printf("\n");
1280 ce030684 2021-08-04 op
1281 54736a95 2021-08-04 op popvn(argc);
1282 dd1d2343 2021-08-05 op
1283 dd1d2343 2021-08-05 op return EVAL_OK;
1284 dd1d2343 2021-08-05 op }
1285 dd1d2343 2021-08-05 op
1286 dd1d2343 2021-08-05 op static int
1287 dd1d2343 2021-08-05 op builtin_debug(int argc)
1288 dd1d2343 2021-08-05 op {
1289 dd1d2343 2021-08-05 op if (debug)
1290 dd1d2343 2021-08-05 op return builtin_print(argc);
1291 54736a95 2021-08-04 op
1292 dd1d2343 2021-08-05 op popvn(argc);
1293 333d8d7d 2021-08-04 op return EVAL_OK;
1294 c734c0e9 2021-08-03 op }
1295 c734c0e9 2021-08-03 op
1296 c734c0e9 2021-08-03 op static int
1297 ce030684 2021-08-04 op builtin_skip(int argc)
1298 ce030684 2021-08-04 op {
1299 ce030684 2021-08-04 op return EVAL_SKIP;
1300 6019438a 2021-08-05 op }
1301 6019438a 2021-08-05 op
1302 6019438a 2021-08-05 op static int
1303 6019438a 2021-08-05 op builtin_iota(int argc)
1304 6019438a 2021-08-05 op {
1305 6019438a 2021-08-05 op struct value v;
1306 6019438a 2021-08-05 op
1307 582b509f 2021-08-07 op v.type = V_U16;
1308 582b509f 2021-08-07 op if ((v.v.u16 = ++lasttag) == 255)
1309 582b509f 2021-08-07 op v.v.u16 = ++lasttag;
1310 6019438a 2021-08-05 op
1311 6019438a 2021-08-05 op pushv(&v);
1312 6019438a 2021-08-05 op return EVAL_OK;
1313 9820edbf 2021-08-06 op }
1314 9820edbf 2021-08-06 op
1315 9820edbf 2021-08-06 op static int
1316 9820edbf 2021-08-06 op builtin_send(int argc)
1317 9820edbf 2021-08-06 op {
1318 9820edbf 2021-08-06 op struct ibuf *buf;
1319 9820edbf 2021-08-06 op struct value v;
1320 9820edbf 2021-08-06 op uint32_t len;
1321 9820edbf 2021-08-06 op uint16_t slen;
1322 9820edbf 2021-08-06 op int i;
1323 370b4f2e 2021-08-07 op
1324 370b4f2e 2021-08-07 op check_for_output();
1325 9820edbf 2021-08-06 op
1326 9820edbf 2021-08-06 op /*
1327 9820edbf 2021-08-06 op * Compute the length of the packet. 4 is for the initial
1328 9820edbf 2021-08-06 op * length field
1329 9820edbf 2021-08-06 op */
1330 9820edbf 2021-08-06 op len = 4;
1331 9820edbf 2021-08-06 op
1332 9820edbf 2021-08-06 op for (i = argc; i > 0; --i) {
1333 9820edbf 2021-08-06 op peekn(i, &v);
1334 9820edbf 2021-08-06 op switch (v.type) {
1335 9820edbf 2021-08-06 op case V_STR:
1336 9820edbf 2021-08-06 op len += 2; /* count */
1337 9820edbf 2021-08-06 op len += strlen(v.v.str);
1338 9820edbf 2021-08-06 op break;
1339 9820edbf 2021-08-06 op
1340 9820edbf 2021-08-06 op case V_U8:
1341 9820edbf 2021-08-06 op len += 1;
1342 9820edbf 2021-08-06 op break;
1343 9820edbf 2021-08-06 op
1344 9820edbf 2021-08-06 op case V_U16:
1345 9820edbf 2021-08-06 op len += 2;
1346 9820edbf 2021-08-06 op break;
1347 9820edbf 2021-08-06 op
1348 9820edbf 2021-08-06 op case V_U32:
1349 9820edbf 2021-08-06 op len += 4;
1350 9820edbf 2021-08-06 op break;
1351 9820edbf 2021-08-06 op
1352 9820edbf 2021-08-06 op default:
1353 9820edbf 2021-08-06 op before_printing();
1354 9820edbf 2021-08-06 op printf("%s: can't serialize ", __func__);
1355 9820edbf 2021-08-06 op pp_val(&v);
1356 9820edbf 2021-08-06 op printf("\n");
1357 9820edbf 2021-08-06 op return EVAL_ERR;
1358 9820edbf 2021-08-06 op }
1359 9820edbf 2021-08-06 op }
1360 9820edbf 2021-08-06 op
1361 9820edbf 2021-08-06 op if (len > UINT16_MAX) {
1362 9820edbf 2021-08-06 op before_printing();
1363 9820edbf 2021-08-06 op printf("%s: message size too long: got %d when max is %d\n",
1364 9820edbf 2021-08-06 op __func__, len, UINT16_MAX);
1365 9820edbf 2021-08-06 op return EVAL_ERR;
1366 9820edbf 2021-08-06 op }
1367 9820edbf 2021-08-06 op
1368 9820edbf 2021-08-06 op if ((buf = imsg_create(&ibuf, IMSG_BUF, 0, 0, len)) == NULL)
1369 9820edbf 2021-08-06 op fatal("imsg_create(%d)", len);
1370 9820edbf 2021-08-06 op
1371 34aba5f7 2021-08-06 op len = htole32(len);
1372 9820edbf 2021-08-06 op imsg_add(buf, &len, sizeof(len));
1373 34aba5f7 2021-08-06 op
1374 9820edbf 2021-08-06 op for (i = argc; i > 0; --i) {
1375 9820edbf 2021-08-06 op peekn(i, &v);
1376 9820edbf 2021-08-06 op switch (v.type) {
1377 9820edbf 2021-08-06 op case V_STR:
1378 9820edbf 2021-08-06 op slen = strlen(v.v.str);
1379 9820edbf 2021-08-06 op slen = htole16(slen);
1380 9820edbf 2021-08-06 op imsg_add(buf, &slen, sizeof(slen));
1381 9820edbf 2021-08-06 op imsg_add(buf, v.v.str, strlen(v.v.str));
1382 9820edbf 2021-08-06 op break;
1383 9820edbf 2021-08-06 op
1384 9820edbf 2021-08-06 op case V_U8:
1385 9820edbf 2021-08-06 op imsg_add(buf, &v.v.u8, 1);
1386 9820edbf 2021-08-06 op break;
1387 9820edbf 2021-08-06 op
1388 9820edbf 2021-08-06 op case V_U16:
1389 9820edbf 2021-08-06 op v.v.u16 = htole16(v.v.u16);
1390 9820edbf 2021-08-06 op imsg_add(buf, &v.v.u16, 2);
1391 9820edbf 2021-08-06 op break;
1392 9820edbf 2021-08-06 op
1393 9820edbf 2021-08-06 op case V_U32:
1394 9820edbf 2021-08-06 op v.v.u32 = htole32(v.v.u32);
1395 9820edbf 2021-08-06 op imsg_add(buf, &v.v.u32, 4);
1396 9820edbf 2021-08-06 op break;
1397 9820edbf 2021-08-06 op }
1398 9820edbf 2021-08-06 op }
1399 9820edbf 2021-08-06 op
1400 9820edbf 2021-08-06 op imsg_close(&ibuf, buf);
1401 9820edbf 2021-08-06 op
1402 9820edbf 2021-08-06 op if (imsg_flush(&ibuf) == -1) {
1403 9820edbf 2021-08-06 op i = errno;
1404 9820edbf 2021-08-06 op before_printing();
1405 9820edbf 2021-08-06 op printf("%s: imsg_flush failed: %s\n", __func__, strerror(i));
1406 9820edbf 2021-08-06 op return EVAL_ERR;
1407 9820edbf 2021-08-06 op }
1408 9820edbf 2021-08-06 op
1409 370b4f2e 2021-08-07 op check_for_output();
1410 9820edbf 2021-08-06 op return EVAL_OK;
1411 9820edbf 2021-08-06 op }
1412 9820edbf 2021-08-06 op
1413 9820edbf 2021-08-06 op static int
1414 9820edbf 2021-08-06 op builtin_recv(int argc)
1415 9820edbf 2021-08-06 op {
1416 9820edbf 2021-08-06 op struct pollfd pfd;
1417 9820edbf 2021-08-06 op struct value v;
1418 9820edbf 2021-08-06 op struct imsg imsg;
1419 9820edbf 2021-08-06 op ssize_t n, datalen;
1420 9820edbf 2021-08-06 op int serrno;
1421 9820edbf 2021-08-06 op
1422 9820edbf 2021-08-06 op if (lastmsg != NULL) {
1423 9820edbf 2021-08-06 op free(lastmsg);
1424 9820edbf 2021-08-06 op lastmsg = NULL;
1425 9820edbf 2021-08-06 op }
1426 9820edbf 2021-08-06 op
1427 9820edbf 2021-08-06 op pfd.fd = ibuf.fd;
1428 9820edbf 2021-08-06 op pfd.events = POLLIN;
1429 9820edbf 2021-08-06 op if (poll(&pfd, 1, INFTIM) == -1) {
1430 9820edbf 2021-08-06 op serrno = errno;
1431 9820edbf 2021-08-06 op before_printing();
1432 9820edbf 2021-08-06 op printf("%s: poll failed: %s\n", __func__, strerror(serrno));
1433 9820edbf 2021-08-06 op return EVAL_ERR;
1434 9820edbf 2021-08-06 op }
1435 9820edbf 2021-08-06 op
1436 9820edbf 2021-08-06 op again:
1437 9820edbf 2021-08-06 op if ((n = imsg_read(&ibuf)) == -1) {
1438 9820edbf 2021-08-06 op if (errno == EAGAIN)
1439 9820edbf 2021-08-06 op goto again;
1440 9820edbf 2021-08-06 op fatal("imsg_read");
1441 9820edbf 2021-08-06 op }
1442 9820edbf 2021-08-06 op if (n == 0) {
1443 9820edbf 2021-08-06 op disconnect:
1444 9820edbf 2021-08-06 op before_printing();
1445 9820edbf 2021-08-06 op printf("child disconnected\n");
1446 9820edbf 2021-08-06 op return EVAL_ERR;
1447 9820edbf 2021-08-06 op }
1448 9820edbf 2021-08-06 op
1449 eed75362 2021-08-06 op nextmessage:
1450 370b4f2e 2021-08-07 op check_for_output();
1451 370b4f2e 2021-08-07 op
1452 9820edbf 2021-08-06 op /* read only one message */
1453 9820edbf 2021-08-06 op if ((n = imsg_get(&ibuf, &imsg)) == -1)
1454 9820edbf 2021-08-06 op fatal("imsg_get");
1455 9820edbf 2021-08-06 op if (n == 0)
1456 9820edbf 2021-08-06 op goto disconnect;
1457 9820edbf 2021-08-06 op
1458 9820edbf 2021-08-06 op datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
1459 9820edbf 2021-08-06 op switch (imsg.hdr.type) {
1460 9820edbf 2021-08-06 op case IMSG_BUF:
1461 9820edbf 2021-08-06 op v.type = V_MSG;
1462 9820edbf 2021-08-06 op if ((v.v.msg.msg = malloc(datalen)) == NULL)
1463 9820edbf 2021-08-06 op fatal("malloc");
1464 9820edbf 2021-08-06 op memcpy(v.v.msg.msg, imsg.data, datalen);
1465 9820edbf 2021-08-06 op v.v.msg.len = datalen;
1466 9820edbf 2021-08-06 op pushv(&v);
1467 9820edbf 2021-08-06 op imsg_free(&imsg);
1468 9820edbf 2021-08-06 op return EVAL_OK;
1469 9820edbf 2021-08-06 op
1470 9820edbf 2021-08-06 op case IMSG_CLOSE:
1471 9820edbf 2021-08-06 op before_printing();
1472 9820edbf 2021-08-06 op printf("subprocess closed the connection\n");
1473 9820edbf 2021-08-06 op imsg_free(&imsg);
1474 9820edbf 2021-08-06 op return EVAL_ERR;
1475 9820edbf 2021-08-06 op
1476 eed75362 2021-08-06 op case IMSG_MSIZE:
1477 eed75362 2021-08-06 op imsg_free(&imsg);
1478 eed75362 2021-08-06 op goto nextmessage;
1479 eed75362 2021-08-06 op
1480 9820edbf 2021-08-06 op default:
1481 9820edbf 2021-08-06 op before_printing();
1482 9820edbf 2021-08-06 op printf("got unknown message from subprocess: %d\n",
1483 9820edbf 2021-08-06 op imsg.hdr.type);
1484 9820edbf 2021-08-06 op imsg_free(&imsg);
1485 9820edbf 2021-08-06 op return EVAL_ERR;
1486 9820edbf 2021-08-06 op }
1487 ce030684 2021-08-04 op }
1488 ce030684 2021-08-04 op
1489 9820edbf 2021-08-06 op static pid_t
1490 9820edbf 2021-08-06 op spawn_client_proc(void)
1491 9820edbf 2021-08-06 op {
1492 9820edbf 2021-08-06 op const char *argv[4];
1493 370b4f2e 2021-08-07 op int p[2], out[2], argc = 0;
1494 9820edbf 2021-08-06 op pid_t pid;
1495 9820edbf 2021-08-06 op
1496 370b4f2e 2021-08-07 op if (child_out != -1)
1497 370b4f2e 2021-08-07 op close(child_out);
1498 370b4f2e 2021-08-07 op
1499 9820edbf 2021-08-06 op if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
1500 9820edbf 2021-08-06 op PF_UNSPEC, p) == -1)
1501 370b4f2e 2021-08-07 op fatal("socketpair");
1502 370b4f2e 2021-08-07 op
1503 370b4f2e 2021-08-07 op if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
1504 370b4f2e 2021-08-07 op PF_UNSPEC, out) == -1)
1505 9820edbf 2021-08-06 op fatal("socketpair");
1506 9820edbf 2021-08-06 op
1507 9820edbf 2021-08-06 op switch (pid = fork()) {
1508 9820edbf 2021-08-06 op case -1:
1509 9820edbf 2021-08-06 op fatal("cannot fork");
1510 9820edbf 2021-08-06 op case 0:
1511 9820edbf 2021-08-06 op break;
1512 9820edbf 2021-08-06 op default:
1513 9820edbf 2021-08-06 op close(p[1]);
1514 370b4f2e 2021-08-07 op close(out[1]);
1515 370b4f2e 2021-08-07 op child_out = out[0];
1516 9820edbf 2021-08-06 op if (ibuf_inuse) {
1517 9820edbf 2021-08-06 op msgbuf_clear(&ibuf.w);
1518 9820edbf 2021-08-06 op close(ibuf.fd);
1519 9820edbf 2021-08-06 op }
1520 9820edbf 2021-08-06 op imsg_init(&ibuf, p[0]);
1521 9820edbf 2021-08-06 op ibuf_inuse = 1;
1522 9820edbf 2021-08-06 op return pid;
1523 9820edbf 2021-08-06 op }
1524 9820edbf 2021-08-06 op
1525 9820edbf 2021-08-06 op close(p[0]);
1526 370b4f2e 2021-08-07 op close(out[0]);
1527 9820edbf 2021-08-06 op
1528 370b4f2e 2021-08-07 op if (dup2(out[1], 1) == -1 ||
1529 370b4f2e 2021-08-07 op dup2(out[1], 2) == -1)
1530 370b4f2e 2021-08-07 op fatal("dup2");
1531 370b4f2e 2021-08-07 op
1532 9820edbf 2021-08-06 op if (p[1] != 3) {
1533 9820edbf 2021-08-06 op if (dup2(p[1], 3) == -1)
1534 9820edbf 2021-08-06 op fatal("cannot setup imsg fd");
1535 9820edbf 2021-08-06 op } else if (fcntl(F_SETFD, 0) == -1)
1536 9820edbf 2021-08-06 op fatal("cannot setup imsg fd");
1537 9820edbf 2021-08-06 op
1538 9820edbf 2021-08-06 op argv[argc++] = argv0;
1539 9820edbf 2021-08-06 op argv[argc++] = "-Tc";
1540 9820edbf 2021-08-06 op
1541 9820edbf 2021-08-06 op #if DEBUG
1542 9820edbf 2021-08-06 op argv[argc++] = "-v";
1543 9820edbf 2021-08-06 op #endif
1544 9820edbf 2021-08-06 op
1545 9820edbf 2021-08-06 op argv[argc++] = NULL;
1546 9820edbf 2021-08-06 op
1547 9820edbf 2021-08-06 op execvp(argv0, (char *const *)argv);
1548 9820edbf 2021-08-06 op fatal("execvp");
1549 9820edbf 2021-08-06 op }
1550 9820edbf 2021-08-06 op
1551 9820edbf 2021-08-06 op static void
1552 9820edbf 2021-08-06 op prepare_child_for_test(struct test *t)
1553 9820edbf 2021-08-06 op {
1554 9820edbf 2021-08-06 op struct passwd *pw;
1555 9820edbf 2021-08-06 op struct stat sb;
1556 9820edbf 2021-08-06 op
1557 9820edbf 2021-08-06 op if (stat(t->dir, &sb) == -1)
1558 9820edbf 2021-08-06 op fatal("stat(\"%s\")", t->dir);
1559 9820edbf 2021-08-06 op
1560 9820edbf 2021-08-06 op if ((pw = getpwuid(sb.st_uid)) == NULL)
1561 9820edbf 2021-08-06 op fatal("getpwuid(%d)", sb.st_uid);
1562 9820edbf 2021-08-06 op
1563 9820edbf 2021-08-06 op imsg_compose(&ibuf, IMSG_AUTH, 0, 0, -1,
1564 9820edbf 2021-08-06 op pw->pw_name, strlen(pw->pw_name)+1);
1565 9820edbf 2021-08-06 op imsg_compose(&ibuf, IMSG_AUTH_DIR, 0, 0, -1,
1566 9820edbf 2021-08-06 op t->dir, strlen(t->dir)+1);
1567 9820edbf 2021-08-06 op
1568 9820edbf 2021-08-06 op if (imsg_flush(&ibuf) == -1)
1569 9820edbf 2021-08-06 op fatal("imsg_flush");
1570 9820edbf 2021-08-06 op }
1571 9820edbf 2021-08-06 op
1572 ce030684 2021-08-04 op static int
1573 c734c0e9 2021-08-03 op run_test(struct test *t)
1574 c734c0e9 2021-08-03 op {
1575 9820edbf 2021-08-06 op pid_t pid;
1576 9820edbf 2021-08-06 op int ret;
1577 9820edbf 2021-08-06 op
1578 c734c0e9 2021-08-03 op #if DEBUG
1579 f3289b7e 2021-08-06 op before_printing();
1580 c734c0e9 2021-08-03 op puts("=====================");
1581 8e0ef4cb 2021-08-04 op pp_block(t->body);
1582 c734c0e9 2021-08-03 op puts("=====================");
1583 c734c0e9 2021-08-03 op #endif
1584 c734c0e9 2021-08-03 op
1585 09e42a8d 2021-08-07 op if (stackh != 0)
1586 09e42a8d 2021-08-07 op popvn(stackh);
1587 09e42a8d 2021-08-07 op
1588 91cfe5ca 2021-08-06 op if (t->body == NULL) {
1589 91cfe5ca 2021-08-06 op before_printing();
1590 91cfe5ca 2021-08-06 op printf("no instructions, skipping...\n");
1591 91cfe5ca 2021-08-06 op return EVAL_SKIP;
1592 91cfe5ca 2021-08-06 op }
1593 91cfe5ca 2021-08-06 op
1594 9820edbf 2021-08-06 op pid = spawn_client_proc();
1595 9820edbf 2021-08-06 op prepare_child_for_test(t);
1596 9820edbf 2021-08-06 op ret = eval(t->body);
1597 9820edbf 2021-08-06 op
1598 eed75362 2021-08-06 op imsg_compose(&ibuf, IMSG_CONN_GONE, 0, 0, -1, NULL, 0);
1599 eed75362 2021-08-06 op imsg_flush(&ibuf);
1600 eed75362 2021-08-06 op
1601 9820edbf 2021-08-06 op while (waitpid(pid, NULL, 0) != pid)
1602 9820edbf 2021-08-06 op ; /* nop */
1603 0b453b63 2021-08-07 op
1604 370b4f2e 2021-08-07 op check_for_output();
1605 370b4f2e 2021-08-07 op
1606 0b453b63 2021-08-07 op if (t->shouldfail) {
1607 0b453b63 2021-08-07 op if (ret == EVAL_OK) {
1608 0b453b63 2021-08-07 op before_printing();
1609 0b453b63 2021-08-07 op printf("test was expected to fail\n");
1610 0b453b63 2021-08-07 op return EVAL_ERR;
1611 0b453b63 2021-08-07 op } else if (ret == EVAL_ERR)
1612 0b453b63 2021-08-07 op return EVAL_OK;
1613 0b453b63 2021-08-07 op }
1614 9820edbf 2021-08-06 op
1615 9820edbf 2021-08-06 op return ret;
1616 c734c0e9 2021-08-03 op }
1617 c734c0e9 2021-08-03 op
1618 c734c0e9 2021-08-03 op int
1619 c734c0e9 2021-08-03 op main(int argc, char **argv)
1620 c734c0e9 2021-08-03 op {
1621 c734c0e9 2021-08-03 op struct test *t;
1622 f3289b7e 2021-08-06 op int ch, i, r, passed = 0, failed = 0, skipped = 0;
1623 9820edbf 2021-08-06 op int runclient = 0;
1624 32b8add4 2021-12-14 op const char *pat = NULL;
1625 32b8add4 2021-12-14 op regex_t reg;
1626 c734c0e9 2021-08-03 op
1627 9820edbf 2021-08-06 op assert(argv0 = argv[0]);
1628 9820edbf 2021-08-06 op
1629 9820edbf 2021-08-06 op signal(SIGPIPE, SIG_IGN);
1630 9820edbf 2021-08-06 op
1631 c734c0e9 2021-08-03 op log_init(1, LOG_DAEMON);
1632 c734c0e9 2021-08-03 op log_setverbose(1);
1633 c734c0e9 2021-08-03 op
1634 f9cd3e06 2021-08-04 op /* prepare the global env */
1635 f9cd3e06 2021-08-04 op pushenv();
1636 f9cd3e06 2021-08-04 op
1637 54736a95 2021-08-04 op add_builtin_proc("print", builtin_print, 1, 1);
1638 dd1d2343 2021-08-05 op add_builtin_proc("debug", builtin_debug, 1, 1);
1639 54736a95 2021-08-04 op add_builtin_proc("skip", builtin_skip, 0, 0);
1640 6019438a 2021-08-05 op add_builtin_proc("iota", builtin_iota, 0, 0);
1641 9820edbf 2021-08-06 op add_builtin_proc("send", builtin_send, 2, 1);
1642 9820edbf 2021-08-06 op add_builtin_proc("recv", builtin_recv, 0, 0);
1643 c734c0e9 2021-08-03 op
1644 32b8add4 2021-12-14 op while ((ch = getopt(argc, argv, "nT:vx:")) != -1) {
1645 dd1d2343 2021-08-05 op switch (ch) {
1646 4315b20a 2021-08-05 op case 'n':
1647 4315b20a 2021-08-05 op syntaxcheck = 1;
1648 4315b20a 2021-08-05 op break;
1649 9820edbf 2021-08-06 op case 'T':
1650 9820edbf 2021-08-06 op assert(*optarg == 'c');
1651 9820edbf 2021-08-06 op runclient = 1;
1652 9820edbf 2021-08-06 op break;
1653 dd1d2343 2021-08-05 op case 'v':
1654 dd1d2343 2021-08-05 op debug = 1;
1655 dd1d2343 2021-08-05 op break;
1656 32b8add4 2021-12-14 op case 'x':
1657 32b8add4 2021-12-14 op pat = optarg;
1658 32b8add4 2021-12-14 op break;
1659 dd1d2343 2021-08-05 op default:
1660 4315b20a 2021-08-05 op fprintf(stderr, "Usage: %s [-nv] [files...]\n",
1661 dd1d2343 2021-08-05 op *argv);
1662 dd1d2343 2021-08-05 op exit(1);
1663 dd1d2343 2021-08-05 op }
1664 dd1d2343 2021-08-05 op }
1665 dd1d2343 2021-08-05 op argc -= optind;
1666 dd1d2343 2021-08-05 op argv += optind;
1667 dd1d2343 2021-08-05 op
1668 9820edbf 2021-08-06 op if (runclient)
1669 9820edbf 2021-08-06 op client(1, debug);
1670 32b8add4 2021-12-14 op
1671 32b8add4 2021-12-14 op if (pat == NULL)
1672 32b8add4 2021-12-14 op pat = ".*";
1673 9820edbf 2021-08-06 op
1674 32b8add4 2021-12-14 op if (regcomp(&reg, pat, REG_BASIC | REG_ICASE | REG_NOSUB) != 0)
1675 32b8add4 2021-12-14 op fatalx("invalid regexp: %s", pat);
1676 32b8add4 2021-12-14 op
1677 dd1d2343 2021-08-05 op for (i = 0; i < argc; ++i)
1678 c734c0e9 2021-08-03 op loadfile(argv[i]);
1679 c734c0e9 2021-08-03 op
1680 4315b20a 2021-08-05 op if (syntaxcheck) {
1681 4315b20a 2021-08-05 op fprintf(stderr, "files OK\n");
1682 4315b20a 2021-08-05 op return 0;
1683 4315b20a 2021-08-05 op }
1684 4315b20a 2021-08-05 op
1685 9820edbf 2021-08-06 op /* Check for root privileges. */
1686 9820edbf 2021-08-06 op if (geteuid())
1687 9820edbf 2021-08-06 op fatalx("need root privileges");
1688 9820edbf 2021-08-06 op
1689 e334da07 2021-08-04 op i = 0;
1690 c734c0e9 2021-08-03 op TAILQ_FOREACH(t, &tests, entry) {
1691 32b8add4 2021-12-14 op if (regexec(&reg, t->name, 0, NULL, 0) != 0)
1692 32b8add4 2021-12-14 op continue;
1693 32b8add4 2021-12-14 op
1694 4e3f88dd 2021-12-13 op printf("===> [%d/%d] running test \"%s\"... ", i+1, ntests,
1695 d728769d 2021-08-07 op t->name);
1696 e334da07 2021-08-04 op fflush(stdout);
1697 e334da07 2021-08-04 op
1698 f3289b7e 2021-08-06 op filler = "\n";
1699 f3289b7e 2021-08-06 op r = run_test(t);
1700 f3289b7e 2021-08-06 op if (filler == NULL)
1701 f3289b7e 2021-08-06 op printf("=> test ");
1702 f3289b7e 2021-08-06 op
1703 f3289b7e 2021-08-06 op switch (r) {
1704 333d8d7d 2021-08-04 op case EVAL_OK:
1705 d728769d 2021-08-07 op printf("passed\n");
1706 e334da07 2021-08-04 op passed++;
1707 e334da07 2021-08-04 op break;
1708 333d8d7d 2021-08-04 op case EVAL_ERR:
1709 e334da07 2021-08-04 op failed++;
1710 f3289b7e 2021-08-06 op printf("failed\n");
1711 e334da07 2021-08-04 op break;
1712 333d8d7d 2021-08-04 op case EVAL_SKIP:
1713 f3289b7e 2021-08-06 op printf("skipped\n");
1714 e334da07 2021-08-04 op skipped++;
1715 e334da07 2021-08-04 op break;
1716 c734c0e9 2021-08-03 op }
1717 e334da07 2021-08-04 op
1718 83117bfe 2021-08-07 op if (filler == NULL)
1719 83117bfe 2021-08-07 op printf("\n");
1720 e334da07 2021-08-04 op i++;
1721 c734c0e9 2021-08-03 op }
1722 c734c0e9 2021-08-03 op
1723 f3289b7e 2021-08-06 op printf("\n");
1724 4ed3f1b8 2021-12-14 op printf("%d/%d passed (%d skipped and %d failed)\n",
1725 25b0f8d2 2021-08-07 op passed, i, skipped, failed);
1726 c734c0e9 2021-08-03 op
1727 f9cd3e06 2021-08-04 op popenv();
1728 d41deb93 2021-08-07 op free(lastmsg);
1729 32b8add4 2021-12-14 op regfree(&reg);
1730 f9cd3e06 2021-08-04 op
1731 c734c0e9 2021-08-03 op return failed != 0;
1732 c734c0e9 2021-08-03 op }