2 c734c0e9 2021-08-03 op * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
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.
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.
17 c734c0e9 2021-08-03 op #include "compat.h"
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>
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>
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"
43 c734c0e9 2021-08-03 op #define DEBUG 0
45 9820edbf 2021-08-06 op #ifndef INFTIM
46 9820edbf 2021-08-06 op #define INFTIM -1
49 9820edbf 2021-08-06 op static const char *argv0;
51 9820edbf 2021-08-06 op static uint8_t *lastmsg;
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;
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);
60 d728769d 2021-08-07 op static int ntests;
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);
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;
69 f9cd3e06 2021-08-04 op static struct envs envs = TAILQ_HEAD_INITIALIZER(envs);
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}};
74 6019438a 2021-08-05 op static uint8_t lasttag;
76 dd1d2343 2021-08-05 op static int debug;
77 4315b20a 2021-08-05 op static int syntaxcheck;
79 f3289b7e 2021-08-06 op static const char *filler;
81 f9cd3e06 2021-08-04 op static inline void
82 f3289b7e 2021-08-06 op before_printing(void)
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;
90 f3289b7e 2021-08-06 op static inline void
91 370b4f2e 2021-08-07 op check_for_output(void)
93 370b4f2e 2021-08-07 op static char buf[BUFSIZ];
94 370b4f2e 2021-08-07 op struct pollfd pfd;
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");
102 370b4f2e 2021-08-07 op if (!(pfd.revents & POLLIN))
106 2305d578 2021-08-07 op if ((r = read(child_out, buf, sizeof(buf))) == -1) {
107 2305d578 2021-08-07 op if (errno == EAGAIN)
109 370b4f2e 2021-08-07 op fatal("read");
113 370b4f2e 2021-08-07 op before_printing();
114 370b4f2e 2021-08-07 op fwrite(buf, 1, r, stdout);
118 370b4f2e 2021-08-07 op static inline void
119 54736a95 2021-08-04 op peekn(int depth, struct value *v)
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",
124 54736a95 2021-08-04 op memcpy(v, &vstack[stackh - depth], sizeof(*v));
127 54736a95 2021-08-04 op printf("peeking(%d) ", depth); pp_val(v); printf("\n");
131 54736a95 2021-08-04 op static inline void
132 f9cd3e06 2021-08-04 op popv(struct value *v)
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));
139 f9cd3e06 2021-08-04 op printf("popping "); pp_val(v); printf("\n");
143 f9cd3e06 2021-08-04 op static inline void
146 54736a95 2021-08-04 op struct value v;
148 54736a95 2021-08-04 op while (n-- > 0)
152 54736a95 2021-08-04 op static inline void
153 f9cd3e06 2021-08-04 op pushv(struct value *v)
155 f9cd3e06 2021-08-04 op if (stackh == STACK_HEIGHT)
156 f9cd3e06 2021-08-04 op errx(1, "can't push the stack: overflow");
159 f9cd3e06 2021-08-04 op printf("pushing "); pp_val(v); printf("\n");
162 f9cd3e06 2021-08-04 op memcpy(&vstack[stackh++], v, sizeof(*v));
165 f9cd3e06 2021-08-04 op static inline void
166 f9cd3e06 2021-08-04 op pushbool(int n)
168 f9cd3e06 2021-08-04 op pushv(n ? &v_true : &v_false);
171 a9e9e3f7 2021-08-07 op static inline void
172 a9e9e3f7 2021-08-07 op pushnum(int64_t n)
174 a9e9e3f7 2021-08-07 op struct value v;
176 a9e9e3f7 2021-08-07 op v.type = V_NUM;
181 d9d02161 2021-08-04 op static inline struct opstack *
182 d9d02161 2021-08-04 op pushstack(struct opstacks *stack)
184 d9d02161 2021-08-04 op struct opstack *ops;
186 d9d02161 2021-08-04 op ops = xcalloc(1, sizeof(*ops));
187 d9d02161 2021-08-04 op TAILQ_INSERT_HEAD(stack, ops, entry);
191 d9d02161 2021-08-04 op static inline struct opstack *
192 d9d02161 2021-08-04 op peek(struct opstacks *stack)
194 d9d02161 2021-08-04 op if (TAILQ_EMPTY(stack))
195 d9d02161 2021-08-04 op errx(1, "%s: args underflow", __func__);
197 d9d02161 2021-08-04 op return TAILQ_FIRST(stack);
200 d9d02161 2021-08-04 op static inline struct op *
201 d9d02161 2021-08-04 op finalize(struct opstacks *stack, int *argc)
203 d9d02161 2021-08-04 op struct opstack *ops;
204 d9d02161 2021-08-04 op struct op *op;
206 d9d02161 2021-08-04 op if (TAILQ_EMPTY(stack))
207 d9d02161 2021-08-04 op errx(1, "%s: args underflow", __func__);
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;
213 d9d02161 2021-08-04 op if (argc != NULL)
214 d9d02161 2021-08-04 op *argc = ops->counter;
220 d9d02161 2021-08-04 op static inline void
221 d9d02161 2021-08-04 op push(struct opstacks *stack, struct op *op)
223 d9d02161 2021-08-04 op struct opstack *ops;
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;
230 d9d02161 2021-08-04 op ops->last->next = op;
231 d9d02161 2021-08-04 op ops->last = op;
234 d9d02161 2021-08-04 op ops->counter++;
237 f9cd3e06 2021-08-04 op static inline void
238 f9cd3e06 2021-08-04 op pushenv(void)
240 f9cd3e06 2021-08-04 op struct env *e;
242 f9cd3e06 2021-08-04 op e = xcalloc(1, sizeof(*e));
243 f9cd3e06 2021-08-04 op TAILQ_INSERT_HEAD(&envs, e, entry);
246 f9cd3e06 2021-08-04 op static inline struct env *
247 f9cd3e06 2021-08-04 op currentenv(void)
249 f9cd3e06 2021-08-04 op assert(!TAILQ_EMPTY(&envs));
250 f9cd3e06 2021-08-04 op return TAILQ_FIRST(&envs);
256 f9cd3e06 2021-08-04 op struct env *e;
257 f9cd3e06 2021-08-04 op struct binding *b, *tb;
259 f9cd3e06 2021-08-04 op e = currentenv();
260 f9cd3e06 2021-08-04 op TAILQ_REMOVE(&envs, e, entry);
262 0b3307f1 2021-08-08 op TAILQ_FOREACH_SAFE(b, &e->bindings, entry, tb)
268 f9cd3e06 2021-08-04 op static inline int
269 f9cd3e06 2021-08-04 op setvar(char *sym, struct op *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;
275 511b3aa7 2021-08-07 op height = stackh;
276 f9cd3e06 2021-08-04 op if ((ret = eval(op)) != EVAL_OK)
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);
283 511b3aa7 2021-08-07 op printf("\n");
284 511b3aa7 2021-08-07 op return EVAL_ERR;
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);
291 f9cd3e06 2021-08-04 op e = TAILQ_FIRST(&envs);
292 f9cd3e06 2021-08-04 op TAILQ_INSERT_HEAD(&e->bindings, b, entry);
294 f9cd3e06 2021-08-04 op return EVAL_OK;
297 6eb34747 2021-08-05 op static inline void
298 6eb34747 2021-08-05 op setvar_raw(char *sym, struct op *op)
300 6eb34747 2021-08-05 op struct binding *b;
301 6eb34747 2021-08-05 op struct env *e;
303 6eb34747 2021-08-05 op b = xcalloc(1, sizeof(*b));
304 6eb34747 2021-08-05 op b->name = sym;
307 6eb34747 2021-08-05 op e = TAILQ_FIRST(&envs);
308 6eb34747 2021-08-05 op TAILQ_INSERT_HEAD(&e->bindings, b, entry);
311 f9cd3e06 2021-08-04 op static inline int
312 f9cd3e06 2021-08-04 op getvar(const char *sym, struct value *v)
314 f9cd3e06 2021-08-04 op struct env *e;
315 f9cd3e06 2021-08-04 op struct binding *b;
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;
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;
331 6eb34747 2021-08-05 op static inline int
332 6eb34747 2021-08-05 op getvar_raw(const char *sym, struct op **raw)
334 6eb34747 2021-08-05 op struct env *e;
335 6eb34747 2021-08-05 op struct binding *b;
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;
346 6eb34747 2021-08-05 op return EVAL_ERR;
350 c734c0e9 2021-08-03 op global_set(char *sym, struct op *op)
352 f9cd3e06 2021-08-04 op struct binding *b;
353 f9cd3e06 2021-08-04 op struct env *e;
355 f9cd3e06 2021-08-04 op /* TODO: check for duplicates */
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))
361 f9cd3e06 2021-08-04 op b = xcalloc(1, sizeof(*b));
362 f9cd3e06 2021-08-04 op b->name = sym;
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) {
370 3a74f37a 2021-08-04 op popv(&b->val);
372 e599ffc4 2021-08-04 op memcpy(&b->val, &op->v.literal, sizeof(b->val));
374 f9cd3e06 2021-08-04 op e = TAILQ_LAST(&envs, envs);
375 f9cd3e06 2021-08-04 op TAILQ_INSERT_HEAD(&e->bindings, b, entry);
381 c734c0e9 2021-08-03 op newop(int type)
383 c734c0e9 2021-08-03 op struct op *op;
385 f53af81c 2021-08-04 op op = xcalloc(1, sizeof(*op));
386 c734c0e9 2021-08-03 op op->type = type;
392 8a2def82 2021-08-12 op free_op_rec(struct op *op)
394 8a2def82 2021-08-12 op struct op *n;
396 8a2def82 2021-08-12 op while (op != NULL) {
397 8a2def82 2021-08-12 op n = op->next;
404 c734c0e9 2021-08-03 op free_op(struct op *op)
406 8a2def82 2021-08-12 op if (op == NULL)
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:
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);
418 8a2def82 2021-08-12 op case OP_ASSERT:
419 8a2def82 2021-08-12 op free_op_rec(op->v.assert);
421 8a2def82 2021-08-12 op case OP_FUNCALL:
422 8a2def82 2021-08-12 op free_op_rec(op->v.funcall.argv);
425 8a2def82 2021-08-12 op free(op->v.var);
427 8a2def82 2021-08-12 op case OP_CAST:
428 8a2def82 2021-08-12 op free_op_rec(op->v.cast.expr);
430 8a2def82 2021-08-12 op case OP_CMP_EQ:
431 423f02f5 2021-12-28 cage case OP_CMP_LEQ:
432 423f02f5 2021-12-28 cage free_op_rec(op->v.bin_cmp.a);
433 423f02f5 2021-12-28 cage free_op_rec(op->v.bin_cmp.b);
435 8a2def82 2021-08-12 op case OP_FACCESS:
436 8a2def82 2021-08-12 op free_op_rec(op->v.faccess.expr);
437 8a2def82 2021-08-12 op free(op->v.faccess.field);
439 8a2def82 2021-08-12 op case OP_SFAIL:
440 8a2def82 2021-08-12 op free(op->v.sfail.msg);
441 8a2def82 2021-08-12 op free_op_rec(op->v.sfail.expr);
444 8a2def82 2021-08-12 op /* unreachable */
452 0e62706a 2021-08-04 op op_rest(void)
454 0e62706a 2021-08-04 op return newop(OP_REST);
458 c734c0e9 2021-08-03 op op_assign(char *sym, struct op *expr)
460 c734c0e9 2021-08-03 op struct op *op;
462 c734c0e9 2021-08-03 op op = newop(OP_ASSIGN);
463 c734c0e9 2021-08-03 op op->v.assign.name = sym;
464 c734c0e9 2021-08-03 op op->v.assign.expr = expr;
470 c734c0e9 2021-08-03 op op_assert(struct op *expr)
472 c734c0e9 2021-08-03 op struct op *op;
474 c734c0e9 2021-08-03 op op = newop(OP_ASSERT);
475 c734c0e9 2021-08-03 op op->v.assert = expr;
481 c734c0e9 2021-08-03 op op_var(char *sym)
483 c734c0e9 2021-08-03 op struct op *op;
485 c734c0e9 2021-08-03 op op = newop(OP_VAR);
486 c734c0e9 2021-08-03 op op->v.var = sym;
492 c734c0e9 2021-08-03 op op_lit_str(char *str)
494 c734c0e9 2021-08-03 op struct op *op;
496 c734c0e9 2021-08-03 op op = newop(OP_LITERAL);
497 dcb493d2 2021-08-04 op op->v.literal.type = V_STR;
498 c734c0e9 2021-08-03 op op->v.literal.v.str = str;
504 c734c0e9 2021-08-03 op op_lit_num(uint64_t n)
506 c734c0e9 2021-08-03 op struct op *op;
508 c734c0e9 2021-08-03 op op = newop(OP_LITERAL);
509 c734c0e9 2021-08-03 op op->v.literal.type = V_NUM;
510 c734c0e9 2021-08-03 op op->v.literal.v.num = n;
516 c734c0e9 2021-08-03 op op_cmp_eq(struct op *a, struct op *b)
518 c734c0e9 2021-08-03 op struct op *op;
520 c734c0e9 2021-08-03 op op = newop(OP_CMP_EQ);
521 423f02f5 2021-12-28 cage op->v.bin_cmp.a = a;
522 423f02f5 2021-12-28 cage op->v.bin_cmp.b = b;
527 423f02f5 2021-12-28 cage struct op *
528 423f02f5 2021-12-28 cage op_cmp_leq(struct op *a, struct op *b)
530 423f02f5 2021-12-28 cage struct op *op;
532 423f02f5 2021-12-28 cage op = newop(OP_CMP_LEQ);
533 423f02f5 2021-12-28 cage op->v.bin_cmp.a = a;
534 423f02f5 2021-12-28 cage op->v.bin_cmp.b = b;
540 c734c0e9 2021-08-03 op op_cast(struct op *expr, int totype)
542 c734c0e9 2021-08-03 op struct op *op;
544 c734c0e9 2021-08-03 op op = newop(OP_CAST);
545 c734c0e9 2021-08-03 op op->v.cast.expr = expr;
546 c734c0e9 2021-08-03 op op->v.cast.totype = totype;
552 acf1403a 2021-08-05 op op_faccess(struct op *expr, char *field)
554 acf1403a 2021-08-05 op struct op *op;
556 acf1403a 2021-08-05 op op = newop(OP_FACCESS);
557 acf1403a 2021-08-05 op op->v.faccess.expr = expr;
558 acf1403a 2021-08-05 op op->v.faccess.field = field;
564 8250ab19 2021-08-07 op op_sfail(struct op *expr, char *msg)
566 8250ab19 2021-08-07 op struct op *op;
568 8250ab19 2021-08-07 op op = newop(OP_SFAIL);
569 8250ab19 2021-08-07 op op->v.sfail.expr = expr;
570 8250ab19 2021-08-07 op op->v.sfail.msg = msg;
576 a9e9e3f7 2021-08-07 op op_vargs(void)
578 a9e9e3f7 2021-08-07 op struct op *op;
580 a9e9e3f7 2021-08-07 op op = newop(OP_VARGS);
586 da4de0c1 2021-08-04 op ppf_val(FILE *f, struct value *val)
590 c734c0e9 2021-08-03 op switch (val->type) {
592 da4de0c1 2021-08-04 op fprintf(f, "%s", val->v.str);
595 da4de0c1 2021-08-04 op fprintf(f, "\"%s\"", val->v.str);
598 ae3939af 2021-08-04 op fprintf(f, "%"PRIi64, val->v.num);
601 ae3939af 2021-08-04 op fprintf(f, "%"PRIu8, val->v.u8);
604 ae3939af 2021-08-04 op fprintf(f, "%"PRIu16, val->v.u16);
607 ae3939af 2021-08-04 op fprintf(f, "%"PRIu32, val->v.u32);
610 9820edbf 2021-08-06 op fprintf(f, "(");
611 9820edbf 2021-08-06 op for (i = 0; i < val->v.msg.len; ++i)
612 9820edbf 2021-08-06 op fprintf(f, "%x%s", val->v.msg.msg[i],
613 9820edbf 2021-08-06 op i == val->v.msg.len-1 ? "" : " ");
614 9820edbf 2021-08-06 op fprintf(f, ")");
616 983e73a6 2021-08-08 op case V_QIDVEC:
617 983e73a6 2021-08-08 op fprintf(f, "qids[n=%zu]", val->v.qidvec.len);
620 da4de0c1 2021-08-04 op fprintf(f, "<unknown value>");
626 da4de0c1 2021-08-04 op pp_val(struct value *val)
628 da4de0c1 2021-08-04 op ppf_val(stdout, val);
632 47c583a9 2021-08-07 op val_type(struct value *v)
634 47c583a9 2021-08-07 op switch (v->type) {
635 47c583a9 2021-08-07 op case V_SYM: return "symbol";
636 47c583a9 2021-08-07 op case V_STR: return "string";
637 47c583a9 2021-08-07 op case V_NUM: return "number";
638 47c583a9 2021-08-07 op case V_MSG: return "message";
639 47c583a9 2021-08-07 op case V_QID: return "qid";
640 47c583a9 2021-08-07 op case V_U8: return "u8";
641 47c583a9 2021-08-07 op case V_U16: return "u16";
642 47c583a9 2021-08-07 op case V_U32: return "u32";
643 47c583a9 2021-08-07 op default: return "unknown";
648 c734c0e9 2021-08-03 op val_trueish(struct value *a)
650 8ec0e863 2021-12-02 op if (val_isnum(a))
651 8ec0e863 2021-12-02 op return val_tonum(a);
656 c734c0e9 2021-08-03 op val_isnum(struct value *a)
658 c734c0e9 2021-08-03 op return a->type == V_NUM
659 c734c0e9 2021-08-03 op || a->type == V_U8
660 c734c0e9 2021-08-03 op || a->type == V_U16
661 c734c0e9 2021-08-03 op || a->type == V_U32;
665 309658f3 2021-08-04 op val_tonum(struct value *a)
667 309658f3 2021-08-04 op switch (a->type) {
668 309658f3 2021-08-04 op case V_NUM: return a->v.num;
669 309658f3 2021-08-04 op case V_U8: return a->v.u8;
670 309658f3 2021-08-04 op case V_U16: return a->v.u16;
671 309658f3 2021-08-04 op case V_U32: return a->v.u32;
673 f3289b7e 2021-08-06 op before_printing();
674 309658f3 2021-08-04 op fprintf(stderr, "%s: given value is not a number\n", __func__);
680 c734c0e9 2021-08-03 op val_eq(struct value *a, struct value *b)
682 c734c0e9 2021-08-03 op if (val_isnum(a) && val_isnum(b))
683 309658f3 2021-08-04 op return val_tonum(a) == val_tonum(b);
685 c734c0e9 2021-08-03 op if (a->type != b->type)
688 c734c0e9 2021-08-03 op switch (a->type) {
691 c734c0e9 2021-08-03 op return !strcmp(a->v.str, b->v.str);
698 423f02f5 2021-12-28 cage val_leq(struct value *a, struct value *b)
700 423f02f5 2021-12-28 cage if (val_isnum(a) && val_isnum(b))
701 423f02f5 2021-12-28 cage return val_tonum(a) <= val_tonum(b);
705 da4de0c1 2021-08-04 op static inline const char *
706 da4de0c1 2021-08-04 op pp_totype(int totype)
709 da4de0c1 2021-08-04 op * Not all of these are valid cast type thought, including
710 da4de0c1 2021-08-04 op * every possibility only to aid debugging.
712 da4de0c1 2021-08-04 op switch (totype) {
713 da4de0c1 2021-08-04 op case V_STR: return "str";
714 da4de0c1 2021-08-04 op case V_SYM: return "sym";
715 da4de0c1 2021-08-04 op case V_NUM: return "num";
716 da4de0c1 2021-08-04 op case V_QID: return "qid";
717 da4de0c1 2021-08-04 op case V_U8: return "u8";
718 da4de0c1 2021-08-04 op case V_U16: return "u16";
719 da4de0c1 2021-08-04 op case V_U32: return "u32";
720 da4de0c1 2021-08-04 op default: return "unknown";
725 da4de0c1 2021-08-04 op val_cast(struct value *a, int totype)
729 ae3939af 2021-08-04 op #define NUMCAST(val, t, c, totype, max) do { \
730 ae3939af 2021-08-04 op if (val > max) { \
731 f3289b7e 2021-08-06 op before_printing(); \
732 ae3939af 2021-08-04 op fprintf(stderr, "can't cast %"PRIu64 \
733 ae3939af 2021-08-04 op " to %s\n", val, pp_totype(totype)); \
734 ae3939af 2021-08-04 op return EVAL_ERR; \
736 ae3939af 2021-08-04 op a->type = totype; \
737 ae3939af 2021-08-04 op a->v.t = (c)val; \
738 ae3939af 2021-08-04 op return EVAL_OK; \
741 652f7308 2021-08-07 op if (a->type == totype)
742 652f7308 2021-08-07 op return EVAL_OK;
744 da4de0c1 2021-08-04 op if (!val_isnum(a)) {
745 f3289b7e 2021-08-06 op before_printing();
746 04a9c38f 2021-08-04 op fprintf(stderr, "can't cast ");
747 da4de0c1 2021-08-04 op ppf_val(stderr, a);
748 da4de0c1 2021-08-04 op fprintf(stderr, " to type %s\n", pp_totype(totype));
749 da4de0c1 2021-08-04 op return EVAL_ERR;
752 da4de0c1 2021-08-04 op v = a->v.num;
753 da4de0c1 2021-08-04 op switch (totype) {
754 ae3939af 2021-08-04 op case V_U8: NUMCAST(v, u8, uint8_t, totype, UINT8_MAX);
755 ae3939af 2021-08-04 op case V_U16: NUMCAST(v, u16, uint16_t, totype, UINT16_MAX);
756 ae3939af 2021-08-04 op case V_U32: NUMCAST(v, u32, uint32_t, totype, UINT32_MAX);
758 f3289b7e 2021-08-06 op before_printing();
759 04a9c38f 2021-08-04 op fprintf(stderr, "can't cast %"PRIu64" to %s\n",
760 da4de0c1 2021-08-04 op v, pp_totype(totype));
761 da4de0c1 2021-08-04 op return EVAL_ERR;
764 da4de0c1 2021-08-04 op #undef NUMCAST
768 acf1403a 2021-08-05 op val_faccess(struct value *a, const char *field, struct value *ret)
770 983e73a6 2021-08-08 op uint8_t mtype;
771 983e73a6 2021-08-08 op uint16_t len;
772 983e73a6 2021-08-08 op const char *errstr;
774 d8d5d55f 2021-08-07 op #define MSGTYPE(m) *(m.msg + 4) /* skip the length */
776 acf1403a 2021-08-05 op switch (a->type) {
778 acf1403a 2021-08-05 op /* TODO: add path. needs uint64_t values thought! */
779 acf1403a 2021-08-05 op if (!strcmp(field, "vers")) {
780 acf1403a 2021-08-05 op ret->type = V_U32;
781 acf1403a 2021-08-05 op memcpy(&ret->v.u32, a->v.qid+1, 4);
782 47c583a9 2021-08-07 op return EVAL_OK;
783 acf1403a 2021-08-05 op } else if (!strcmp(field, "type")) {
784 acf1403a 2021-08-05 op ret->type = V_U8;
785 acf1403a 2021-08-05 op ret->v.u8 = *a->v.qid;
786 47c583a9 2021-08-07 op return EVAL_OK;
791 a4273600 2021-08-07 op mtype = MSGTYPE(a->v.msg);
792 d1355133 2021-08-07 op if (!strcmp(field, "type")) {
793 d1355133 2021-08-07 op ret->type = V_U8;
794 d8d5d55f 2021-08-07 op ret->v.u8 = MSGTYPE(a->v.msg);
795 47c583a9 2021-08-07 op return EVAL_OK;
796 2cb7d94c 2021-08-07 op } else if (!strcmp(field, "tag")) {
797 2cb7d94c 2021-08-07 op ret->type = V_U16;
798 2cb7d94c 2021-08-07 op memcpy(&ret->v.u16, &a->v.msg.msg[5], 2);
799 2cb7d94c 2021-08-07 op ret->v.u16 = le16toh(ret->v.u16);
800 d8d5d55f 2021-08-07 op return EVAL_OK;
801 a4273600 2021-08-07 op } else if (!strcmp(field, "msize") && mtype == Rversion) {
802 d8d5d55f 2021-08-07 op ret->type = V_U32;
803 d8d5d55f 2021-08-07 op memcpy(&ret->v.u32, &a->v.msg.msg[7], 4);
804 d8d5d55f 2021-08-07 op ret->v.u32 = le32toh(ret->v.u32);
805 2cb7d94c 2021-08-07 op return EVAL_OK;
806 a4273600 2021-08-07 op } else if (!strcmp(field, "qid") && mtype == Rattach) {
807 a4273600 2021-08-07 op ret->type = V_QID;
808 a4273600 2021-08-07 op memcpy(&ret->v.qid, &a->v.msg.msg[7], QIDSIZE);
809 983e73a6 2021-08-08 op return EVAL_OK;
810 983e73a6 2021-08-08 op } else if (!strcmp(field, "nwqid") && mtype == Rwalk) {
811 983e73a6 2021-08-08 op ret->type = V_U16;
812 983e73a6 2021-08-08 op memcpy(&ret->v.u16, &a->v.msg.msg[7], 2);
813 983e73a6 2021-08-08 op ret->v.u16 = le16toh(ret->v.u16);
814 a4273600 2021-08-07 op return EVAL_OK;
815 983e73a6 2021-08-08 op } else if (!strcmp(field, "wqid") && mtype == Rwalk) {
816 983e73a6 2021-08-08 op ret->type = V_QIDVEC;
817 983e73a6 2021-08-08 op ret->v.qidvec.start = &a->v.msg.msg[9];
818 983e73a6 2021-08-08 op memcpy(&len, &a->v.msg.msg[7], 2);
819 983e73a6 2021-08-08 op len = le16toh(len);
820 983e73a6 2021-08-08 op ret->v.qidvec.len = len;
821 983e73a6 2021-08-08 op return EVAL_OK;
825 983e73a6 2021-08-08 op case V_QIDVEC:
826 983e73a6 2021-08-08 op len = strtonum(field, 0, MAXWELEM, &errstr);
827 983e73a6 2021-08-08 op if (errstr != NULL) {
828 983e73a6 2021-08-08 op before_printing();
829 983e73a6 2021-08-08 op printf("can't access qid #%s: %s\n", field, errstr);
830 983e73a6 2021-08-08 op return EVAL_ERR;
833 983e73a6 2021-08-08 op if (len >= a->v.qidvec.len) {
834 983e73a6 2021-08-08 op before_printing();
835 983e73a6 2021-08-08 op printf("can't access qid #%d: out-of-bound "
836 983e73a6 2021-08-08 op "(max %zu)\n", len, a->v.qidvec.len);
837 983e73a6 2021-08-08 op return EVAL_ERR;
840 983e73a6 2021-08-08 op ret->type = V_QID;
841 983e73a6 2021-08-08 op memcpy(&ret->v.qid, a->v.qidvec.start + len * QIDSIZE,
844 983e73a6 2021-08-08 op return EVAL_OK;
850 47c583a9 2021-08-07 op before_printing();
851 47c583a9 2021-08-07 op printf("can't access field `%s' on type %s (", field, val_type(a));
853 47c583a9 2021-08-07 op printf(")\n");
854 47c583a9 2021-08-07 op return EVAL_ERR;
856 d8d5d55f 2021-08-07 op #undef MSGTYPE
860 c734c0e9 2021-08-03 op pp_op(struct op *op)
862 3e23847c 2021-08-04 op struct op *aux;
864 c734c0e9 2021-08-03 op switch (op->type) {
865 0e62706a 2021-08-04 op case OP_REST:
866 0e62706a 2021-08-04 op printf("...");
868 c734c0e9 2021-08-03 op case OP_ASSIGN:
869 c734c0e9 2021-08-03 op printf("%s = ", op->v.assign.name);
870 c734c0e9 2021-08-03 op pp_op(op->v.assign.expr);
872 c734c0e9 2021-08-03 op case OP_ASSERT:
873 c734c0e9 2021-08-03 op printf("assert ");
874 c734c0e9 2021-08-03 op pp_op(op->v.assert);
876 c734c0e9 2021-08-03 op case OP_FUNCALL:
877 3e23847c 2021-08-04 op printf("funcall %s(", op->v.funcall.proc->name);
878 3e23847c 2021-08-04 op for (aux = op->v.funcall.argv; aux != NULL; aux = aux->next) {
880 3e23847c 2021-08-04 op if (aux->next != NULL)
881 3e23847c 2021-08-04 op printf(", ");
885 c734c0e9 2021-08-03 op case OP_LITERAL:
886 c734c0e9 2021-08-03 op pp_val(&op->v.literal);
889 c734c0e9 2021-08-03 op printf("%s", op->v.var);
891 c734c0e9 2021-08-03 op case OP_CAST:
892 c734c0e9 2021-08-03 op pp_op(op->v.cast.expr);
894 c734c0e9 2021-08-03 op switch (op->v.cast.totype) {
895 c734c0e9 2021-08-03 op case V_U8: printf("u8"); break;
896 c734c0e9 2021-08-03 op case V_U16: printf("u16"); break;
897 c734c0e9 2021-08-03 op case V_U32: printf("u32"); break;
898 c734c0e9 2021-08-03 op case V_STR: printf("str"); break;
899 c734c0e9 2021-08-03 op default: printf("???"); break;
902 c734c0e9 2021-08-03 op case OP_CMP_EQ:
903 423f02f5 2021-12-28 cage pp_op(op->v.bin_cmp.a);
904 c734c0e9 2021-08-03 op printf(" == ");
905 423f02f5 2021-12-28 cage pp_op(op->v.bin_cmp.b);
907 423f02f5 2021-12-28 cage case OP_CMP_LEQ:
908 423f02f5 2021-12-28 cage pp_op(op->v.bin_cmp.a);
909 423f02f5 2021-12-28 cage printf(" <= ");
910 423f02f5 2021-12-28 cage pp_op(op->v.bin_cmp.b);
912 acf1403a 2021-08-05 op case OP_FACCESS:
913 acf1403a 2021-08-05 op pp_op(op->v.faccess.expr);
914 acf1403a 2021-08-05 op printf(".%s", op->v.faccess.field);
916 8250ab19 2021-08-07 op case OP_SFAIL:
917 8250ab19 2021-08-07 op printf("should-fail ");
918 8250ab19 2021-08-07 op pp_op(op->v.sfail.expr);
919 8250ab19 2021-08-07 op if (op->v.sfail.msg != NULL)
920 8250ab19 2021-08-07 op printf(": \"%s\"", op->v.sfail.msg);
922 a9e9e3f7 2021-08-07 op case OP_VARGS:
923 a9e9e3f7 2021-08-07 op printf("vargs");
926 c734c0e9 2021-08-03 op printf(" ???[%d] ", op->type);
931 c734c0e9 2021-08-03 op pp_block(struct op *op)
933 c734c0e9 2021-08-03 op while (op != NULL) {
934 c734c0e9 2021-08-03 op printf("> ");
936 c734c0e9 2021-08-03 op printf("\n");
938 c734c0e9 2021-08-03 op op = op->next;
943 c734c0e9 2021-08-03 op eval(struct op *op)
945 c734c0e9 2021-08-03 op struct value a, b;
946 c734c0e9 2021-08-03 op struct proc *proc;
947 29c35556 2021-08-07 op struct op *t, *tnext;
952 c734c0e9 2021-08-03 op printf("\n");
955 c734c0e9 2021-08-03 op switch (op->type) {
956 6eb34747 2021-08-05 op case OP_REST:
958 c31f55f5 2021-08-07 op * Try to load the rest argument. Note that it can be
961 c31f55f5 2021-08-07 op if ((ret = getvar_raw("...", &t)) == EVAL_OK)
962 c31f55f5 2021-08-07 op if ((ret = eval(t)) != EVAL_OK)
966 c734c0e9 2021-08-03 op case OP_ASSIGN:
967 f9cd3e06 2021-08-04 op ret = setvar(op->v.assign.name, op->v.assign.expr);
968 f9cd3e06 2021-08-04 op if (ret != EVAL_OK)
972 c734c0e9 2021-08-03 op case OP_ASSERT:
973 333d8d7d 2021-08-04 op if ((ret = eval(op->v.assert)) != EVAL_OK)
976 c734c0e9 2021-08-03 op if (!val_trueish(&a)) {
977 f3289b7e 2021-08-06 op before_printing();
978 c734c0e9 2021-08-03 op printf("assertion failed: ");
979 c734c0e9 2021-08-03 op pp_op(op->v.assert);
980 c734c0e9 2021-08-03 op printf("\n");
981 333d8d7d 2021-08-04 op return EVAL_ERR;
985 c734c0e9 2021-08-03 op case OP_FUNCALL:
986 349fd94e 2021-08-05 op /* assume airity matches */
988 f9cd3e06 2021-08-04 op proc = op->v.funcall.proc;
989 9af2cde2 2021-08-04 op if (proc->nativefn != NULL) {
991 6eb34747 2021-08-05 op * Push arguments on the stack for builtin
992 6eb34747 2021-08-05 op * functions. Counting the height of the
993 6eb34747 2021-08-05 op * stack is done to compute the correct number
994 6eb34747 2021-08-05 op * in the vararg case. argc only counts the
995 6eb34747 2021-08-05 op * "syntactical" arguments, i.e. foo(x, ...)
996 6eb34747 2021-08-05 op * has argc == 2, but at runtime argc may be
997 6eb34747 2021-08-05 op * 1, 2 or a greater number!
1001 219cbeaa 2021-08-04 op t = op->v.funcall.argv;
1002 219cbeaa 2021-08-04 op if (t != NULL && (ret = eval(t)) != EVAL_OK)
1004 6eb34747 2021-08-05 op i = stackh - i;
1006 6eb34747 2021-08-05 op assert(i >= 0);
1008 6eb34747 2021-08-05 op if ((ret = proc->nativefn(i))
1012 91cfe5ca 2021-08-06 op if (proc->body == NULL) {
1013 91cfe5ca 2021-08-06 op before_printing();
1014 91cfe5ca 2021-08-06 op printf("warn: calling the empty proc `%s'\n",
1015 91cfe5ca 2021-08-06 op proc->name);
1021 219cbeaa 2021-08-04 op for (t = op->v.funcall.argv, i = 0;
1023 219cbeaa 2021-08-04 op t = t->next, i++) {
1025 6eb34747 2021-08-05 op * Push a pseudo variable `...' (and
1026 6eb34747 2021-08-05 op * don't evaluate it) in the vararg
1027 6eb34747 2021-08-05 op * case. A special case is when the
1028 6eb34747 2021-08-05 op * variable is itself `...'.
1030 6eb34747 2021-08-05 op if (proc->vararg && i == proc->minargs) {
1031 6eb34747 2021-08-05 op if (t->type != OP_REST)
1032 6eb34747 2021-08-05 op setvar_raw(xstrdup("..."), t);
1037 29c35556 2021-08-07 op * The arguments are a linked list of
1038 29c35556 2021-08-07 op * ops. Setvar will call eval that
1039 29c35556 2021-08-07 op * will evaluate *all* the arguments.
1040 29c35556 2021-08-07 op * The dance here that sets next to
1041 29c35556 2021-08-07 op * NULL and then restores it is to
1042 29c35556 2021-08-07 op * avoid this behaviour.
1044 29c35556 2021-08-07 op tnext = t->next;
1045 29c35556 2021-08-07 op t->next = NULL;
1046 29c35556 2021-08-07 op ret = setvar(proc->args[i], t);
1047 29c35556 2021-08-07 op t->next = tnext;
1049 29c35556 2021-08-07 op if (ret != EVAL_OK)
1053 9af2cde2 2021-08-04 op if ((ret = eval(proc->body)) != EVAL_OK)
1061 c734c0e9 2021-08-03 op case OP_LITERAL:
1062 c734c0e9 2021-08-03 op pushv(&op->v.literal);
1065 c734c0e9 2021-08-03 op case OP_VAR:
1066 f9cd3e06 2021-08-04 op if ((ret = getvar(op->v.var, &a)) != EVAL_OK)
1071 c734c0e9 2021-08-03 op case OP_CAST:
1072 da4de0c1 2021-08-04 op if ((ret = eval(op->v.cast.expr)) != EVAL_OK)
1075 da4de0c1 2021-08-04 op if ((ret = val_cast(&a, op->v.cast.totype)) != EVAL_OK)
1080 c734c0e9 2021-08-03 op case OP_CMP_EQ:
1081 423f02f5 2021-12-28 cage if ((ret = eval(op->v.bin_cmp.a)) != EVAL_OK)
1083 423f02f5 2021-12-28 cage if ((ret = eval(op->v.bin_cmp.b)) != EVAL_OK)
1088 c734c0e9 2021-08-03 op pushbool(val_eq(&a, &b));
1091 423f02f5 2021-12-28 cage case OP_CMP_LEQ:
1092 423f02f5 2021-12-28 cage if ((ret = eval(op->v.bin_cmp.a)) != EVAL_OK)
1093 423f02f5 2021-12-28 cage return ret;
1094 423f02f5 2021-12-28 cage if ((ret = eval(op->v.bin_cmp.b)) != EVAL_OK)
1095 423f02f5 2021-12-28 cage return ret;
1099 423f02f5 2021-12-28 cage pushbool(val_leq(&a, &b));
1102 acf1403a 2021-08-05 op case OP_FACCESS:
1103 acf1403a 2021-08-05 op if ((ret = eval(op->v.faccess.expr)) != EVAL_OK)
1106 acf1403a 2021-08-05 op if ((ret = val_faccess(&a, op->v.faccess.field, &b))
1112 8250ab19 2021-08-07 op case OP_SFAIL:
1113 8250ab19 2021-08-07 op if ((ret = eval(op->v.sfail.expr)) == EVAL_OK) {
1114 8250ab19 2021-08-07 op before_printing();
1115 8250ab19 2021-08-07 op printf("expecting failure");
1116 8250ab19 2021-08-07 op if (op->v.sfail.msg != NULL)
1117 8250ab19 2021-08-07 op printf(" \"%s\"", op->v.sfail.msg);
1118 8250ab19 2021-08-07 op printf("\n");
1119 8250ab19 2021-08-07 op printf("expression: ");
1120 8250ab19 2021-08-07 op pp_op(op->v.sfail.expr);
1121 8250ab19 2021-08-07 op printf("\n");
1122 8250ab19 2021-08-07 op return EVAL_ERR;
1124 8250ab19 2021-08-07 op if (ret == EVAL_SKIP)
1128 a9e9e3f7 2021-08-07 op case OP_VARGS:
1129 a9e9e3f7 2021-08-07 op if ((ret = getvar_raw("...", &t)) == EVAL_OK) {
1130 a9e9e3f7 2021-08-07 op for (i = 0; t != NULL; t = t->next)
1138 f3289b7e 2021-08-06 op before_printing();
1139 e9f9c9b1 2021-08-04 op fprintf(stderr, "invalid op, aborting.\n");
1143 c734c0e9 2021-08-03 op if (op->next)
1144 c734c0e9 2021-08-03 op return eval(op->next);
1145 333d8d7d 2021-08-04 op return EVAL_OK;
1149 d9d02161 2021-08-04 op prepare_funcall(void)
1151 d9d02161 2021-08-04 op pushstack(&args);
1155 c734c0e9 2021-08-03 op push_arg(struct op *op)
1157 d9d02161 2021-08-04 op push(&args, op);
1161 d9d02161 2021-08-04 op op_funcall(struct proc *proc)
1163 d9d02161 2021-08-04 op struct op *op, *argv;
1166 d9d02161 2021-08-04 op argv = finalize(&args, &argc);
1168 c734c0e9 2021-08-03 op op = newop(OP_FUNCALL);
1169 c734c0e9 2021-08-03 op op->v.funcall.proc = proc;
1170 d9d02161 2021-08-04 op op->v.funcall.argv = argv;
1171 d9d02161 2021-08-04 op op->v.funcall.argc = argc;
1177 54736a95 2021-08-04 op add_builtin_proc(const char *name, int (*fn)(int), int argc, int vararg)
1179 c734c0e9 2021-08-03 op struct proc *proc;
1181 c734c0e9 2021-08-03 op proc = xcalloc(1, sizeof(*proc));
1182 c734c0e9 2021-08-03 op proc->name = xstrdup(name);
1183 c734c0e9 2021-08-03 op proc->nativefn = fn;
1184 126080b7 2021-08-04 op proc->minargs = argc;
1185 54736a95 2021-08-04 op proc->vararg = vararg;
1187 c734c0e9 2021-08-03 op TAILQ_INSERT_HEAD(&procs, proc, entry);
1191 d9d02161 2021-08-04 op prepare_proc(void)
1193 d9d02161 2021-08-04 op pushstack(&args);
1197 c734c0e9 2021-08-03 op proc_setup_body(void)
1199 d9d02161 2021-08-04 op struct opstack *argv;
1200 d9d02161 2021-08-04 op struct op *op;
1203 d9d02161 2021-08-04 op argv = peek(&args);
1204 d9d02161 2021-08-04 op for (i = 0, op = argv->base.next; op != NULL; i++) {
1206 0e62706a 2021-08-04 op * TODO: should free the whole list on error but..,
1207 0e62706a 2021-08-04 op * we're gonna exit real soon(tm)!
1209 0e62706a 2021-08-04 op if (op->type != OP_VAR && op->type != OP_REST)
1212 c8878182 2021-08-04 op op = op->next;
1215 d9d02161 2021-08-04 op assert(i == argv->counter);
1216 d9d02161 2021-08-04 op pushstack(&blocks);
1221 d9d02161 2021-08-04 op proc_done(char *name)
1223 d9d02161 2021-08-04 op struct proc *proc;
1224 d9d02161 2021-08-04 op struct op *op, *next, *argv, *body;
1225 d9d02161 2021-08-04 op int i, argc;
1227 d9d02161 2021-08-04 op argv = finalize(&args, &argc);
1228 d9d02161 2021-08-04 op body = finalize(&blocks, NULL);
1230 d9d02161 2021-08-04 op proc = xcalloc(1, sizeof(*proc));
1231 d9d02161 2021-08-04 op proc->name = name;
1232 d9d02161 2021-08-04 op proc->minargs = argc;
1234 b99bdaa1 2021-08-04 op for (i = 0, op = argv; op != NULL; ++i) {
1235 0e62706a 2021-08-04 op if (op->type == OP_REST) {
1236 0e62706a 2021-08-04 op proc->vararg = 1;
1237 0e62706a 2021-08-04 op proc->minargs = i;
1241 d9d02161 2021-08-04 op proc->args[i] = xstrdup(op->v.var);
1243 d9d02161 2021-08-04 op next = op->next;
1244 d9d02161 2021-08-04 op free_op(op);
1247 0e62706a 2021-08-04 op assert(i == argc || (proc->vararg && i == proc->minargs));
1249 d9d02161 2021-08-04 op proc->body = body;
1251 d9d02161 2021-08-04 op TAILQ_INSERT_HEAD(&procs, proc, entry);
1255 c734c0e9 2021-08-03 op block_push(struct op *op)
1257 d9d02161 2021-08-04 op push(&blocks, op);
1260 c734c0e9 2021-08-03 op struct proc *
1261 c734c0e9 2021-08-03 op proc_by_name(const char *name)
1263 c734c0e9 2021-08-03 op struct proc *p;
1265 c734c0e9 2021-08-03 op TAILQ_FOREACH(p, &procs, entry) {
1266 c734c0e9 2021-08-03 op if (!strcmp(p->name, name))
1270 c734c0e9 2021-08-03 op return NULL;
1274 d9d02161 2021-08-04 op prepare_test(void)
1276 d9d02161 2021-08-04 op pushstack(&blocks);
1280 0b453b63 2021-08-07 op test_done(int shouldfail, char *name, char *dir)
1282 d9d02161 2021-08-04 op struct test *test;
1284 d9d02161 2021-08-04 op test = xcalloc(1, sizeof(*test));
1285 0b453b63 2021-08-07 op test->shouldfail = shouldfail;
1286 d9d02161 2021-08-04 op test->name = name;
1287 d9d02161 2021-08-04 op test->dir = dir;
1288 d9d02161 2021-08-04 op test->body = finalize(&blocks, NULL);
1290 5e5c37b5 2021-08-04 op if (TAILQ_EMPTY(&tests))
1291 5e5c37b5 2021-08-04 op TAILQ_INSERT_HEAD(&tests, test, entry);
1293 5e5c37b5 2021-08-04 op TAILQ_INSERT_TAIL(&tests, test, entry);
1299 54736a95 2021-08-04 op builtin_print(int argc)
1301 54736a95 2021-08-04 op struct value v;
1304 f3289b7e 2021-08-06 op before_printing();
1306 54736a95 2021-08-04 op for (i = argc; i > 0; --i) {
1307 54736a95 2021-08-04 op peekn(i, &v);
1308 54736a95 2021-08-04 op if (v.type == V_STR)
1309 54736a95 2021-08-04 op printf("%s", v.v.str);
1312 54736a95 2021-08-04 op printf(" ");
1315 ce030684 2021-08-04 op printf("\n");
1317 54736a95 2021-08-04 op popvn(argc);
1319 dd1d2343 2021-08-05 op return EVAL_OK;
1323 dd1d2343 2021-08-05 op builtin_debug(int argc)
1326 dd1d2343 2021-08-05 op return builtin_print(argc);
1328 dd1d2343 2021-08-05 op popvn(argc);
1329 333d8d7d 2021-08-04 op return EVAL_OK;
1333 ce030684 2021-08-04 op builtin_skip(int argc)
1335 ce030684 2021-08-04 op return EVAL_SKIP;
1339 6019438a 2021-08-05 op builtin_iota(int argc)
1341 6019438a 2021-08-05 op struct value v;
1343 582b509f 2021-08-07 op v.type = V_U16;
1344 582b509f 2021-08-07 op if ((v.v.u16 = ++lasttag) == 255)
1345 582b509f 2021-08-07 op v.v.u16 = ++lasttag;
1348 6019438a 2021-08-05 op return EVAL_OK;
1352 9820edbf 2021-08-06 op builtin_send(int argc)
1354 9820edbf 2021-08-06 op struct ibuf *buf;
1355 9820edbf 2021-08-06 op struct value v;
1356 9820edbf 2021-08-06 op uint32_t len;
1357 9820edbf 2021-08-06 op uint16_t slen;
1360 370b4f2e 2021-08-07 op check_for_output();
1363 9820edbf 2021-08-06 op * Compute the length of the packet. 4 is for the initial
1364 9820edbf 2021-08-06 op * length field
1368 9820edbf 2021-08-06 op for (i = argc; i > 0; --i) {
1369 9820edbf 2021-08-06 op peekn(i, &v);
1370 9820edbf 2021-08-06 op switch (v.type) {
1372 9820edbf 2021-08-06 op len += 2; /* count */
1373 9820edbf 2021-08-06 op len += strlen(v.v.str);
1389 9820edbf 2021-08-06 op before_printing();
1390 9820edbf 2021-08-06 op printf("%s: can't serialize ", __func__);
1392 9820edbf 2021-08-06 op printf("\n");
1393 9820edbf 2021-08-06 op return EVAL_ERR;
1397 9820edbf 2021-08-06 op if (len > UINT16_MAX) {
1398 9820edbf 2021-08-06 op before_printing();
1399 9820edbf 2021-08-06 op printf("%s: message size too long: got %d when max is %d\n",
1400 9820edbf 2021-08-06 op __func__, len, UINT16_MAX);
1401 9820edbf 2021-08-06 op return EVAL_ERR;
1404 9820edbf 2021-08-06 op if ((buf = imsg_create(&ibuf, IMSG_BUF, 0, 0, len)) == NULL)
1405 9820edbf 2021-08-06 op fatal("imsg_create(%d)", len);
1407 34aba5f7 2021-08-06 op len = htole32(len);
1408 9820edbf 2021-08-06 op imsg_add(buf, &len, sizeof(len));
1410 9820edbf 2021-08-06 op for (i = argc; i > 0; --i) {
1411 9820edbf 2021-08-06 op peekn(i, &v);
1412 9820edbf 2021-08-06 op switch (v.type) {
1414 9820edbf 2021-08-06 op slen = strlen(v.v.str);
1415 9820edbf 2021-08-06 op slen = htole16(slen);
1416 9820edbf 2021-08-06 op imsg_add(buf, &slen, sizeof(slen));
1417 9820edbf 2021-08-06 op imsg_add(buf, v.v.str, strlen(v.v.str));
1421 9820edbf 2021-08-06 op imsg_add(buf, &v.v.u8, 1);
1425 9820edbf 2021-08-06 op v.v.u16 = htole16(v.v.u16);
1426 9820edbf 2021-08-06 op imsg_add(buf, &v.v.u16, 2);
1430 9820edbf 2021-08-06 op v.v.u32 = htole32(v.v.u32);
1431 9820edbf 2021-08-06 op imsg_add(buf, &v.v.u32, 4);
1436 9820edbf 2021-08-06 op imsg_close(&ibuf, buf);
1438 9820edbf 2021-08-06 op if (imsg_flush(&ibuf) == -1) {
1440 9820edbf 2021-08-06 op before_printing();
1441 9820edbf 2021-08-06 op printf("%s: imsg_flush failed: %s\n", __func__, strerror(i));
1442 9820edbf 2021-08-06 op return EVAL_ERR;
1445 370b4f2e 2021-08-07 op check_for_output();
1446 9820edbf 2021-08-06 op return EVAL_OK;
1450 9820edbf 2021-08-06 op builtin_recv(int argc)
1452 9820edbf 2021-08-06 op struct pollfd pfd;
1453 9820edbf 2021-08-06 op struct value v;
1454 9820edbf 2021-08-06 op struct imsg imsg;
1455 9820edbf 2021-08-06 op ssize_t n, datalen;
1458 9820edbf 2021-08-06 op if (lastmsg != NULL) {
1459 9820edbf 2021-08-06 op free(lastmsg);
1460 9820edbf 2021-08-06 op lastmsg = NULL;
1463 9820edbf 2021-08-06 op pfd.fd = ibuf.fd;
1464 9820edbf 2021-08-06 op pfd.events = POLLIN;
1465 9820edbf 2021-08-06 op if (poll(&pfd, 1, INFTIM) == -1) {
1466 9820edbf 2021-08-06 op serrno = errno;
1467 9820edbf 2021-08-06 op before_printing();
1468 9820edbf 2021-08-06 op printf("%s: poll failed: %s\n", __func__, strerror(serrno));
1469 9820edbf 2021-08-06 op return EVAL_ERR;
1473 9820edbf 2021-08-06 op if ((n = imsg_read(&ibuf)) == -1) {
1474 9820edbf 2021-08-06 op if (errno == EAGAIN)
1476 9820edbf 2021-08-06 op fatal("imsg_read");
1478 9820edbf 2021-08-06 op if (n == 0) {
1480 9820edbf 2021-08-06 op before_printing();
1481 9820edbf 2021-08-06 op printf("child disconnected\n");
1482 9820edbf 2021-08-06 op return EVAL_ERR;
1485 eed75362 2021-08-06 op nextmessage:
1486 370b4f2e 2021-08-07 op check_for_output();
1488 9820edbf 2021-08-06 op /* read only one message */
1489 9820edbf 2021-08-06 op if ((n = imsg_get(&ibuf, &imsg)) == -1)
1490 9820edbf 2021-08-06 op fatal("imsg_get");
1492 9820edbf 2021-08-06 op goto disconnect;
1494 9820edbf 2021-08-06 op datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
1495 9820edbf 2021-08-06 op switch (imsg.hdr.type) {
1496 9820edbf 2021-08-06 op case IMSG_BUF:
1497 9820edbf 2021-08-06 op v.type = V_MSG;
1498 9820edbf 2021-08-06 op if ((v.v.msg.msg = malloc(datalen)) == NULL)
1499 9820edbf 2021-08-06 op fatal("malloc");
1500 9820edbf 2021-08-06 op memcpy(v.v.msg.msg, imsg.data, datalen);
1501 9820edbf 2021-08-06 op v.v.msg.len = datalen;
1503 9820edbf 2021-08-06 op imsg_free(&imsg);
1504 9820edbf 2021-08-06 op return EVAL_OK;
1506 9820edbf 2021-08-06 op case IMSG_CLOSE:
1507 9820edbf 2021-08-06 op before_printing();
1508 9820edbf 2021-08-06 op printf("subprocess closed the connection\n");
1509 9820edbf 2021-08-06 op imsg_free(&imsg);
1510 9820edbf 2021-08-06 op return EVAL_ERR;
1512 eed75362 2021-08-06 op case IMSG_MSIZE:
1513 eed75362 2021-08-06 op imsg_free(&imsg);
1514 eed75362 2021-08-06 op goto nextmessage;
1517 9820edbf 2021-08-06 op before_printing();
1518 9820edbf 2021-08-06 op printf("got unknown message from subprocess: %d\n",
1519 9820edbf 2021-08-06 op imsg.hdr.type);
1520 9820edbf 2021-08-06 op imsg_free(&imsg);
1521 9820edbf 2021-08-06 op return EVAL_ERR;
1525 9820edbf 2021-08-06 op static pid_t
1526 9820edbf 2021-08-06 op spawn_client_proc(void)
1528 9820edbf 2021-08-06 op const char *argv[4];
1529 370b4f2e 2021-08-07 op int p[2], out[2], argc = 0;
1532 370b4f2e 2021-08-07 op if (child_out != -1)
1533 370b4f2e 2021-08-07 op close(child_out);
1535 9820edbf 2021-08-06 op if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
1536 9820edbf 2021-08-06 op PF_UNSPEC, p) == -1)
1537 370b4f2e 2021-08-07 op fatal("socketpair");
1539 370b4f2e 2021-08-07 op if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
1540 370b4f2e 2021-08-07 op PF_UNSPEC, out) == -1)
1541 9820edbf 2021-08-06 op fatal("socketpair");
1543 9820edbf 2021-08-06 op switch (pid = fork()) {
1545 9820edbf 2021-08-06 op fatal("cannot fork");
1549 9820edbf 2021-08-06 op close(p[1]);
1550 370b4f2e 2021-08-07 op close(out[1]);
1551 370b4f2e 2021-08-07 op child_out = out[0];
1552 9820edbf 2021-08-06 op if (ibuf_inuse) {
1553 9820edbf 2021-08-06 op msgbuf_clear(&ibuf.w);
1554 9820edbf 2021-08-06 op close(ibuf.fd);
1556 9820edbf 2021-08-06 op imsg_init(&ibuf, p[0]);
1557 9820edbf 2021-08-06 op ibuf_inuse = 1;
1561 9820edbf 2021-08-06 op close(p[0]);
1562 370b4f2e 2021-08-07 op close(out[0]);
1564 370b4f2e 2021-08-07 op if (dup2(out[1], 1) == -1 ||
1565 370b4f2e 2021-08-07 op dup2(out[1], 2) == -1)
1566 370b4f2e 2021-08-07 op fatal("dup2");
1568 9820edbf 2021-08-06 op if (p[1] != 3) {
1569 9820edbf 2021-08-06 op if (dup2(p[1], 3) == -1)
1570 9820edbf 2021-08-06 op fatal("cannot setup imsg fd");
1571 9820edbf 2021-08-06 op } else if (fcntl(F_SETFD, 0) == -1)
1572 9820edbf 2021-08-06 op fatal("cannot setup imsg fd");
1574 9820edbf 2021-08-06 op argv[argc++] = argv0;
1575 9820edbf 2021-08-06 op argv[argc++] = "-Tc";
1578 9820edbf 2021-08-06 op argv[argc++] = "-v";
1581 9820edbf 2021-08-06 op argv[argc++] = NULL;
1583 9820edbf 2021-08-06 op execvp(argv0, (char *const *)argv);
1584 9820edbf 2021-08-06 op fatal("execvp");
1588 9820edbf 2021-08-06 op prepare_child_for_test(struct test *t)
1590 9820edbf 2021-08-06 op struct passwd *pw;
1591 9820edbf 2021-08-06 op struct stat sb;
1593 9820edbf 2021-08-06 op if (stat(t->dir, &sb) == -1)
1594 9820edbf 2021-08-06 op fatal("stat(\"%s\")", t->dir);
1596 9820edbf 2021-08-06 op if ((pw = getpwuid(sb.st_uid)) == NULL)
1597 9820edbf 2021-08-06 op fatal("getpwuid(%d)", sb.st_uid);
1599 9820edbf 2021-08-06 op imsg_compose(&ibuf, IMSG_AUTH, 0, 0, -1,
1600 9820edbf 2021-08-06 op pw->pw_name, strlen(pw->pw_name)+1);
1601 9820edbf 2021-08-06 op imsg_compose(&ibuf, IMSG_AUTH_DIR, 0, 0, -1,
1602 9820edbf 2021-08-06 op t->dir, strlen(t->dir)+1);
1604 9820edbf 2021-08-06 op if (imsg_flush(&ibuf) == -1)
1605 9820edbf 2021-08-06 op fatal("imsg_flush");
1609 c734c0e9 2021-08-03 op run_test(struct test *t)
1615 f3289b7e 2021-08-06 op before_printing();
1616 c734c0e9 2021-08-03 op puts("=====================");
1617 8e0ef4cb 2021-08-04 op pp_block(t->body);
1618 c734c0e9 2021-08-03 op puts("=====================");
1621 09e42a8d 2021-08-07 op if (stackh != 0)
1622 09e42a8d 2021-08-07 op popvn(stackh);
1624 91cfe5ca 2021-08-06 op if (t->body == NULL) {
1625 91cfe5ca 2021-08-06 op before_printing();
1626 91cfe5ca 2021-08-06 op printf("no instructions, skipping...\n");
1627 91cfe5ca 2021-08-06 op return EVAL_SKIP;
1630 9820edbf 2021-08-06 op pid = spawn_client_proc();
1631 9820edbf 2021-08-06 op prepare_child_for_test(t);
1632 9820edbf 2021-08-06 op ret = eval(t->body);
1634 eed75362 2021-08-06 op imsg_compose(&ibuf, IMSG_CONN_GONE, 0, 0, -1, NULL, 0);
1635 eed75362 2021-08-06 op imsg_flush(&ibuf);
1637 9820edbf 2021-08-06 op while (waitpid(pid, NULL, 0) != pid)
1640 370b4f2e 2021-08-07 op check_for_output();
1642 0b453b63 2021-08-07 op if (t->shouldfail) {
1643 0b453b63 2021-08-07 op if (ret == EVAL_OK) {
1644 0b453b63 2021-08-07 op before_printing();
1645 0b453b63 2021-08-07 op printf("test was expected to fail\n");
1646 0b453b63 2021-08-07 op return EVAL_ERR;
1647 0b453b63 2021-08-07 op } else if (ret == EVAL_ERR)
1648 0b453b63 2021-08-07 op return EVAL_OK;
1655 c734c0e9 2021-08-03 op main(int argc, char **argv)
1657 c734c0e9 2021-08-03 op struct test *t;
1658 f3289b7e 2021-08-06 op int ch, i, r, passed = 0, failed = 0, skipped = 0;
1659 9820edbf 2021-08-06 op int runclient = 0;
1660 32b8add4 2021-12-14 op const char *pat = NULL;
1661 32b8add4 2021-12-14 op regex_t reg;
1663 9820edbf 2021-08-06 op assert(argv0 = argv[0]);
1665 9820edbf 2021-08-06 op signal(SIGPIPE, SIG_IGN);
1667 c734c0e9 2021-08-03 op log_init(1, LOG_DAEMON);
1668 c734c0e9 2021-08-03 op log_setverbose(1);
1670 f9cd3e06 2021-08-04 op /* prepare the global env */
1673 54736a95 2021-08-04 op add_builtin_proc("print", builtin_print, 1, 1);
1674 dd1d2343 2021-08-05 op add_builtin_proc("debug", builtin_debug, 1, 1);
1675 54736a95 2021-08-04 op add_builtin_proc("skip", builtin_skip, 0, 0);
1676 6019438a 2021-08-05 op add_builtin_proc("iota", builtin_iota, 0, 0);
1677 9820edbf 2021-08-06 op add_builtin_proc("send", builtin_send, 2, 1);
1678 9820edbf 2021-08-06 op add_builtin_proc("recv", builtin_recv, 0, 0);
1680 32b8add4 2021-12-14 op while ((ch = getopt(argc, argv, "nT:vx:")) != -1) {
1681 dd1d2343 2021-08-05 op switch (ch) {
1683 4315b20a 2021-08-05 op syntaxcheck = 1;
1686 9820edbf 2021-08-06 op assert(*optarg == 'c');
1687 9820edbf 2021-08-06 op runclient = 1;
1693 32b8add4 2021-12-14 op pat = optarg;
1696 4315b20a 2021-08-05 op fprintf(stderr, "Usage: %s [-nv] [files...]\n",
1701 dd1d2343 2021-08-05 op argc -= optind;
1702 dd1d2343 2021-08-05 op argv += optind;
1704 9820edbf 2021-08-06 op if (runclient)
1705 9820edbf 2021-08-06 op client(1, debug);
1707 32b8add4 2021-12-14 op if (pat == NULL)
1710 32b8add4 2021-12-14 op if (regcomp(®, pat, REG_BASIC | REG_ICASE | REG_NOSUB) != 0)
1711 32b8add4 2021-12-14 op fatalx("invalid regexp: %s", pat);
1713 dd1d2343 2021-08-05 op for (i = 0; i < argc; ++i)
1714 c734c0e9 2021-08-03 op loadfile(argv[i]);
1716 4315b20a 2021-08-05 op if (syntaxcheck) {
1717 4315b20a 2021-08-05 op fprintf(stderr, "files OK\n");
1721 9820edbf 2021-08-06 op /* Check for root privileges. */
1722 9820edbf 2021-08-06 op if (geteuid())
1723 9820edbf 2021-08-06 op fatalx("need root privileges");
1726 c734c0e9 2021-08-03 op TAILQ_FOREACH(t, &tests, entry) {
1727 32b8add4 2021-12-14 op if (regexec(®, t->name, 0, NULL, 0) != 0)
1730 4e3f88dd 2021-12-13 op printf("===> [%d/%d] running test \"%s\"... ", i+1, ntests,
1732 e334da07 2021-08-04 op fflush(stdout);
1734 f3289b7e 2021-08-06 op filler = "\n";
1735 f3289b7e 2021-08-06 op r = run_test(t);
1736 f3289b7e 2021-08-06 op if (filler == NULL)
1737 f3289b7e 2021-08-06 op printf("=> test ");
1739 f3289b7e 2021-08-06 op switch (r) {
1740 333d8d7d 2021-08-04 op case EVAL_OK:
1741 d728769d 2021-08-07 op printf("passed\n");
1744 333d8d7d 2021-08-04 op case EVAL_ERR:
1746 f3289b7e 2021-08-06 op printf("failed\n");
1748 333d8d7d 2021-08-04 op case EVAL_SKIP:
1749 f3289b7e 2021-08-06 op printf("skipped\n");
1754 83117bfe 2021-08-07 op if (filler == NULL)
1755 83117bfe 2021-08-07 op printf("\n");
1759 f3289b7e 2021-08-06 op printf("\n");
1760 4ed3f1b8 2021-12-14 op printf("%d/%d passed (%d skipped and %d failed)\n",
1761 25b0f8d2 2021-08-07 op passed, i, skipped, failed);
1764 d41deb93 2021-08-07 op free(lastmsg);
1765 32b8add4 2021-12-14 op regfree(®);
1767 c734c0e9 2021-08-03 op return failed != 0;