Blob


1 /*
2 * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
17 #include "compat.h"
19 #include <sys/socket.h>
20 #include <sys/stat.h>
21 #include <sys/wait.h>
23 #include <assert.h>
24 #include <endian.h>
25 #include <errno.h>
26 #include <fcntl.h>
27 #include <inttypes.h>
28 #include <poll.h>
29 #include <pwd.h>
30 #include <regex.h>
31 #include <signal.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <syslog.h>
36 #include <unistd.h>
38 #include "client.h"
39 #include "kami.h"
40 #include "kamid.h"
41 #include "log.h"
42 #include "script.h"
43 #include "utils.h"
45 #define DEBUG 0
47 #ifndef INFTIM
48 #define INFTIM -1
49 #endif
51 static const char *argv0;
52 static const char *dir;
53 static uid_t uid;
55 static uint8_t *lastmsg;
57 static struct imsgbuf ibuf;
58 static int ibuf_inuse;
59 static int child_out = -1;
61 static struct procs procs = TAILQ_HEAD_INITIALIZER(procs);
62 static struct tests tests = TAILQ_HEAD_INITIALIZER(tests);
64 static int ntests;
66 static struct opstacks blocks = TAILQ_HEAD_INITIALIZER(blocks);
67 static struct opstacks args = TAILQ_HEAD_INITIALIZER(args);
69 #define STACK_HEIGHT 64
70 static struct value vstack[STACK_HEIGHT];
71 static int stackh;
73 static struct envs envs = TAILQ_HEAD_INITIALIZER(envs);
75 static struct value v_false = {.type = V_NUM, .v = {.num = 0}};
76 static struct value v_true = {.type = V_NUM, .v = {.num = 1}};
78 static uint8_t lasttag;
80 static int debug;
81 static int syntaxcheck;
83 static const char *filler;
85 static inline void
86 before_printing(void)
87 {
88 if (filler != NULL) {
89 printf("%s", filler);
90 filler = NULL;
91 }
92 }
94 static inline void
95 check_for_output(void)
96 {
97 static char buf[BUFSIZ];
98 struct pollfd pfd;
99 ssize_t r;
101 pfd.fd = child_out;
102 pfd.events = POLLIN;
103 if (poll(&pfd, 1, 0) == -1)
104 fatal("poll");
106 if (!(pfd.revents & POLLIN))
107 return;
109 for (;;) {
110 if ((r = read(child_out, buf, sizeof(buf))) == -1) {
111 if (errno == EAGAIN)
112 break;
113 fatal("read");
115 if (r == 0)
116 break;
117 before_printing();
118 fwrite(buf, 1, r, stdout);
122 static inline void
123 peekn(int depth, struct value *v)
125 if (depth > stackh)
126 errx(1, "can't peek the stack at %d: underflow",
127 depth);
128 memcpy(v, &vstack[stackh - depth], sizeof(*v));
130 #if DEBUG
131 printf("peeking(%d) ", depth); pp_val(v); printf("\n");
132 #endif
135 static inline void
136 popv(struct value *v)
138 if (stackh == 0)
139 errx(1, "can't pop the stack: underflow");
140 memcpy(v, &vstack[--stackh], sizeof(*v));
142 #if DEBUG
143 printf("popping "); pp_val(v); printf("\n");
144 #endif
147 static inline void
148 popvn(int n)
150 struct value v;
152 while (n-- > 0)
153 popv(&v);
156 static inline void
157 pushv(struct value *v)
159 if (stackh == STACK_HEIGHT)
160 errx(1, "can't push the stack: overflow");
162 #if DEBUG
163 printf("pushing "); pp_val(v); printf("\n");
164 #endif
166 memcpy(&vstack[stackh++], v, sizeof(*v));
169 static inline void
170 pushbool(int n)
172 pushv(n ? &v_true : &v_false);
175 static inline void
176 pushnum(int64_t n)
178 struct value v;
180 v.type = V_NUM;
181 v.v.num = n;
182 pushv(&v);
185 static inline struct opstack *
186 pushstack(struct opstacks *stack)
188 struct opstack *ops;
190 ops = xcalloc(1, sizeof(*ops));
191 TAILQ_INSERT_HEAD(stack, ops, entry);
192 return ops;
195 static inline struct opstack *
196 peek(struct opstacks *stack)
198 if (TAILQ_EMPTY(stack))
199 errx(1, "%s: args underflow", __func__);
201 return TAILQ_FIRST(stack);
204 static inline struct op *
205 finalize(struct opstacks *stack, int *argc)
207 struct opstack *ops;
208 struct op *op;
210 if (TAILQ_EMPTY(stack))
211 errx(1, "%s: args underflow", __func__);
213 ops = peek(stack);
214 TAILQ_REMOVE(&args, ops, entry);
215 op = ops->base.next;
217 if (argc != NULL)
218 *argc = ops->counter;
220 free(ops);
221 return op;
224 static inline void
225 push(struct opstacks *stack, struct op *op)
227 struct opstack *ops;
229 ops = peek(stack);
230 if (ops->last == NULL) {
231 ops->base.next = op;
232 ops->last = op;
233 } else {
234 ops->last->next = op;
235 ops->last = op;
238 ops->counter++;
241 static inline void
242 pushenv(void)
244 struct env *e;
246 e = xcalloc(1, sizeof(*e));
247 TAILQ_INSERT_HEAD(&envs, e, entry);
250 static inline struct env *
251 currentenv(void)
253 assert(!TAILQ_EMPTY(&envs));
254 return TAILQ_FIRST(&envs);
257 static void
258 popenv(void)
260 struct env *e;
261 struct binding *b, *tb;
263 e = currentenv();
264 TAILQ_REMOVE(&envs, e, entry);
266 TAILQ_FOREACH_SAFE(b, &e->bindings, entry, tb)
267 free(b);
269 free(e);
272 static inline int
273 setvar(char *sym, struct op *op)
275 struct binding *b;
276 struct env *e;
277 int ret, height;
279 height = stackh;
280 if ((ret = eval(op)) != EVAL_OK)
281 return ret;
283 if (stackh != height + 1) {
284 before_printing();
285 printf("trying to assign to `%s' a void value: ", sym);
286 pp_op(op);
287 printf("\n");
288 return EVAL_ERR;
291 b = xcalloc(1, sizeof(*b));
292 b->name = sym;
293 popv(&b->val);
295 e = TAILQ_FIRST(&envs);
296 TAILQ_INSERT_HEAD(&e->bindings, b, entry);
298 return EVAL_OK;
301 static inline void
302 setvar_raw(char *sym, struct op *op)
304 struct binding *b;
305 struct env *e;
307 b = xcalloc(1, sizeof(*b));
308 b->name = sym;
309 b->raw = op;
311 e = TAILQ_FIRST(&envs);
312 TAILQ_INSERT_HEAD(&e->bindings, b, entry);
315 static inline int
316 getvar(const char *sym, struct value *v)
318 struct env *e;
319 struct binding *b;
321 TAILQ_FOREACH(e, &envs, entry) {
322 TAILQ_FOREACH(b, &e->bindings, entry) {
323 if (!strcmp(sym, b->name)) {
324 memcpy(v, &b->val, sizeof(*v));
325 return EVAL_OK;
330 before_printing();
331 fprintf(stderr, "unbound variable %s\n", sym);
332 return EVAL_ERR;
335 static inline int
336 getvar_raw(const char *sym, struct op **raw)
338 struct env *e;
339 struct binding *b;
341 TAILQ_FOREACH(e, &envs, entry) {
342 TAILQ_FOREACH(b, &e->bindings, entry) {
343 if (!strcmp(sym, b->name)) {
344 *raw = b->raw;
345 return EVAL_OK;
350 return EVAL_ERR;
353 int
354 global_set(char *sym, struct op *op)
356 struct binding *b;
357 struct env *e;
359 /* TODO: check for duplicates */
361 if (op->type != OP_LITERAL &&
362 (op->type == OP_CAST && op->v.cast.expr->type != OP_LITERAL))
363 return 0;
365 b = xcalloc(1, sizeof(*b));
366 b->name = sym;
368 /* it's only a cast on a literal! */
369 if (op->type == OP_CAST) {
370 if (eval(op) != EVAL_OK) {
371 free(b);
372 return 0;
374 popv(&b->val);
375 } else
376 memcpy(&b->val, &op->v.literal, sizeof(b->val));
378 e = TAILQ_LAST(&envs, envs);
379 TAILQ_INSERT_HEAD(&e->bindings, b, entry);
381 return 1;
384 struct op *
385 newop(int type)
387 struct op *op;
389 op = xcalloc(1, sizeof(*op));
390 op->type = type;
392 return op;
395 void
396 free_op_rec(struct op *op)
398 struct op *n;
400 while (op != NULL) {
401 n = op->next;
402 free_op(op);
403 op = n;
407 void
408 free_op(struct op *op)
410 if (op == NULL)
411 return;
413 switch (op->type) {
414 case OP_REST:
415 case OP_LITERAL:
416 case OP_VARGS:
417 break;
418 case OP_ASSIGN:
419 free(op->v.assign.name);
420 free_op_rec(op->v.assign.expr);
421 break;
422 case OP_ASSERT:
423 free_op_rec(op->v.assert);
424 break;
425 case OP_FUNCALL:
426 free_op_rec(op->v.funcall.argv);
427 break;
428 case OP_VAR:
429 free(op->v.var);
430 break;
431 case OP_CAST:
432 free_op_rec(op->v.cast.expr);
433 break;
434 case OP_CMP_EQ:
435 case OP_CMP_LEQ:
436 free_op_rec(op->v.bin_cmp.a);
437 free_op_rec(op->v.bin_cmp.b);
438 break;
439 case OP_FACCESS:
440 free_op_rec(op->v.faccess.expr);
441 free(op->v.faccess.field);
442 break;
443 case OP_SFAIL:
444 free(op->v.sfail.msg);
445 free_op_rec(op->v.sfail.expr);
446 break;
447 default:
448 /* unreachable */
449 abort();
452 free(op);
455 struct op *
456 op_rest(void)
458 return newop(OP_REST);
461 struct op *
462 op_assign(char *sym, struct op *expr)
464 struct op *op;
466 op = newop(OP_ASSIGN);
467 op->v.assign.name = sym;
468 op->v.assign.expr = expr;
470 return op;
473 struct op *
474 op_assert(struct op *expr)
476 struct op *op;
478 op = newop(OP_ASSERT);
479 op->v.assert = expr;
481 return op;
484 struct op *
485 op_var(char *sym)
487 struct op *op;
489 op = newop(OP_VAR);
490 op->v.var = sym;
492 return op;
495 struct op *
496 op_lit_str(char *str)
498 struct op *op;
500 op = newop(OP_LITERAL);
501 op->v.literal.type = V_STR;
502 op->v.literal.v.str = str;
504 return op;
507 struct op *
508 op_lit_num(uint64_t n)
510 struct op *op;
512 op = newop(OP_LITERAL);
513 op->v.literal.type = V_NUM;
514 op->v.literal.v.num = n;
516 return op;
519 struct op *
520 op_cmp_eq(struct op *a, struct op *b)
522 struct op *op;
524 op = newop(OP_CMP_EQ);
525 op->v.bin_cmp.a = a;
526 op->v.bin_cmp.b = b;
528 return op;
531 struct op *
532 op_cmp_leq(struct op *a, struct op *b)
534 struct op *op;
536 op = newop(OP_CMP_LEQ);
537 op->v.bin_cmp.a = a;
538 op->v.bin_cmp.b = b;
540 return op;
543 struct op *
544 op_cast(struct op *expr, int totype)
546 struct op *op;
548 op = newop(OP_CAST);
549 op->v.cast.expr = expr;
550 op->v.cast.totype = totype;
552 return op;
555 struct op *
556 op_faccess(struct op *expr, char *field)
558 struct op *op;
560 op = newop(OP_FACCESS);
561 op->v.faccess.expr = expr;
562 op->v.faccess.field = field;
564 return op;
567 struct op *
568 op_sfail(struct op *expr, char *msg)
570 struct op *op;
572 op = newop(OP_SFAIL);
573 op->v.sfail.expr = expr;
574 op->v.sfail.msg = msg;
576 return op;
579 struct op *
580 op_vargs(void)
582 struct op *op;
584 op = newop(OP_VARGS);
586 return op;
589 void
590 ppf_val(FILE *f, struct value *val)
592 size_t i;
594 switch (val->type) {
595 case V_SYM:
596 fprintf(f, "%s", val->v.str);
597 break;
598 case V_STR:
599 fprintf(f, "\"%s\"", val->v.str);
600 break;
601 case V_NUM:
602 fprintf(f, "%"PRIi64, val->v.num);
603 break;
604 case V_U8:
605 fprintf(f, "%"PRIu8, val->v.u8);
606 break;
607 case V_U16:
608 fprintf(f, "%"PRIu16, val->v.u16);
609 break;
610 case V_U32:
611 fprintf(f, "%"PRIu32, val->v.u32);
612 break;
613 case V_MSG:
614 fprintf(f, "(");
615 for (i = 0; i < val->v.msg.len; ++i)
616 fprintf(f, "%x%s", val->v.msg.msg[i],
617 i == val->v.msg.len-1 ? "" : " ");
618 fprintf(f, ")");
619 break;
620 case V_QIDVEC:
621 fprintf(f, "qids[n=%zu]", val->v.qidvec.len);
622 break;
623 default:
624 fprintf(f, "<unknown value>");
625 break;
629 void
630 pp_val(struct value *val)
632 ppf_val(stdout, val);
635 const char *
636 val_type(struct value *v)
638 switch (v->type) {
639 case V_SYM: return "symbol";
640 case V_STR: return "string";
641 case V_NUM: return "number";
642 case V_MSG: return "message";
643 case V_QID: return "qid";
644 case V_U8: return "u8";
645 case V_U16: return "u16";
646 case V_U32: return "u32";
647 default: return "unknown";
651 int
652 val_trueish(struct value *a)
654 if (val_isnum(a))
655 return val_tonum(a);
656 return 1;
659 int
660 val_isnum(struct value *a)
662 return a->type == V_NUM
663 || a->type == V_U8
664 || a->type == V_U16
665 || a->type == V_U32;
668 int64_t
669 val_tonum(struct value *a)
671 switch (a->type) {
672 case V_NUM: return a->v.num;
673 case V_U8: return a->v.u8;
674 case V_U16: return a->v.u16;
675 case V_U32: return a->v.u32;
676 default:
677 before_printing();
678 fprintf(stderr, "%s: given value is not a number\n", __func__);
679 abort();
683 int
684 val_eq(struct value *a, struct value *b)
686 if (val_isnum(a) && val_isnum(b))
687 return val_tonum(a) == val_tonum(b);
689 if (a->type != b->type)
690 return 0;
692 switch (a->type) {
693 case V_STR:
694 case V_SYM:
695 return !strcmp(a->v.str, b->v.str);
698 return 0;
701 int
702 val_leq(struct value *a, struct value *b)
704 if (val_isnum(a) && val_isnum(b))
705 return val_tonum(a) <= val_tonum(b);
706 return 0;
709 static inline const char *
710 pp_totype(int totype)
712 /*
713 * Not all of these are valid cast type thought, including
714 * every possibility only to aid debugging.
715 */
716 switch (totype) {
717 case V_STR: return "str";
718 case V_SYM: return "sym";
719 case V_NUM: return "num";
720 case V_QID: return "qid";
721 case V_U8: return "u8";
722 case V_U16: return "u16";
723 case V_U32: return "u32";
724 default: return "unknown";
728 int
729 val_cast(struct value *a, int totype)
731 int64_t v;
733 #define NUMCAST(val, t, c, totype, max) do { \
734 if (val > max) { \
735 before_printing(); \
736 fprintf(stderr, "can't cast %"PRIu64 \
737 " to %s\n", val, pp_totype(totype)); \
738 return EVAL_ERR; \
739 } \
740 a->type = totype; \
741 a->v.t = (c)val; \
742 return EVAL_OK; \
743 } while (0)
745 if (a->type == totype)
746 return EVAL_OK;
748 if (!val_isnum(a)) {
749 before_printing();
750 fprintf(stderr, "can't cast ");
751 ppf_val(stderr, a);
752 fprintf(stderr, " to type %s\n", pp_totype(totype));
753 return EVAL_ERR;
756 v = a->v.num;
757 switch (totype) {
758 case V_U8: NUMCAST(v, u8, uint8_t, totype, UINT8_MAX);
759 case V_U16: NUMCAST(v, u16, uint16_t, totype, UINT16_MAX);
760 case V_U32: NUMCAST(v, u32, uint32_t, totype, UINT32_MAX);
761 default:
762 before_printing();
763 fprintf(stderr, "can't cast %"PRIu64" to %s\n",
764 v, pp_totype(totype));
765 return EVAL_ERR;
768 #undef NUMCAST
771 int
772 val_faccess(struct value *a, const char *field, struct value *ret)
774 uint8_t mtype;
775 uint16_t len;
776 const char *errstr;
778 #define MSGTYPE(m) *(m.msg + 4) /* skip the length */
780 switch (a->type) {
781 case V_QID:
782 /* TODO: add path. needs uint64_t values thought! */
783 if (!strcmp(field, "vers")) {
784 ret->type = V_U32;
785 memcpy(&ret->v.u32, a->v.qid+1, 4);
786 return EVAL_OK;
787 } else if (!strcmp(field, "type")) {
788 ret->type = V_U8;
789 ret->v.u8 = *a->v.qid;
790 return EVAL_OK;
792 break;
794 case V_MSG:
795 mtype = MSGTYPE(a->v.msg);
796 if (!strcmp(field, "type")) {
797 ret->type = V_U8;
798 ret->v.u8 = MSGTYPE(a->v.msg);
799 return EVAL_OK;
800 } else if (!strcmp(field, "tag")) {
801 ret->type = V_U16;
802 memcpy(&ret->v.u16, &a->v.msg.msg[5], 2);
803 ret->v.u16 = le16toh(ret->v.u16);
804 return EVAL_OK;
805 } else if (!strcmp(field, "msize") && mtype == Rversion) {
806 ret->type = V_U32;
807 memcpy(&ret->v.u32, &a->v.msg.msg[7], 4);
808 ret->v.u32 = le32toh(ret->v.u32);
809 return EVAL_OK;
810 } else if (!strcmp(field, "qid") && mtype == Rattach) {
811 ret->type = V_QID;
812 memcpy(&ret->v.qid, &a->v.msg.msg[7], QIDSIZE);
813 return EVAL_OK;
814 } else if (!strcmp(field, "nwqid") && mtype == Rwalk) {
815 ret->type = V_U16;
816 memcpy(&ret->v.u16, &a->v.msg.msg[7], 2);
817 ret->v.u16 = le16toh(ret->v.u16);
818 return EVAL_OK;
819 } else if (!strcmp(field, "wqid") && mtype == Rwalk) {
820 ret->type = V_QIDVEC;
821 ret->v.qidvec.start = &a->v.msg.msg[9];
822 memcpy(&len, &a->v.msg.msg[7], 2);
823 len = le16toh(len);
824 ret->v.qidvec.len = len;
825 return EVAL_OK;
827 break;
829 case V_QIDVEC:
830 len = strtonum(field, 0, MAXWELEM, &errstr);
831 if (errstr != NULL) {
832 before_printing();
833 printf("can't access qid #%s: %s\n", field, errstr);
834 return EVAL_ERR;
837 if (len >= a->v.qidvec.len) {
838 before_printing();
839 printf("can't access qid #%d: out-of-bound "
840 "(max %zu)\n", len, a->v.qidvec.len);
841 return EVAL_ERR;
844 ret->type = V_QID;
845 memcpy(&ret->v.qid, a->v.qidvec.start + len * QIDSIZE,
846 QIDSIZE);
848 return EVAL_OK;
850 default:
851 break;
854 before_printing();
855 printf("can't access field `%s' on type %s (", field, val_type(a));
856 pp_val(a);
857 printf(")\n");
858 return EVAL_ERR;
860 #undef MSGTYPE
863 void
864 pp_op(struct op *op)
866 struct op *aux;
868 switch (op->type) {
869 case OP_REST:
870 printf("...");
871 break;
872 case OP_ASSIGN:
873 printf("%s = ", op->v.assign.name);
874 pp_op(op->v.assign.expr);
875 break;
876 case OP_ASSERT:
877 printf("assert ");
878 pp_op(op->v.assert);
879 break;
880 case OP_FUNCALL:
881 printf("funcall %s(", op->v.funcall.proc->name);
882 for (aux = op->v.funcall.argv; aux != NULL; aux = aux->next) {
883 pp_op(aux);
884 if (aux->next != NULL)
885 printf(", ");
887 printf(")");
888 break;
889 case OP_LITERAL:
890 pp_val(&op->v.literal);
891 break;
892 case OP_VAR:
893 printf("%s", op->v.var);
894 break;
895 case OP_CAST:
896 pp_op(op->v.cast.expr);
897 printf(":");
898 switch (op->v.cast.totype) {
899 case V_U8: printf("u8"); break;
900 case V_U16: printf("u16"); break;
901 case V_U32: printf("u32"); break;
902 case V_STR: printf("str"); break;
903 default: printf("???"); break;
905 break;
906 case OP_CMP_EQ:
907 pp_op(op->v.bin_cmp.a);
908 printf(" == ");
909 pp_op(op->v.bin_cmp.b);
910 break;
911 case OP_CMP_LEQ:
912 pp_op(op->v.bin_cmp.a);
913 printf(" <= ");
914 pp_op(op->v.bin_cmp.b);
915 break;
916 case OP_FACCESS:
917 pp_op(op->v.faccess.expr);
918 printf(".%s", op->v.faccess.field);
919 break;
920 case OP_SFAIL:
921 printf("should-fail ");
922 pp_op(op->v.sfail.expr);
923 if (op->v.sfail.msg != NULL)
924 printf(": \"%s\"", op->v.sfail.msg);
925 break;
926 case OP_VARGS:
927 printf("vargs");
928 break;
929 default:
930 printf(" ???[%d] ", op->type);
934 void
935 pp_block(struct op *op)
937 while (op != NULL) {
938 printf("> ");
939 pp_op(op);
940 printf("\n");
942 op = op->next;
946 int
947 eval(struct op *op)
949 struct value a, b;
950 struct proc *proc;
951 struct op *t, *tnext;
952 int i, ret;
954 #if DEBUG
955 pp_op(op);
956 printf("\n");
957 #endif
959 switch (op->type) {
960 case OP_REST:
961 /*
962 * Try to load the rest argument. Note that it can be
963 * empty!
964 */
965 if ((ret = getvar_raw("...", &t)) == EVAL_OK)
966 if ((ret = eval(t)) != EVAL_OK)
967 return ret;
968 break;
970 case OP_ASSIGN:
971 ret = setvar(op->v.assign.name, op->v.assign.expr);
972 if (ret != EVAL_OK)
973 return ret;
974 break;
976 case OP_ASSERT:
977 if ((ret = eval(op->v.assert)) != EVAL_OK)
978 return ret;
979 popv(&a);
980 if (!val_trueish(&a)) {
981 before_printing();
982 printf("assertion failed: ");
983 pp_op(op->v.assert);
984 printf("\n");
985 return EVAL_ERR;
987 break;
989 case OP_FUNCALL:
990 /* assume airity matches */
992 proc = op->v.funcall.proc;
993 if (proc->nativefn != NULL) {
994 /*
995 * Push arguments on the stack for builtin
996 * functions. Counting the height of the
997 * stack is done to compute the correct number
998 * in the vararg case. argc only counts the
999 * "syntactical" arguments, i.e. foo(x, ...)
1000 * has argc == 2, but at runtime argc may be
1001 * 1, 2 or a greater number!
1004 i = stackh;
1005 t = op->v.funcall.argv;
1006 if (t != NULL && (ret = eval(t)) != EVAL_OK)
1007 return ret;
1008 i = stackh - i;
1010 assert(i >= 0);
1012 if ((ret = proc->nativefn(i))
1013 != EVAL_OK)
1014 return ret;
1015 } else {
1016 if (proc->body == NULL) {
1017 before_printing();
1018 printf("warn: calling the empty proc `%s'\n",
1019 proc->name);
1020 break;
1023 pushenv();
1025 for (t = op->v.funcall.argv, i = 0;
1026 t != NULL;
1027 t = t->next, i++) {
1029 * Push a pseudo variable `...' (and
1030 * don't evaluate it) in the vararg
1031 * case. A special case is when the
1032 * variable is itself `...'.
1034 if (proc->vararg && i == proc->minargs) {
1035 if (t->type != OP_REST)
1036 setvar_raw(xstrdup("..."), t);
1037 break;
1041 * The arguments are a linked list of
1042 * ops. Setvar will call eval that
1043 * will evaluate *all* the arguments.
1044 * The dance here that sets next to
1045 * NULL and then restores it is to
1046 * avoid this behaviour.
1048 tnext = t->next;
1049 t->next = NULL;
1050 ret = setvar(proc->args[i], t);
1051 t->next = tnext;
1053 if (ret != EVAL_OK)
1054 return ret;
1057 if ((ret = eval(proc->body)) != EVAL_OK)
1058 return ret;
1060 popenv();
1063 break;
1065 case OP_LITERAL:
1066 pushv(&op->v.literal);
1067 break;
1069 case OP_VAR:
1070 if ((ret = getvar(op->v.var, &a)) != EVAL_OK)
1071 return ret;
1072 pushv(&a);
1073 break;
1075 case OP_CAST:
1076 if ((ret = eval(op->v.cast.expr)) != EVAL_OK)
1077 return ret;
1078 popv(&a);
1079 if ((ret = val_cast(&a, op->v.cast.totype)) != EVAL_OK)
1080 return ret;
1081 pushv(&a);
1082 break;
1084 case OP_CMP_EQ:
1085 if ((ret = eval(op->v.bin_cmp.a)) != EVAL_OK)
1086 return ret;
1087 if ((ret = eval(op->v.bin_cmp.b)) != EVAL_OK)
1088 return ret;
1090 popv(&b);
1091 popv(&a);
1092 pushbool(val_eq(&a, &b));
1093 break;
1095 case OP_CMP_LEQ:
1096 if ((ret = eval(op->v.bin_cmp.a)) != EVAL_OK)
1097 return ret;
1098 if ((ret = eval(op->v.bin_cmp.b)) != EVAL_OK)
1099 return ret;
1101 popv(&b);
1102 popv(&a);
1103 pushbool(val_leq(&a, &b));
1104 break;
1106 case OP_FACCESS:
1107 if ((ret = eval(op->v.faccess.expr)) != EVAL_OK)
1108 return ret;
1109 popv(&a);
1110 if ((ret = val_faccess(&a, op->v.faccess.field, &b))
1111 != EVAL_OK)
1112 return ret;
1113 pushv(&b);
1114 break;
1116 case OP_SFAIL:
1117 if ((ret = eval(op->v.sfail.expr)) == EVAL_OK) {
1118 before_printing();
1119 printf("expecting failure");
1120 if (op->v.sfail.msg != NULL)
1121 printf(" \"%s\"", op->v.sfail.msg);
1122 printf("\n");
1123 printf("expression: ");
1124 pp_op(op->v.sfail.expr);
1125 printf("\n");
1126 return EVAL_ERR;
1128 if (ret == EVAL_SKIP)
1129 return ret;
1130 break;
1132 case OP_VARGS:
1133 if ((ret = getvar_raw("...", &t)) == EVAL_OK) {
1134 for (i = 0; t != NULL; t = t->next)
1135 i++;
1136 pushnum(i);
1137 } else
1138 pushnum(0);
1139 break;
1141 default:
1142 before_printing();
1143 fprintf(stderr, "invalid op, aborting.\n");
1144 abort();
1147 if (op->next)
1148 return eval(op->next);
1149 return EVAL_OK;
1152 void
1153 prepare_funcall(void)
1155 pushstack(&args);
1158 void
1159 push_arg(struct op *op)
1161 push(&args, op);
1164 struct op *
1165 op_funcall(struct proc *proc)
1167 struct op *op, *argv;
1168 int argc;
1170 argv = finalize(&args, &argc);
1172 op = newop(OP_FUNCALL);
1173 op->v.funcall.proc = proc;
1174 op->v.funcall.argv = argv;
1175 op->v.funcall.argc = argc;
1177 return op;
1180 void
1181 add_builtin_proc(const char *name, int (*fn)(int), int argc, int vararg)
1183 struct proc *proc;
1185 proc = xcalloc(1, sizeof(*proc));
1186 proc->name = xstrdup(name);
1187 proc->nativefn = fn;
1188 proc->minargs = argc;
1189 proc->vararg = vararg;
1191 TAILQ_INSERT_HEAD(&procs, proc, entry);
1194 void
1195 prepare_proc(void)
1197 pushstack(&args);
1200 int
1201 proc_setup_body(void)
1203 struct opstack *argv;
1204 struct op *op;
1205 int i;
1207 argv = peek(&args);
1208 for (i = 0, op = argv->base.next; op != NULL; i++) {
1210 * TODO: should free the whole list on error but..,
1211 * we're gonna exit real soon(tm)!
1213 if (op->type != OP_VAR && op->type != OP_REST)
1214 return 0;
1216 op = op->next;
1219 assert(i == argv->counter);
1220 pushstack(&blocks);
1221 return 1;
1224 void
1225 proc_done(char *name)
1227 struct proc *proc;
1228 struct op *op, *next, *argv, *body;
1229 int i, argc;
1231 argv = finalize(&args, &argc);
1232 body = finalize(&blocks, NULL);
1234 proc = xcalloc(1, sizeof(*proc));
1235 proc->name = name;
1236 proc->minargs = argc;
1238 for (i = 0, op = argv; op != NULL; ++i) {
1239 if (op->type == OP_REST) {
1240 proc->vararg = 1;
1241 proc->minargs = i;
1242 break;
1245 proc->args[i] = xstrdup(op->v.var);
1247 next = op->next;
1248 free_op(op);
1249 op = next;
1251 assert(i == argc || (proc->vararg && i == proc->minargs));
1253 proc->body = body;
1255 TAILQ_INSERT_HEAD(&procs, proc, entry);
1258 void
1259 block_push(struct op *op)
1261 push(&blocks, op);
1264 struct proc *
1265 proc_by_name(const char *name)
1267 struct proc *p;
1269 TAILQ_FOREACH(p, &procs, entry) {
1270 if (!strcmp(p->name, name))
1271 return p;
1274 return NULL;
1277 void
1278 prepare_test(void)
1280 pushstack(&blocks);
1283 void
1284 test_done(int shouldfail, char *name)
1286 struct test *test;
1288 test = xcalloc(1, sizeof(*test));
1289 test->shouldfail = shouldfail;
1290 test->name = name;
1291 test->body = finalize(&blocks, NULL);
1293 if (TAILQ_EMPTY(&tests))
1294 TAILQ_INSERT_HEAD(&tests, test, entry);
1295 else
1296 TAILQ_INSERT_TAIL(&tests, test, entry);
1298 ntests++;
1301 static int
1302 builtin_print(int argc)
1304 struct value v;
1305 int i;
1307 before_printing();
1309 for (i = argc; i > 0; --i) {
1310 peekn(i, &v);
1311 if (v.type == V_STR)
1312 printf("%s", v.v.str);
1313 else
1314 pp_val(&v);
1315 printf(" ");
1318 printf("\n");
1320 popvn(argc);
1322 return EVAL_OK;
1325 static int
1326 builtin_debug(int argc)
1328 if (debug)
1329 return builtin_print(argc);
1331 popvn(argc);
1332 return EVAL_OK;
1335 static int
1336 builtin_skip(int argc)
1338 return EVAL_SKIP;
1341 static int
1342 builtin_iota(int argc)
1344 struct value v;
1346 v.type = V_U16;
1347 if ((v.v.u16 = ++lasttag) == 255)
1348 v.v.u16 = ++lasttag;
1350 pushv(&v);
1351 return EVAL_OK;
1354 static int
1355 builtin_send(int argc)
1357 struct ibuf *buf;
1358 struct value v;
1359 uint32_t len;
1360 uint16_t slen;
1361 int i;
1363 check_for_output();
1366 * Compute the length of the packet. 4 is for the initial
1367 * length field
1369 len = 4;
1371 for (i = argc; i > 0; --i) {
1372 peekn(i, &v);
1373 switch (v.type) {
1374 case V_STR:
1375 len += 2; /* count */
1376 len += strlen(v.v.str);
1377 break;
1379 case V_U8:
1380 len += 1;
1381 break;
1383 case V_U16:
1384 len += 2;
1385 break;
1387 case V_U32:
1388 len += 4;
1389 break;
1391 default:
1392 before_printing();
1393 printf("%s: can't serialize ", __func__);
1394 pp_val(&v);
1395 printf("\n");
1396 return EVAL_ERR;
1400 if (len > UINT16_MAX) {
1401 before_printing();
1402 printf("%s: message size too long: got %d when max is %d\n",
1403 __func__, len, UINT16_MAX);
1404 return EVAL_ERR;
1407 if ((buf = imsg_create(&ibuf, IMSG_BUF, 0, 0, len)) == NULL)
1408 fatal("imsg_create(%d)", len);
1410 len = htole32(len);
1411 imsg_add(buf, &len, sizeof(len));
1413 for (i = argc; i > 0; --i) {
1414 peekn(i, &v);
1415 switch (v.type) {
1416 case V_STR:
1417 slen = strlen(v.v.str);
1418 slen = htole16(slen);
1419 imsg_add(buf, &slen, sizeof(slen));
1420 imsg_add(buf, v.v.str, strlen(v.v.str));
1421 break;
1423 case V_U8:
1424 imsg_add(buf, &v.v.u8, 1);
1425 break;
1427 case V_U16:
1428 v.v.u16 = htole16(v.v.u16);
1429 imsg_add(buf, &v.v.u16, 2);
1430 break;
1432 case V_U32:
1433 v.v.u32 = htole32(v.v.u32);
1434 imsg_add(buf, &v.v.u32, 4);
1435 break;
1439 imsg_close(&ibuf, buf);
1441 if (imsg_flush(&ibuf) == -1) {
1442 i = errno;
1443 before_printing();
1444 printf("%s: imsg_flush failed: %s\n", __func__, strerror(i));
1445 return EVAL_ERR;
1448 check_for_output();
1449 return EVAL_OK;
1452 static int
1453 builtin_recv(int argc)
1455 struct pollfd pfd;
1456 struct value v;
1457 struct imsg imsg;
1458 ssize_t n, datalen;
1459 int serrno;
1461 if (lastmsg != NULL) {
1462 free(lastmsg);
1463 lastmsg = NULL;
1466 pfd.fd = ibuf.fd;
1467 pfd.events = POLLIN;
1468 if (poll(&pfd, 1, INFTIM) == -1) {
1469 serrno = errno;
1470 before_printing();
1471 printf("%s: poll failed: %s\n", __func__, strerror(serrno));
1472 return EVAL_ERR;
1475 again:
1476 if ((n = imsg_read(&ibuf)) == -1) {
1477 if (errno == EAGAIN)
1478 goto again;
1479 fatal("imsg_read");
1481 if (n == 0) {
1482 disconnect:
1483 before_printing();
1484 printf("child disconnected\n");
1485 return EVAL_ERR;
1488 nextmessage:
1489 check_for_output();
1491 /* read only one message */
1492 if ((n = imsg_get(&ibuf, &imsg)) == -1)
1493 fatal("imsg_get");
1494 if (n == 0)
1495 goto disconnect;
1497 datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
1498 switch (imsg.hdr.type) {
1499 case IMSG_BUF:
1500 v.type = V_MSG;
1501 if ((v.v.msg.msg = malloc(datalen)) == NULL)
1502 fatal("malloc");
1503 memcpy(v.v.msg.msg, imsg.data, datalen);
1504 v.v.msg.len = datalen;
1505 pushv(&v);
1506 imsg_free(&imsg);
1507 return EVAL_OK;
1509 case IMSG_CLOSE:
1510 before_printing();
1511 printf("subprocess closed the connection\n");
1512 imsg_free(&imsg);
1513 return EVAL_ERR;
1515 case IMSG_MSIZE:
1516 imsg_free(&imsg);
1517 goto nextmessage;
1519 default:
1520 before_printing();
1521 printf("got unknown message from subprocess: %d\n",
1522 imsg.hdr.type);
1523 imsg_free(&imsg);
1524 return EVAL_ERR;
1528 static pid_t
1529 spawn_client_proc(void)
1531 const char *argv[4];
1532 int p[2], out[2], argc = 0;
1533 pid_t pid;
1535 if (child_out != -1)
1536 close(child_out);
1538 if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
1539 PF_UNSPEC, p) == -1)
1540 fatal("socketpair");
1542 if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
1543 PF_UNSPEC, out) == -1)
1544 fatal("socketpair");
1546 switch (pid = fork()) {
1547 case -1:
1548 fatal("cannot fork");
1549 case 0:
1550 break;
1551 default:
1552 close(p[1]);
1553 close(out[1]);
1554 child_out = out[0];
1555 if (ibuf_inuse) {
1556 msgbuf_clear(&ibuf.w);
1557 close(ibuf.fd);
1559 imsg_init(&ibuf, p[0]);
1560 ibuf_inuse = 1;
1561 return pid;
1564 close(p[0]);
1565 close(out[0]);
1567 if (dup2(out[1], 1) == -1 ||
1568 dup2(out[1], 2) == -1)
1569 fatal("dup2");
1571 if (p[1] != 3) {
1572 if (dup2(p[1], 3) == -1)
1573 fatal("cannot setup imsg fd");
1574 } else if (fcntl(F_SETFD, 0) == -1)
1575 fatal("cannot setup imsg fd");
1577 argv[argc++] = argv0;
1578 argv[argc++] = "-Tc";
1580 #if DEBUG
1581 argv[argc++] = "-v";
1582 #endif
1584 argv[argc++] = NULL;
1586 execvp(argv0, (char *const *)argv);
1587 fatal("execvp");
1590 static void
1591 prepare_child_for_test(struct test *t)
1593 struct passwd *pw;
1595 if ((pw = getpwuid(uid)) == NULL)
1596 fatal("getpwuid(%d)", uid);
1598 imsg_compose(&ibuf, IMSG_AUTH, 0, 0, -1,
1599 pw->pw_name, strlen(pw->pw_name)+1);
1600 imsg_compose(&ibuf, IMSG_AUTH_DIR, 0, 0, -1,
1601 dir, strlen(dir)+1);
1603 if (imsg_flush(&ibuf) == -1)
1604 fatal("imsg_flush");
1607 static int
1608 run_test(struct test *t)
1610 pid_t pid;
1611 int ret;
1613 #if DEBUG
1614 before_printing();
1615 puts("=====================");
1616 pp_block(t->body);
1617 puts("=====================");
1618 #endif
1620 if (stackh != 0)
1621 popvn(stackh);
1623 if (t->body == NULL) {
1624 before_printing();
1625 printf("no instructions, skipping...\n");
1626 return EVAL_SKIP;
1629 pid = spawn_client_proc();
1630 prepare_child_for_test(t);
1631 ret = eval(t->body);
1633 imsg_compose(&ibuf, IMSG_CONN_GONE, 0, 0, -1, NULL, 0);
1634 imsg_flush(&ibuf);
1636 while (waitpid(pid, NULL, 0) != pid)
1637 ; /* nop */
1639 check_for_output();
1641 if (t->shouldfail) {
1642 if (ret == EVAL_OK) {
1643 before_printing();
1644 printf("test was expected to fail\n");
1645 return EVAL_ERR;
1646 } else if (ret == EVAL_ERR)
1647 return EVAL_OK;
1650 return ret;
1653 int
1654 main(int argc, char **argv)
1656 struct stat sb;
1657 struct test *t;
1658 int ch, i, r, passed = 0, failed = 0, skipped = 0;
1659 int runclient = 0;
1660 const char *pat = NULL;
1661 regex_t reg;
1663 assert(argv0 = argv[0]);
1665 signal(SIGPIPE, SIG_IGN);
1667 log_init(1, LOG_DAEMON);
1668 log_setverbose(1);
1670 /* prepare the global env */
1671 pushenv();
1673 add_builtin_proc("print", builtin_print, 1, 1);
1674 add_builtin_proc("debug", builtin_debug, 1, 1);
1675 add_builtin_proc("skip", builtin_skip, 0, 0);
1676 add_builtin_proc("iota", builtin_iota, 0, 0);
1677 add_builtin_proc("send", builtin_send, 2, 1);
1678 add_builtin_proc("recv", builtin_recv, 0, 0);
1680 while ((ch = getopt(argc, argv, "nT:r:vx:")) != -1) {
1681 switch (ch) {
1682 case 'n':
1683 syntaxcheck = 1;
1684 break;
1685 case 'T':
1686 assert(*optarg == 'c');
1687 runclient = 1;
1688 break;
1689 case 'r':
1690 dir = optarg;
1691 break;
1692 case 'v':
1693 debug = 1;
1694 break;
1695 case 'x':
1696 pat = optarg;
1697 break;
1698 default:
1699 fprintf(stderr, "Usage: %s [-nv] [files...]\n",
1700 *argv);
1701 exit(1);
1704 argc -= optind;
1705 argv += optind;
1707 if (runclient)
1708 client(1, debug);
1710 if (dir == NULL)
1711 fatal("missing root test dir");
1713 if (stat(dir, &sb) == -1)
1714 fatal("stat(\"%s\")", dir);
1715 uid = sb.st_uid;
1717 if (pat == NULL)
1718 pat = ".*";
1720 if (regcomp(&reg, pat, REG_ICASE | REG_NOSUB) != 0)
1721 fatalx("invalid regexp: %s", pat);
1723 for (i = 0; i < argc; ++i)
1724 loadfile(argv[i]);
1726 if (syntaxcheck) {
1727 fprintf(stderr, "files OK\n");
1728 return 0;
1731 /* Check for root privileges. */
1732 if (geteuid())
1733 fatalx("need root privileges");
1735 i = 0;
1736 TAILQ_FOREACH(t, &tests, entry) {
1737 if (regexec(&reg, t->name, 0, NULL, 0) != 0)
1738 continue;
1740 printf("===> [%d/%d] running test \"%s\"... ", i+1, ntests,
1741 t->name);
1742 fflush(stdout);
1744 filler = "\n";
1745 r = run_test(t);
1746 if (filler == NULL)
1747 printf("=> test ");
1749 switch (r) {
1750 case EVAL_OK:
1751 printf("passed\n");
1752 passed++;
1753 break;
1754 case EVAL_ERR:
1755 failed++;
1756 printf("failed\n");
1757 break;
1758 case EVAL_SKIP:
1759 printf("skipped\n");
1760 skipped++;
1761 break;
1764 if (filler == NULL)
1765 printf("\n");
1766 i++;
1769 printf("\n");
1770 printf("%d/%d passed (%d skipped and %d failed)\n",
1771 passed, i, skipped, failed);
1773 popenv();
1774 free(lastmsg);
1775 regfree(&reg);
1777 return failed != 0;