+static void
+do_pipe(char* program, struct list* hash)
+{
+ struct email em = prepare_email(hash);
+ struct procstat* f;
+ int res = 0;
+ char* buf;
+ off_t pos;
+
+ f = pipe_to(program, &em);
+ if (!f) {
+ res++;
+ goto end;
+ }
+ pos = lseek(f->fd, 0, SEEK_END);
+ lseek(f->fd, 0, SEEK_SET);
+ buf = xmalloc(pos);
+
+ read(f->fd, buf, pos);
+ set_exit_code_var(f->exit, hash);
+ set_last_pipe_var(buf, hash);
+ free(buf);
+
+ unlink(f->name);
+ free(f);
+end:
+ destroy_email(em);
+}
+
+void
+interp(struct list* ins, struct list* hash)
+{
+ struct code* p;
+ char* result;
+ int v;
+
+ p = (void*) ins->head.next;
+ while ((struct node*) p != &ins->head) {
+ switch (p->opcode) {
+ case OPC_SET:
+ result = get_var_nc(p->u.set.r);
+ set_var(p->u.set.l, result);
+ break;
+ case OPC_JUMP:
+ p = p->u.jump.target;
+ continue;
+ case OPC_JUMP_IF:
+ if (eval_cond(p->u.jump_if.cond)) {
+ p = p->u.jump_if.target;
+ continue;
+ }
+ break;
+ case OPC_JUMP_UNLESS:
+ if (!eval_cond(p->u.jump_unless.cond)) {
+ p = p->u.jump_unless.target;
+ continue;
+ }
+ break;
+ case OPC_NOP:
+ break;
+ case OPC_GT:
+ case OPC_LT:
+ case OPC_LE:
+ case OPC_GE:
+ case OPC_EQ:
+ case OPC_NEQ:
+ case OPC_AND:
+ case OPC_OR:
+ case OPC_XOR:
+ case OPC_PLUS:
+ case OPC_MINUS:
+ case OPC_MUL:
+ case OPC_DIV:
+ do_num_ternary_op(p);
+ break;
+ case OPC_NOT:
+ result = xmalloc(INT_TO_STRING_LEN);
+ sscanf(get_var_nc(p->u.dpop.par),"%d", &v);
+ sprintf(result, "%d", !v);
+ set_var(p->u.dpop.res, result);
+ free_string(result);
+ break;
+ case OPC_CAT:
+ case OPC_RE:
+ case OPC_NRE:
+ do_string_ternary_op(p);
+ break;
+ case OPC_PIPE:
+ do_pipe(get_var_nc(p->u.arrow.what), hash);
+ break;
+ case OPC_FILTER:
+ do_filter(get_var_nc(p->u.arrow.what), hash);
+ break;
+ case OPC_MAIL:
+ send_mail(get_var_nc(p->u.arrow.what),
+ p->u.arrow.copy, hash);
+ break;
+ case OPC_DELIVER:
+ deliver(get_var_nc(p->u.arrow.what),
+ p->u.arrow.copy, hash);
+ break;
+ case OPC_DISCARD:
+ bye(0, NULL);
+ break;
+ }
+ p = (void*) ((struct node*) p)->next;
+ }
+ deliver(default_mailbox, 0, hash);
+}
+
+void
+print_vars(struct list* hash)
+{
+ int i;
+ struct variable* p;
+
+ for (i=0; i<HASHSIZE; i++){
+ LIST_FOREACH(p, hash + i)
+ printf("%s=%s\n",p->name, get_var_nc(p->varcode));
+ }