17 #define INT_TO_STRING_LEN ((sizeof(int)*4*CHAR_BIT)/10 + 6)
19 static void __attribute__ ((noreturn))
20 bye(int code, char* msg, ...)
24 if (current_body->tmpfile)
25 unlink(current_body->tmpfile);
29 vfprintf(stderr, msg, args);
44 set_var(int var, char* value)
47 var_tab[var] = xstrdup(value);
55 return const_tab[-var];
59 /* return var struct or NULL if not found */
60 static struct variable*
61 get_var_struct(char* name, struct list* hash)
66 n = get_bucket_number(name);
67 int nocase = isupper(*name);
68 LIST_FOREACH(p, hash + n)
69 if (!(nocase ? strcasecmp : strcmp)(p->name,name))
76 regex_cmp(char* s, char* r)
81 int ovector[OVECCOUNT];
83 brum = pcre_compile(r,0,&error,&erroroffset,NULL);
87 int res = pcre_exec(brum,NULL,s,strlen(s),0,0,ovector,OVECCOUNT);
93 #define UPPER(a) ((a) >> 8)
94 #define LOWER(a) ((a) & 0xFF)
97 xcat(char* left, char* right)
99 char* res = xmalloc(strlen(left) + strlen(right) + 1);
111 modify_headers(struct list* headers, struct list* hash)
118 LIST_FOREACH(p, headers){
119 pv = get_var_struct(p->name, hash);
125 p->value = xstrdup(get_var(pv->varcode)); //FIXME: fold it
130 for (i = 0; i < HASHSIZE; i++){
131 LIST_FOREACH(pv, hash + i){
132 if (isupper(pv->name[0]) && pv->modified){
135 p = xmalloc(sizeof(struct hlist));
136 p->name = xstrdup(pv->name);
137 p->value = xstrdup(get_var(pv->varcode));
139 list_add_last(headers,&p->car);
146 copy_headers(struct list* orig)
148 struct list* new = xmalloc(sizeof(struct list));
149 struct hlist* po, *pn;
153 LIST_FOREACH(po, orig){
154 pn = xmalloc(sizeof(struct hlist));
155 pn->name = xstrdup(po->name);
156 pn->value = xstrdup(po->value);
159 list_add_last(new, &pn->car);
166 prepare_email(struct list* hash)
170 modify_headers(current_headers, hash);
171 em.headers = copy_headers(current_headers);
172 em.body_len = current_body->body_len;
173 em.fd = current_body->fd;
174 if (current_body->body) {
175 em.body = xmalloc(em.body_len);
176 memcpy(em.body, current_body->body, em.body_len);
179 em.tmpfile = xstrdup(current_body->tmpfile);
187 destroy_email(struct email em)
196 do_string_ternary_op(struct code* p)
198 char* l = get_var(p->u.tpop.l);
199 char* r = get_var(p->u.tpop.r);
204 result = xmalloc(INT_TO_STRING_LEN);
205 sprintf(result, "%d", regex_cmp(l, r));
207 result = xmalloc(INT_TO_STRING_LEN);
208 sprintf(result, "%d", !regex_cmp(l, r));
215 set_var(p->u.tpop.res, result);
219 do_num_ternary_op(struct code* p)
222 char* result = xmalloc(INT_TO_STRING_LEN);
224 sscanf(get_var(p->u.tpop.l),"%d", &l);
225 sscanf(get_var(p->u.tpop.r),"%d", &r);
253 res = ((l || r) && !(l && r));
271 sprintf(result, "%d", res);
272 set_var(p->u.tpop.res, result);
278 char* val = get_var(var);
285 sscanf(val, "%d", &v);
291 deliver(char* where, int copy, struct list* hash)
294 struct email em = prepare_email(hash);
296 res = deliver_local_email(where, &em);
309 interp(struct list* ins, struct list* hash)
315 var_tab = xmalloc(max_varcode * sizeof(char*));
317 LIST_FOREACH(p, ins) {
320 set_var(p->u.set.l, get_var(p->u.set.r));
323 p = p->u.jump.target;
327 if (eval_cond(p->u.jump_if.cond))
328 p = p->u.jump_if.target;
331 case OPC_JUMP_UNLESS:
332 if (!eval_cond(p->u.jump_unless.cond))
333 p = p->u.jump_unless.target;
352 do_num_ternary_op(p);
355 result = xmalloc(INT_TO_STRING_LEN);
356 sscanf(get_var(p->u.tpop.l),"%d", &v);
357 sprintf(result, "%d", !v);
358 set_var(p->u.tpop.res, result);
362 do_string_ternary_op(p);
369 deliver(get_var(p->u.arrow.what),
370 p->u.arrow.copy, hash);
378 deliver(default_mailbox, 0, hash);
382 print_vars(struct list* hash)
387 for (i=0; i<HASHSIZE; i++){
388 LIST_FOREACH(p, hash + i)
389 printf("%s=%s\n",p->name, get_var(p->varcode));
400 new = xmalloc(strlen(u)+1);
403 #define IS_WHITE(c) ((c) == '\t' || (c)==' ' || c=='\n')
405 while (IS_WHITE(*pu))
410 while (IS_WHITE(*pu))
423 save_current_headers(struct list* hash)
429 LIST_FOREACH(p, current_headers){
430 pv = get_var_struct(p->name, hash);
433 u = unfold(p->value);
434 set_var(pv->varcode, u);