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 <signal.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <syslog.h>
35 #include <unistd.h>
37 #include "client.h"
38 #include "log.h"
39 #include "script.h"
40 #include "utils.h"
42 #define DEBUG 0
44 #ifndef INFTIM
45 #define INFTIM -1
46 #endif
48 static const char *argv0;
50 static uint8_t *lastmsg;
52 static struct imsgbuf ibuf;
53 static int ibuf_inuse;
55 static struct procs procs = TAILQ_HEAD_INITIALIZER(procs);
56 static struct tests tests = TAILQ_HEAD_INITIALIZER(tests);
58 static int ntests;
60 static struct opstacks blocks = TAILQ_HEAD_INITIALIZER(blocks);
61 static struct opstacks args = TAILQ_HEAD_INITIALIZER(args);
63 #define STACK_HEIGHT 64
64 static struct value vstack[STACK_HEIGHT];
65 static int stackh;
67 static struct envs envs = TAILQ_HEAD_INITIALIZER(envs);
69 static struct value v_false = {.type = V_NUM, .v = {.num = 0}};
70 static struct value v_true = {.type = V_NUM, .v = {.num = 1}};
72 static uint8_t lasttag;
74 static int debug;
75 static int syntaxcheck;
77 static const char *filler;
79 static inline void
80 before_printing(void)
81 {
82 if (filler != NULL) {
83 printf("%s", filler);
84 filler = NULL;
85 }
86 }
88 static inline void
89 peekn(int depth, struct value *v)
90 {
91 if (depth > stackh)
92 errx(1, "can't peek the stack at %d: underflow",
93 depth);
94 memcpy(v, &vstack[stackh - depth], sizeof(*v));
96 #if DEBUG
97 printf("peeking(%d) ", depth); pp_val(v); printf("\n");
98 #endif
99 }
101 static inline void
102 popv(struct value *v)
104 if (stackh == 0)
105 errx(1, "can't pop the stack: underflow");
106 memcpy(v, &vstack[--stackh], sizeof(*v));
108 #if DEBUG
109 printf("popping "); pp_val(v); printf("\n");
110 #endif
113 static inline void
114 popvn(int n)
116 struct value v;
118 while (n-- > 0)
119 popv(&v);
122 static inline void
123 pushv(struct value *v)
125 if (stackh == STACK_HEIGHT)
126 errx(1, "can't push the stack: overflow");
128 #if DEBUG
129 printf("pushing "); pp_val(v); printf("\n");
130 #endif
132 memcpy(&vstack[stackh++], v, sizeof(*v));
135 static inline void
136 pushbool(int n)
138 pushv(n ? &v_true : &v_false);
141 static inline struct opstack *
142 pushstack(struct opstacks *stack)
144 struct opstack *ops;
146 ops = xcalloc(1, sizeof(*ops));
147 TAILQ_INSERT_HEAD(stack, ops, entry);
148 return ops;
151 static inline struct opstack *
152 peek(struct opstacks *stack)
154 if (TAILQ_EMPTY(stack))
155 errx(1, "%s: args underflow", __func__);
157 return TAILQ_FIRST(stack);
160 static inline struct op *
161 finalize(struct opstacks *stack, int *argc)
163 struct opstack *ops;
164 struct op *op;
166 if (TAILQ_EMPTY(stack))
167 errx(1, "%s: args underflow", __func__);
169 ops = peek(stack);
170 TAILQ_REMOVE(&args, ops, entry);
171 op = ops->base.next;
173 if (argc != NULL)
174 *argc = ops->counter;
176 free(ops);
177 return op;
180 static inline void
181 push(struct opstacks *stack, struct op *op)
183 struct opstack *ops;
185 ops = peek(stack);
186 if (ops->last == NULL) {
187 ops->base.next = op;
188 ops->last = op;
189 } else {
190 ops->last->next = op;
191 ops->last = op;
194 ops->counter++;
197 static inline void
198 pushenv(void)
200 struct env *e;
202 e = xcalloc(1, sizeof(*e));
203 TAILQ_INSERT_HEAD(&envs, e, entry);
206 static inline struct env *
207 currentenv(void)
209 assert(!TAILQ_EMPTY(&envs));
210 return TAILQ_FIRST(&envs);
213 static void
214 popenv(void)
216 struct env *e;
217 struct binding *b, *tb;
219 e = currentenv();
220 TAILQ_REMOVE(&envs, e, entry);
222 TAILQ_FOREACH_SAFE(b, &e->bindings, entry, tb) {
223 free(b->name);
224 switch (b->val.type) {
225 case V_SYM:
226 case V_STR:
227 free(b->val.v.str);
228 break;
230 free(b);
233 free(e);
236 static inline int
237 setvar(char *sym, struct op *op)
239 struct binding *b;
240 struct env *e;
241 int ret, height;
243 height = stackh;
244 if ((ret = eval(op)) != EVAL_OK)
245 return ret;
247 if (stackh != height + 1) {
248 before_printing();
249 printf("trying to assign to `%s' a void value: ", sym);
250 pp_op(op);
251 printf("\n");
252 return EVAL_ERR;
255 b = xcalloc(1, sizeof(*b));
256 b->name = sym;
257 popv(&b->val);
259 e = TAILQ_FIRST(&envs);
260 TAILQ_INSERT_HEAD(&e->bindings, b, entry);
262 return EVAL_OK;
265 static inline void
266 setvar_raw(char *sym, struct op *op)
268 struct binding *b;
269 struct env *e;
271 b = xcalloc(1, sizeof(*b));
272 b->name = sym;
273 b->raw = op;
275 e = TAILQ_FIRST(&envs);
276 TAILQ_INSERT_HEAD(&e->bindings, b, entry);
279 static inline int
280 getvar(const char *sym, struct value *v)
282 struct env *e;
283 struct binding *b;
285 TAILQ_FOREACH(e, &envs, entry) {
286 TAILQ_FOREACH(b, &e->bindings, entry) {
287 if (!strcmp(sym, b->name)) {
288 memcpy(v, &b->val, sizeof(*v));
289 return EVAL_OK;
294 before_printing();
295 fprintf(stderr, "unbound variable %s\n", sym);
296 return EVAL_ERR;
299 static inline int
300 getvar_raw(const char *sym, struct op **raw)
302 struct env *e;
303 struct binding *b;
305 TAILQ_FOREACH(e, &envs, entry) {
306 TAILQ_FOREACH(b, &e->bindings, entry) {
307 if (!strcmp(sym, b->name)) {
308 *raw = b->raw;
309 return EVAL_OK;
314 before_printing();
315 fprintf(stderr, "no rest argument `...'\n");
316 return EVAL_ERR;
319 int
320 global_set(char *sym, struct op *op)
322 struct binding *b;
323 struct env *e;
325 /* TODO: check for duplicates */
327 if (op->type != OP_LITERAL &&
328 (op->type == OP_CAST && op->v.cast.expr->type != OP_LITERAL))
329 return 0;
331 b = xcalloc(1, sizeof(*b));
332 b->name = sym;
334 /* it's only a cast on a literal! */
335 if (op->type == OP_CAST) {
336 if (eval(op) != EVAL_OK) {
337 free(b);
338 return 0;
340 popv(&b->val);
341 } else
342 memcpy(&b->val, &op->v.literal, sizeof(b->val));
344 e = TAILQ_LAST(&envs, envs);
345 TAILQ_INSERT_HEAD(&e->bindings, b, entry);
347 return 1;
350 struct op *
351 newop(int type)
353 struct op *op;
355 op = xcalloc(1, sizeof(*op));
356 op->type = type;
358 return op;
361 void
362 free_op(struct op *op)
364 /* TODO: probably more... */
365 free(op);
368 struct op *
369 op_rest(void)
371 return newop(OP_REST);
374 struct op *
375 op_assign(char *sym, struct op *expr)
377 struct op *op;
379 op = newop(OP_ASSIGN);
380 op->v.assign.name = sym;
381 op->v.assign.expr = expr;
383 return op;
386 struct op *
387 op_assert(struct op *expr)
389 struct op *op;
391 op = newop(OP_ASSERT);
392 op->v.assert = expr;
394 return op;
397 struct op *
398 op_var(char *sym)
400 struct op *op;
402 op = newop(OP_VAR);
403 op->v.var = sym;
405 return op;
408 struct op *
409 op_lit_str(char *str)
411 struct op *op;
413 op = newop(OP_LITERAL);
414 op->v.literal.type = V_STR;
415 op->v.literal.v.str = str;
417 return op;
420 struct op *
421 op_lit_num(uint64_t n)
423 struct op *op;
425 op = newop(OP_LITERAL);
426 op->v.literal.type = V_NUM;
427 op->v.literal.v.num = n;
429 return op;
432 struct op *
433 op_cmp_eq(struct op *a, struct op *b)
435 struct op *op;
437 op = newop(OP_CMP_EQ);
438 op->v.cmp_eq.a = a;
439 op->v.cmp_eq.b = b;
441 return op;
444 struct op *
445 op_cast(struct op *expr, int totype)
447 struct op *op;
449 op = newop(OP_CAST);
450 op->v.cast.expr = expr;
451 op->v.cast.totype = totype;
453 return op;
456 struct op *
457 op_faccess(struct op *expr, char *field)
459 struct op *op;
461 op = newop(OP_FACCESS);
462 op->v.faccess.expr = expr;
463 op->v.faccess.field = field;
465 return op;
468 struct op *
469 op_sfail(struct op *expr, char *msg)
471 struct op *op;
473 op = newop(OP_SFAIL);
474 op->v.sfail.expr = expr;
475 op->v.sfail.msg = msg;
477 return op;
480 void
481 ppf_val(FILE *f, struct value *val)
483 size_t i;
485 switch (val->type) {
486 case V_SYM:
487 fprintf(f, "%s", val->v.str);
488 break;
489 case V_STR:
490 fprintf(f, "\"%s\"", val->v.str);
491 break;
492 case V_NUM:
493 fprintf(f, "%"PRIi64, val->v.num);
494 break;
495 case V_U8:
496 fprintf(f, "%"PRIu8, val->v.u8);
497 break;
498 case V_U16:
499 fprintf(f, "%"PRIu16, val->v.u16);
500 break;
501 case V_U32:
502 fprintf(f, "%"PRIu32, val->v.u32);
503 break;
504 case V_MSG:
505 fprintf(f, "(");
506 for (i = 0; i < val->v.msg.len; ++i)
507 fprintf(f, "%x%s", val->v.msg.msg[i],
508 i == val->v.msg.len-1 ? "" : " ");
509 fprintf(f, ")");
510 break;
511 default:
512 fprintf(f, "<unknown value>");
513 break;
517 void
518 pp_val(struct value *val)
520 ppf_val(stdout, val);
523 const char *
524 val_type(struct value *v)
526 switch (v->type) {
527 case V_SYM: return "symbol";
528 case V_STR: return "string";
529 case V_NUM: return "number";
530 case V_MSG: return "message";
531 case V_QID: return "qid";
532 case V_U8: return "u8";
533 case V_U16: return "u16";
534 case V_U32: return "u32";
535 default: return "unknown";
539 int
540 val_trueish(struct value *a)
542 return a->type == V_NUM && a->v.num;
545 static inline int
546 val_isnum(struct value *a)
548 return a->type == V_NUM
549 || a->type == V_U8
550 || a->type == V_U16
551 || a->type == V_U32;
554 static inline int64_t
555 val_tonum(struct value *a)
557 switch (a->type) {
558 case V_NUM: return a->v.num;
559 case V_U8: return a->v.u8;
560 case V_U16: return a->v.u16;
561 case V_U32: return a->v.u32;
562 default:
563 before_printing();
564 fprintf(stderr, "%s: given value is not a number\n", __func__);
565 abort();
569 int
570 val_eq(struct value *a, struct value *b)
572 if (val_isnum(a) && val_isnum(b))
573 return val_tonum(a) == val_tonum(b);
575 if (a->type != b->type)
576 return 0;
578 switch (a->type) {
579 case V_STR:
580 case V_SYM:
581 return !strcmp(a->v.str, b->v.str);
584 return 0;
587 static inline const char *
588 pp_totype(int totype)
590 /*
591 * Not all of these are valid cast type thought, including
592 * every possibility only to aid debugging.
593 */
594 switch (totype) {
595 case V_STR: return "str";
596 case V_SYM: return "sym";
597 case V_NUM: return "num";
598 case V_QID: return "qid";
599 case V_U8: return "u8";
600 case V_U16: return "u16";
601 case V_U32: return "u32";
602 default: return "unknown";
606 int
607 val_cast(struct value *a, int totype)
609 int64_t v;
611 #define NUMCAST(val, t, c, totype, max) do { \
612 if (val > max) { \
613 before_printing(); \
614 fprintf(stderr, "can't cast %"PRIu64 \
615 " to %s\n", val, pp_totype(totype)); \
616 return EVAL_ERR; \
617 } \
618 a->type = totype; \
619 a->v.t = (c)val; \
620 return EVAL_OK; \
621 } while (0)
623 if (!val_isnum(a)) {
624 before_printing();
625 fprintf(stderr, "can't cast ");
626 ppf_val(stderr, a);
627 fprintf(stderr, " to type %s\n", pp_totype(totype));
628 return EVAL_ERR;
631 v = a->v.num;
632 switch (totype) {
633 case V_U8: NUMCAST(v, u8, uint8_t, totype, UINT8_MAX);
634 case V_U16: NUMCAST(v, u16, uint16_t, totype, UINT16_MAX);
635 case V_U32: NUMCAST(v, u32, uint32_t, totype, UINT32_MAX);
636 default:
637 before_printing();
638 fprintf(stderr, "can't cast %"PRIu64" to %s\n",
639 v, pp_totype(totype));
640 return EVAL_ERR;
643 #undef NUMCAST
646 int
647 val_faccess(struct value *a, const char *field, struct value *ret)
649 switch (a->type) {
650 case V_QID:
651 /* TODO: add path. needs uint64_t values thought! */
652 if (!strcmp(field, "vers")) {
653 ret->type = V_U32;
654 memcpy(&ret->v.u32, a->v.qid+1, 4);
655 return EVAL_OK;
656 } else if (!strcmp(field, "type")) {
657 ret->type = V_U8;
658 ret->v.u8 = *a->v.qid;
659 return EVAL_OK;
661 break;
662 case V_MSG:
663 if (!strcmp(field, "type")) {
664 ret->type = V_U8;
665 ret->v.u8 = *(a->v.msg.msg + 4); /* skip the length */
666 return EVAL_OK;
668 break;
669 default:
670 break;
673 before_printing();
674 printf("can't access field `%s' on type %s (", field, val_type(a));
675 pp_val(a);
676 printf(")\n");
677 return EVAL_ERR;
680 void
681 pp_op(struct op *op)
683 struct op *aux;
685 switch (op->type) {
686 case OP_REST:
687 printf("...");
688 break;
689 case OP_ASSIGN:
690 printf("%s = ", op->v.assign.name);
691 pp_op(op->v.assign.expr);
692 break;
693 case OP_ASSERT:
694 printf("assert ");
695 pp_op(op->v.assert);
696 break;
697 case OP_FUNCALL:
698 printf("funcall %s(", op->v.funcall.proc->name);
699 for (aux = op->v.funcall.argv; aux != NULL; aux = aux->next) {
700 pp_op(aux);
701 if (aux->next != NULL)
702 printf(", ");
704 printf(")");
705 break;
706 case OP_LITERAL:
707 pp_val(&op->v.literal);
708 break;
709 case OP_VAR:
710 printf("%s", op->v.var);
711 break;
712 case OP_CAST:
713 pp_op(op->v.cast.expr);
714 printf(":");
715 switch (op->v.cast.totype) {
716 case V_U8: printf("u8"); break;
717 case V_U16: printf("u16"); break;
718 case V_U32: printf("u32"); break;
719 case V_STR: printf("str"); break;
720 default: printf("???"); break;
722 break;
723 case OP_CMP_EQ:
724 pp_op(op->v.cmp_eq.a);
725 printf(" == ");
726 pp_op(op->v.cmp_eq.b);
727 break;
728 case OP_FACCESS:
729 pp_op(op->v.faccess.expr);
730 printf(".%s", op->v.faccess.field);
731 break;
732 case OP_SFAIL:
733 printf("should-fail ");
734 pp_op(op->v.sfail.expr);
735 if (op->v.sfail.msg != NULL)
736 printf(": \"%s\"", op->v.sfail.msg);
737 break;
738 default:
739 printf(" ???[%d] ", op->type);
743 void
744 pp_block(struct op *op)
746 while (op != NULL) {
747 printf("> ");
748 pp_op(op);
749 printf("\n");
751 op = op->next;
755 int
756 eval(struct op *op)
758 struct value a, b;
759 struct proc *proc;
760 struct op *t;
761 int i, ret;
763 #if DEBUG
764 pp_op(op);
765 printf("\n");
766 #endif
768 switch (op->type) {
769 case OP_REST:
770 if ((ret = getvar_raw("...", &t)) != EVAL_OK)
771 return ret;
772 if ((ret = eval(t)) != EVAL_OK)
773 return ret;
774 break;
776 case OP_ASSIGN:
777 ret = setvar(op->v.assign.name, op->v.assign.expr);
778 if (ret != EVAL_OK)
779 return ret;
780 break;
782 case OP_ASSERT:
783 if ((ret = eval(op->v.assert)) != EVAL_OK)
784 return ret;
785 popv(&a);
786 if (!val_trueish(&a)) {
787 before_printing();
788 printf("assertion failed: ");
789 pp_op(op->v.assert);
790 printf("\n");
791 return EVAL_ERR;
793 break;
795 case OP_FUNCALL:
796 /* assume airity matches */
798 proc = op->v.funcall.proc;
799 if (proc->nativefn != NULL) {
800 /*
801 * Push arguments on the stack for builtin
802 * functions. Counting the height of the
803 * stack is done to compute the correct number
804 * in the vararg case. argc only counts the
805 * "syntactical" arguments, i.e. foo(x, ...)
806 * has argc == 2, but at runtime argc may be
807 * 1, 2 or a greater number!
808 */
810 i = stackh;
811 t = op->v.funcall.argv;
812 if (t != NULL && (ret = eval(t)) != EVAL_OK)
813 return ret;
814 i = stackh - i;
816 assert(i >= 0);
818 if ((ret = proc->nativefn(i))
819 != EVAL_OK)
820 return ret;
821 } else {
822 if (proc->body == NULL) {
823 before_printing();
824 printf("warn: calling the empty proc `%s'\n",
825 proc->name);
826 break;
829 pushenv();
831 for (t = op->v.funcall.argv, i = 0;
832 t != NULL;
833 t = t->next, i++) {
834 /*
835 * Push a pseudo variable `...' (and
836 * don't evaluate it) in the vararg
837 * case. A special case is when the
838 * variable is itself `...'.
839 */
840 if (proc->vararg && i == proc->minargs) {
841 if (t->type != OP_REST)
842 setvar_raw(xstrdup("..."), t);
843 break;
846 if ((ret = setvar(proc->args[i], t))
847 != EVAL_OK)
848 return ret;
851 if ((ret = eval(proc->body)) != EVAL_OK)
852 return ret;
854 popenv();
857 break;
859 case OP_LITERAL:
860 pushv(&op->v.literal);
861 break;
863 case OP_VAR:
864 if ((ret = getvar(op->v.var, &a)) != EVAL_OK)
865 return ret;
866 pushv(&a);
867 break;
869 case OP_CAST:
870 if ((ret = eval(op->v.cast.expr)) != EVAL_OK)
871 return ret;
872 popv(&a);
873 if ((ret = val_cast(&a, op->v.cast.totype)) != EVAL_OK)
874 return ret;
875 pushv(&a);
876 break;
878 case OP_CMP_EQ:
879 if ((ret = eval(op->v.cmp_eq.a)) != EVAL_OK)
880 return ret;
881 if ((ret = eval(op->v.cmp_eq.b)) != EVAL_OK)
882 return ret;
884 popv(&b);
885 popv(&a);
886 pushbool(val_eq(&a, &b));
888 break;
890 case OP_FACCESS:
891 if ((ret = eval(op->v.faccess.expr)) != EVAL_OK)
892 return ret;
893 popv(&a);
894 if ((ret = val_faccess(&a, op->v.faccess.field, &b))
895 != EVAL_OK)
896 return ret;
897 pushv(&b);
898 break;
900 case OP_SFAIL:
901 if ((ret = eval(op->v.sfail.expr)) == EVAL_OK) {
902 before_printing();
903 printf("expecting failure");
904 if (op->v.sfail.msg != NULL)
905 printf(" \"%s\"", op->v.sfail.msg);
906 printf("\n");
907 printf("expression: ");
908 pp_op(op->v.sfail.expr);
909 printf("\n");
910 return EVAL_ERR;
912 if (ret == EVAL_SKIP)
913 return ret;
914 break;
916 default:
917 before_printing();
918 fprintf(stderr, "invalid op, aborting.\n");
919 abort();
922 if (op->next)
923 return eval(op->next);
924 return EVAL_OK;
927 void
928 prepare_funcall(void)
930 pushstack(&args);
933 void
934 push_arg(struct op *op)
936 push(&args, op);
939 struct op *
940 op_funcall(struct proc *proc)
942 struct op *op, *argv;
943 int argc;
945 argv = finalize(&args, &argc);
947 op = newop(OP_FUNCALL);
948 op->v.funcall.proc = proc;
949 op->v.funcall.argv = argv;
950 op->v.funcall.argc = argc;
952 return op;
955 void
956 add_builtin_proc(const char *name, int (*fn)(int), int argc, int vararg)
958 struct proc *proc;
960 proc = xcalloc(1, sizeof(*proc));
961 proc->name = xstrdup(name);
962 proc->nativefn = fn;
963 proc->minargs = argc;
964 proc->vararg = vararg;
966 TAILQ_INSERT_HEAD(&procs, proc, entry);
969 void
970 prepare_proc(void)
972 pushstack(&args);
975 int
976 proc_setup_body(void)
978 struct opstack *argv;
979 struct op *op;
980 int i;
982 argv = peek(&args);
983 for (i = 0, op = argv->base.next; op != NULL; i++) {
984 /*
985 * TODO: should free the whole list on error but..,
986 * we're gonna exit real soon(tm)!
987 */
988 if (op->type != OP_VAR && op->type != OP_REST)
989 return 0;
991 op = op->next;
994 assert(i == argv->counter);
995 pushstack(&blocks);
996 return 1;
999 void
1000 proc_done(char *name)
1002 struct proc *proc;
1003 struct op *op, *next, *argv, *body;
1004 int i, argc;
1006 argv = finalize(&args, &argc);
1007 body = finalize(&blocks, NULL);
1009 proc = xcalloc(1, sizeof(*proc));
1010 proc->name = name;
1011 proc->minargs = argc;
1013 for (i = 0, op = argv; op != NULL; ++i) {
1014 if (op->type == OP_REST) {
1015 proc->vararg = 1;
1016 proc->minargs = i;
1017 break;
1020 proc->args[i] = xstrdup(op->v.var);
1022 next = op->next;
1023 free_op(op);
1024 op = next;
1026 assert(i == argc || (proc->vararg && i == proc->minargs));
1028 proc->body = body;
1030 TAILQ_INSERT_HEAD(&procs, proc, entry);
1033 void
1034 block_push(struct op *op)
1036 push(&blocks, op);
1039 struct proc *
1040 proc_by_name(const char *name)
1042 struct proc *p;
1044 TAILQ_FOREACH(p, &procs, entry) {
1045 if (!strcmp(p->name, name))
1046 return p;
1049 return NULL;
1052 void
1053 prepare_test(void)
1055 pushstack(&blocks);
1058 void
1059 test_done(int shouldfail, char *name, char *dir)
1061 struct test *test;
1063 test = xcalloc(1, sizeof(*test));
1064 test->shouldfail = shouldfail;
1065 test->name = name;
1066 test->dir = dir;
1067 test->body = finalize(&blocks, NULL);
1069 if (TAILQ_EMPTY(&tests))
1070 TAILQ_INSERT_HEAD(&tests, test, entry);
1071 else
1072 TAILQ_INSERT_TAIL(&tests, test, entry);
1074 ntests++;
1077 static int
1078 builtin_print(int argc)
1080 struct value v;
1081 int i;
1083 before_printing();
1085 for (i = argc; i > 0; --i) {
1086 peekn(i, &v);
1087 if (v.type == V_STR)
1088 printf("%s", v.v.str);
1089 else
1090 pp_val(&v);
1091 printf(" ");
1094 printf("\n");
1096 popvn(argc);
1098 return EVAL_OK;
1101 static int
1102 builtin_debug(int argc)
1104 if (debug)
1105 return builtin_print(argc);
1107 popvn(argc);
1108 return EVAL_OK;
1111 static int
1112 builtin_skip(int argc)
1114 return EVAL_SKIP;
1117 static int
1118 builtin_iota(int argc)
1120 struct value v;
1122 v.type = V_U8;
1123 if ((v.v.u8 = ++lasttag) == 255)
1124 v.v.u8 = ++lasttag;
1126 pushv(&v);
1127 return EVAL_OK;
1130 static int
1131 builtin_send(int argc)
1133 struct ibuf *buf;
1134 struct value v;
1135 uint32_t len;
1136 uint16_t slen;
1137 int i;
1140 * Compute the length of the packet. 4 is for the initial
1141 * length field
1143 len = 4;
1145 for (i = argc; i > 0; --i) {
1146 peekn(i, &v);
1147 switch (v.type) {
1148 case V_STR:
1149 len += 2; /* count */
1150 len += strlen(v.v.str);
1151 break;
1153 case V_U8:
1154 len += 1;
1155 break;
1157 case V_U16:
1158 len += 2;
1159 break;
1161 case V_U32:
1162 len += 4;
1163 break;
1165 default:
1166 before_printing();
1167 printf("%s: can't serialize ", __func__);
1168 pp_val(&v);
1169 printf("\n");
1170 return EVAL_ERR;
1174 if (len > UINT16_MAX) {
1175 before_printing();
1176 printf("%s: message size too long: got %d when max is %d\n",
1177 __func__, len, UINT16_MAX);
1178 return EVAL_ERR;
1181 if ((buf = imsg_create(&ibuf, IMSG_BUF, 0, 0, len)) == NULL)
1182 fatal("imsg_create(%d)", len);
1184 len = htole32(len);
1185 imsg_add(buf, &len, sizeof(len));
1187 for (i = argc; i > 0; --i) {
1188 peekn(i, &v);
1189 switch (v.type) {
1190 case V_STR:
1191 slen = strlen(v.v.str);
1192 slen = htole16(slen);
1193 imsg_add(buf, &slen, sizeof(slen));
1194 imsg_add(buf, v.v.str, strlen(v.v.str));
1195 break;
1197 case V_U8:
1198 imsg_add(buf, &v.v.u8, 1);
1199 break;
1201 case V_U16:
1202 v.v.u16 = htole16(v.v.u16);
1203 imsg_add(buf, &v.v.u16, 2);
1204 break;
1206 case V_U32:
1207 v.v.u32 = htole32(v.v.u32);
1208 imsg_add(buf, &v.v.u32, 4);
1209 break;
1213 imsg_close(&ibuf, buf);
1215 if (imsg_flush(&ibuf) == -1) {
1216 i = errno;
1217 before_printing();
1218 printf("%s: imsg_flush failed: %s\n", __func__, strerror(i));
1219 return EVAL_ERR;
1222 return EVAL_OK;
1225 static int
1226 builtin_recv(int argc)
1228 struct pollfd pfd;
1229 struct value v;
1230 struct imsg imsg;
1231 ssize_t n, datalen;
1232 int serrno;
1234 if (lastmsg != NULL) {
1235 free(lastmsg);
1236 lastmsg = NULL;
1239 pfd.fd = ibuf.fd;
1240 pfd.events = POLLIN;
1241 if (poll(&pfd, 1, INFTIM) == -1) {
1242 serrno = errno;
1243 before_printing();
1244 printf("%s: poll failed: %s\n", __func__, strerror(serrno));
1245 return EVAL_ERR;
1248 again:
1249 if ((n = imsg_read(&ibuf)) == -1) {
1250 if (errno == EAGAIN)
1251 goto again;
1252 fatal("imsg_read");
1254 if (n == 0) {
1255 disconnect:
1256 before_printing();
1257 printf("child disconnected\n");
1258 return EVAL_ERR;
1261 nextmessage:
1262 /* read only one message */
1263 if ((n = imsg_get(&ibuf, &imsg)) == -1)
1264 fatal("imsg_get");
1265 if (n == 0)
1266 goto disconnect;
1268 datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
1269 switch (imsg.hdr.type) {
1270 case IMSG_BUF:
1271 v.type = V_MSG;
1272 if ((v.v.msg.msg = malloc(datalen)) == NULL)
1273 fatal("malloc");
1274 memcpy(v.v.msg.msg, imsg.data, datalen);
1275 v.v.msg.len = datalen;
1276 pushv(&v);
1277 imsg_free(&imsg);
1278 return EVAL_OK;
1280 case IMSG_CLOSE:
1281 before_printing();
1282 printf("subprocess closed the connection\n");
1283 imsg_free(&imsg);
1284 return EVAL_ERR;
1286 case IMSG_MSIZE:
1287 imsg_free(&imsg);
1288 goto nextmessage;
1290 default:
1291 before_printing();
1292 printf("got unknown message from subprocess: %d\n",
1293 imsg.hdr.type);
1294 imsg_free(&imsg);
1295 return EVAL_ERR;
1299 static pid_t
1300 spawn_client_proc(void)
1302 const char *argv[4];
1303 int p[2], argc = 0;
1304 pid_t pid;
1306 if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
1307 PF_UNSPEC, p) == -1)
1308 fatal("socketpair");
1310 switch (pid = fork()) {
1311 case -1:
1312 fatal("cannot fork");
1313 case 0:
1314 break;
1315 default:
1316 close(p[1]);
1317 if (ibuf_inuse) {
1318 msgbuf_clear(&ibuf.w);
1319 close(ibuf.fd);
1321 imsg_init(&ibuf, p[0]);
1322 ibuf_inuse = 1;
1323 return pid;
1326 close(p[0]);
1328 if (p[1] != 3) {
1329 if (dup2(p[1], 3) == -1)
1330 fatal("cannot setup imsg fd");
1331 } else if (fcntl(F_SETFD, 0) == -1)
1332 fatal("cannot setup imsg fd");
1334 argv[argc++] = argv0;
1335 argv[argc++] = "-Tc";
1337 #if DEBUG
1338 argv[argc++] = "-v";
1339 #endif
1341 argv[argc++] = NULL;
1343 execvp(argv0, (char *const *)argv);
1344 fatal("execvp");
1347 static void
1348 prepare_child_for_test(struct test *t)
1350 struct passwd *pw;
1351 struct stat sb;
1353 if (stat(t->dir, &sb) == -1)
1354 fatal("stat(\"%s\")", t->dir);
1356 if ((pw = getpwuid(sb.st_uid)) == NULL)
1357 fatal("getpwuid(%d)", sb.st_uid);
1359 imsg_compose(&ibuf, IMSG_AUTH, 0, 0, -1,
1360 pw->pw_name, strlen(pw->pw_name)+1);
1361 imsg_compose(&ibuf, IMSG_AUTH_DIR, 0, 0, -1,
1362 t->dir, strlen(t->dir)+1);
1364 if (imsg_flush(&ibuf) == -1)
1365 fatal("imsg_flush");
1368 static int
1369 run_test(struct test *t)
1371 pid_t pid;
1372 int ret;
1374 #if DEBUG
1375 before_printing();
1376 puts("=====================");
1377 pp_block(t->body);
1378 puts("=====================");
1379 #endif
1381 if (t->body == NULL) {
1382 before_printing();
1383 printf("no instructions, skipping...\n");
1384 return EVAL_SKIP;
1387 pid = spawn_client_proc();
1388 prepare_child_for_test(t);
1389 ret = eval(t->body);
1391 imsg_compose(&ibuf, IMSG_CONN_GONE, 0, 0, -1, NULL, 0);
1392 imsg_flush(&ibuf);
1394 while (waitpid(pid, NULL, 0) != pid)
1395 ; /* nop */
1397 if (t->shouldfail) {
1398 if (ret == EVAL_OK) {
1399 before_printing();
1400 printf("test was expected to fail\n");
1401 return EVAL_ERR;
1402 } else if (ret == EVAL_ERR)
1403 return EVAL_OK;
1406 return ret;
1409 int
1410 main(int argc, char **argv)
1412 struct env *e;
1413 struct test *t;
1414 int ch, i, r, passed = 0, failed = 0, skipped = 0;
1415 int runclient = 0;
1417 assert(argv0 = argv[0]);
1419 signal(SIGPIPE, SIG_IGN);
1421 log_init(1, LOG_DAEMON);
1422 log_setverbose(1);
1424 /* prepare the global env */
1425 pushenv();
1427 add_builtin_proc("print", builtin_print, 1, 1);
1428 add_builtin_proc("debug", builtin_debug, 1, 1);
1429 add_builtin_proc("skip", builtin_skip, 0, 0);
1430 add_builtin_proc("iota", builtin_iota, 0, 0);
1431 add_builtin_proc("send", builtin_send, 2, 1);
1432 add_builtin_proc("recv", builtin_recv, 0, 0);
1434 while ((ch = getopt(argc, argv, "nT:v")) != -1) {
1435 switch (ch) {
1436 case 'n':
1437 syntaxcheck = 1;
1438 break;
1439 case 'T':
1440 assert(*optarg == 'c');
1441 runclient = 1;
1442 break;
1443 case 'v':
1444 debug = 1;
1445 break;
1446 default:
1447 fprintf(stderr, "Usage: %s [-nv] [files...]\n",
1448 *argv);
1449 exit(1);
1452 argc -= optind;
1453 argv += optind;
1455 if (runclient)
1456 client(1, debug);
1458 for (i = 0; i < argc; ++i)
1459 loadfile(argv[i]);
1461 if (syntaxcheck) {
1462 fprintf(stderr, "files OK\n");
1463 return 0;
1466 /* Check for root privileges. */
1467 if (geteuid())
1468 fatalx("need root privileges");
1470 i = 0;
1471 TAILQ_FOREACH(t, &tests, entry) {
1472 printf("===> [%d/%d] running test \"%s\"... ", i, ntests,
1473 t->name);
1474 fflush(stdout);
1476 filler = "\n";
1477 r = run_test(t);
1478 if (filler == NULL)
1479 printf("=> test ");
1481 switch (r) {
1482 case EVAL_OK:
1483 printf("passed\n");
1484 passed++;
1485 break;
1486 case EVAL_ERR:
1487 failed++;
1488 printf("failed\n");
1489 break;
1490 case EVAL_SKIP:
1491 printf("skipped\n");
1492 skipped++;
1493 break;
1496 printf("\n");
1497 i++;
1500 printf("\n");
1501 printf("passed: %d/%d\n", passed, i);
1502 printf("failed: %d\n", failed);
1503 printf("skipped: %d\n", skipped);
1505 popenv();
1507 return failed != 0;