16 #define INT_TO_STRING_LEN ((sizeof(int)*4*CHAR_BIT)/10 + 6)
26 set_var(int var, char* value)
29 var_tab[var] = xstrdup(value);
37 return const_tab[-var];
41 /* return var struct or NULL if not found */
42 static struct variable*
43 get_var_struct(char* name, struct list* hash)
48 n = get_bucket_number(name);
49 int nocase = isupper(*name);
50 LIST_FOREACH(p, hash + n)
51 if (!(nocase ? strcasecmp : strcmp)(p->name,name))
58 regex_cmp(char* s, char* r)
63 int ovector[OVECCOUNT];
65 brum = pcre_compile(r,0,&error,&erroroffset,NULL);
69 int res = pcre_exec(brum,NULL,s,strlen(s),0,0,ovector,OVECCOUNT);
75 #define UPPER(a) ((a) >> 8)
76 #define LOWER(a) ((a) & 0xFF)
79 xcat(char* left, char* right)
81 char* res = xmalloc(strlen(left) + strlen(right) + 1);
93 modify_headers(struct list* headers, struct list* hash)
100 LIST_FOREACH(p, headers){
101 pv = get_var_struct(p->name, hash);
107 p->value = xstrdup(get_var(pv->varcode)); //FIXME: fold it
112 for (i = 0; i < HASHSIZE; i++){
113 LIST_FOREACH(pv, hash + i){
114 if (isupper(pv->name[0]) && pv->modified){
117 p = xmalloc(sizeof(struct hlist));
118 p->name = xstrdup(pv->name);
119 p->value = xstrdup(get_var(pv->varcode));
121 list_add_last(headers,&p->car);
128 copy_headers(struct list* orig)
130 struct list* new = xmalloc(sizeof(struct list));
131 struct hlist* po, *pn;
135 LIST_FOREACH(po, orig){
136 pn = xmalloc(sizeof(struct hlist));
137 pn->name = xstrdup(po->name);
138 pn->value = xstrdup(po->value);
141 list_add_last(new, &pn->car);
148 prepare_email(struct list* hash)
152 modify_headers(current_headers, hash);
153 em.headers = copy_headers(current_headers);
154 em.body_len = current_body->body_len;
155 em.body = xmalloc(em.body_len);
156 memcpy(em.body, current_body->body, em.body_len);
162 do_string_ternary_op(struct code* p)
164 char* l = get_var(p->u.tpop.l);
165 char* r = get_var(p->u.tpop.r);
170 result = xmalloc(INT_TO_STRING_LEN);
171 sprintf(result, "%d", regex_cmp(l, r));
173 result = xmalloc(INT_TO_STRING_LEN);
174 sprintf(result, "%d", !regex_cmp(l, r));
181 set_var(p->u.tpop.res, result);
185 do_num_ternary_op(struct code* p)
188 char* result = xmalloc(INT_TO_STRING_LEN);
190 sscanf(get_var(p->u.tpop.l),"%d", &l);
191 sscanf(get_var(p->u.tpop.r),"%d", &r);
219 res = ((l || r) && !(l && r));
237 sprintf(result, "%d", res);
238 set_var(p->u.tpop.res, result);
244 char* val = get_var(var);
251 sscanf(val, "%d", &v);
259 //FIXME: add some magic
264 deliver(char* where, int copy, int last_try, struct list* hash)
267 int fd, len, written;
269 struct email em = prepare_email(hash);
272 fd = open_mailbox(where, last_try);
275 off = lseek(fd, 0, SEEK_END);
278 LIST_FOREACH(p, em.headers) {
279 len = strlen(p->name);
280 written = write(fd, p->name, len);
286 written = write(fd, ": ", 2);
292 len = strlen(p->value);
293 written = write(fd, p->value, len);
299 written = write(fd, "\n", 1);
305 written = write(fd, "\n", 1);
311 written = write(fd, em.body, em.body_len);
312 if (written < em.body_len) {
318 close_mailbox(fd, where, last_try);
323 if (!copy || last_try)
326 if (!copy || last_try)
333 interp(struct list* ins, struct list* hash)
339 LIST_FOREACH(p, ins) {
342 set_var(p->u.set.l, get_var(p->u.set.r));
345 p = p->u.jump.target;
349 if (eval_cond(p->u.jump_if.cond))
350 p = p->u.jump_if.target;
353 case OPC_JUMP_UNLESS:
354 if (!eval_cond(p->u.jump_unless.cond))
355 p = p->u.jump_unless.target;
374 do_num_ternary_op(p);
377 result = xmalloc(INT_TO_STRING_LEN);
378 sscanf(get_var(p->u.tpop.l),"%d", &v);
379 sprintf(result, "%d", !v);
380 set_var(p->u.tpop.res, result);
384 do_string_ternary_op(p);
391 deliver(get_var(p->u.arrow.what),
392 p->u.arrow.copy, 0, hash);
400 deliver(default_mailbox, 0, 1, hash);
404 print_vars(struct list* hash)
409 for (i=0; i<HASHSIZE; i++){
410 LIST_FOREACH(p, hash + i)
411 printf("%s=%s\n",p->name, get_var(p->varcode));
422 new = xmalloc(strlen(u)+1);
425 #define IS_WHITE(c) ((c) == '\t' || (c)==' ' || c=='\n')
427 while (IS_WHITE(*pu))
432 while (IS_WHITE(*pu))
445 save_current_headers(struct list* hash)
451 LIST_FOREACH(p, current_headers){
452 pv = get_var_struct(p->name, hash);
455 u = unfold(p->value);
456 set_var(pv->varcode, u);