From 50516646f2475a9c9350e0fc7e924e039b739175 Mon Sep 17 00:00:00 2001 From: Anicka Bernathova Date: Wed, 22 Jul 2009 21:46:17 +0200 Subject: [PATCH] fix many little bugs, release 0.1 --- code.c | 1 + ham.c | 19 ++++++++++------- int.c | 66 ++++++++++++++++++++++++++++++++-------------------------- lex.c | 25 +++++++++++++--------- umpf.c | 4 +++- 5 files changed, 68 insertions(+), 47 deletions(-) diff --git a/code.c b/code.c index dfb47a6..94f25a1 100644 --- a/code.c +++ b/code.c @@ -364,6 +364,7 @@ compile(struct tree* t, struct list* where) break; case ST_COND: eval_cond(t, -1, where); // warn? + break; case ST_ARROW: do_arrow(t, where); break; diff --git a/ham.c b/ham.c index fa0cc3d..7028304 100644 --- a/ham.c +++ b/ham.c @@ -186,7 +186,7 @@ get_body(int rfd) res = write(fd, buf, MAIL_LEN); if (res < MAIL_LEN) { unlink(b->tmpfile); - bye(EX_TEMPFAIL, "Cannot write to remporary file: %m"); + bye(EX_TEMPFAIL, "Cannot write to temporary file: %m"); } break; } @@ -326,15 +326,20 @@ int write_email_to_fd(int fd, struct email* email) { char* buf; - int wr; + int wr, to_write; open_email(); - do { + for (;;) { buf = read_email(email); - wr = write(fd, buf, chars_written); - if (wr < chars_written) - return 1; - } while (chars_written); + if (!chars_written) + break; + + to_write = chars_written; + while (to_write) { + wr = write(fd, buf, to_write); + to_write -= wr; + } + }; return 0; } diff --git a/int.c b/int.c index cdb5715..d5a39bf 100644 --- a/int.c +++ b/int.c @@ -80,35 +80,31 @@ set_var(int var, char* value) void set_cur_mail_length_var(int len, struct list* hash) { - char* buf; struct variable* pv; + char buf[INT_TO_STRING_LEN]; pv = get_var_struct(INT_VAR_MAIL_LEN, VAR_INTERN, hash); if (! pv) /* user is not interested */ return; - buf = xmalloc(INT_TO_STRING_LEN); sprintf(buf,"%d", len); set_var(pv->varcode, buf); - free_string(buf); } static void set_exit_code_var(int code, struct list* hash) { - char* buf; struct variable* pv; + char buf[INT_TO_STRING_LEN]; pv = get_var_struct(INT_VAR_LAST_EXIT, VAR_INTERN, hash); if (! pv) /* user is not interested */ return; - buf = xmalloc(INT_TO_STRING_LEN); sprintf(buf,"%d", code); set_var(pv->varcode, buf); - free_string(buf); } static void @@ -131,6 +127,14 @@ get_var(int var) return xstrdup(var_tab[var].value); } +static char* +get_var_nc(int var) +{ + if (var < 0) + return const_tab[-var]; + return var_tab[var].value; +} + static int regex_cmp(char* s, char* r) { @@ -172,7 +176,7 @@ fold(const char* value, int taken) int i; char* ret; int len = strlen(value); - int newlines[len / 78 + 5]; + int newlines[len / 40 + 5]; int newl = 0; int curr_ws = -1; int pos = 0; @@ -205,9 +209,9 @@ fold(const char* value, int taken) if(i != newlines[newl_done]) ret[pos++] = value[i]; else { - newl++; + newl_done++; ret[pos++] = '\n'; - ret[pos++] = ' '; + ret[pos++] = '\t'; } } return ret; @@ -256,7 +260,7 @@ modify_headers(struct list* headers, struct list* hash) if (!pv) continue; u = unfold(p->value); - value = get_var(pv->varcode); + value = get_var_nc(pv->varcode); if (strcmp(u, value)){ set_modif_flag(pv->varcode, 0); free_string(p->value); @@ -264,7 +268,6 @@ modify_headers(struct list* headers, struct list* hash) strlen(p->name) + 2); } free_string(u); - free_string(value); } // find new headers @@ -359,8 +362,8 @@ destroy_email(struct email em) static void do_string_ternary_op(struct code* p) { - char* l = get_var(p->u.tpop.l); - char* r = get_var(p->u.tpop.r); + char* l = get_var_nc(p->u.tpop.l); + char* r = get_var_nc(p->u.tpop.r); char* result; switch(p->opcode) { @@ -378,18 +381,18 @@ do_string_ternary_op(struct code* p) default: break; }; - + free_string(result); set_var(p->u.tpop.res, result); } static void do_num_ternary_op(struct code* p) { - int l, r, res; + int l = 0, r = 0, res; char* result = xmalloc(INT_TO_STRING_LEN); - sscanf(get_var(p->u.tpop.l),"%d", &l); - sscanf(get_var(p->u.tpop.r),"%d", &r); + sscanf(get_var_nc(p->u.tpop.l),"%d", &l); + sscanf(get_var_nc(p->u.tpop.r),"%d", &r); switch(p->opcode) { case OPC_GT: @@ -436,13 +439,14 @@ do_num_ternary_op(struct code* p) } sprintf(result, "%d", res); + free_string(result); set_var(p->u.tpop.res, result); } static int eval_cond(int var) { - char* val = get_var(var); + char* val = get_var_nc(var); int v; if (! val) @@ -491,7 +495,8 @@ send_mail(char* where, int copy, struct list* hash) dup(pd[0]); close(pd[0]); //FIXME From? - res = execl("/usr/lib/sendmail", "sendmail", where, NULL); + execl("/usr/lib/sendmail", "sendmail", where, NULL); + exit(1); } close(pd[0]); write_email_to_fd(pd[1], &em); @@ -548,7 +553,8 @@ pipe_to(char* program, struct email* em) close(pd_out[1]); close(pd_in[1]); close(pd_out[0]); - res = execl("/bin/sh", "sh", "-c", program, NULL); + execl("/bin/sh", "sh", "-c", program, NULL); + exit(1); } close(pd_in[0]); close(pd_out[1]); @@ -571,8 +577,11 @@ pipe_to(char* program, struct email* em) break; write(fd, buf, r); } - if (pfd[0].revents & POLLHUP) + if (pfd[0].revents & POLLHUP) { + if (e) + free_string(e); break; + } if (nfds < 2) continue; @@ -709,9 +718,8 @@ interp(struct list* ins, struct list* hash) while ((struct node*) p != &ins->head) { switch (p->opcode) { case OPC_SET: - result = get_var(p->u.set.r); + result = get_var_nc(p->u.set.r); set_var(p->u.set.l, result); - free_string(result); break; case OPC_JUMP: p = p->u.jump.target; @@ -747,7 +755,7 @@ interp(struct list* ins, struct list* hash) break; case OPC_NOT: result = xmalloc(INT_TO_STRING_LEN); - sscanf(get_var(p->u.dpop.par),"%d", &v); + sscanf(get_var_nc(p->u.dpop.par),"%d", &v); sprintf(result, "%d", !v); set_var(p->u.dpop.res, result); free_string(result); @@ -758,17 +766,17 @@ interp(struct list* ins, struct list* hash) do_string_ternary_op(p); break; case OPC_PIPE: - do_pipe(get_var(p->u.arrow.what), hash); + do_pipe(get_var_nc(p->u.arrow.what), hash); break; case OPC_FILTER: - do_filter(get_var(p->u.arrow.what), hash); + do_filter(get_var_nc(p->u.arrow.what), hash); break; case OPC_MAIL: - send_mail(get_var(p->u.arrow.what), + send_mail(get_var_nc(p->u.arrow.what), p->u.arrow.copy, hash); break; case OPC_DELIVER: - deliver(get_var(p->u.arrow.what), + deliver(get_var_nc(p->u.arrow.what), p->u.arrow.copy, hash); break; case OPC_DISCARD: @@ -788,7 +796,7 @@ print_vars(struct list* hash) for (i=0; iname, get_var(p->varcode)); + printf("%s=%s\n",p->name, get_var_nc(p->varcode)); } } diff --git a/lex.c b/lex.c index e16a724..89fb71b 100644 --- a/lex.c +++ b/lex.c @@ -97,19 +97,21 @@ xstrdup(const char* s) static char* get_string_out(int delim) { - int last = delim; int i = 0; int c; char buf[BUFSIZE]; - while ((c = getc(conf)) != delim || last == '\\'){ - if (last=='\\' && c != delim) - buf[i-1] = c; - else { - buf[i] = c; - i++; - } - last = c; + while ((c = getc(conf)) != delim){ + if (c == '\\') { + c = getc(conf); + if (c == EOF) + parse_err("Unbounded string, %c missing", delim); + buf[i++] = c; + } else if (c == '\n' || c == EOF) + parse_err("Unbounded string, %c missing", delim); + else + buf[i++] = c; + if (i >= BUFSIZE-1) parse_err("Too long string, max allowed length is %d",BUFSIZE-1); } @@ -222,7 +224,8 @@ yylex(void) if (i >= BUFSIZE-1) parse_err("Too long number"); } - ungetc(c,conf); + if (c != EOF) + ungetc(c,conf); buf[i] = 0; yylval.str = xstrdup(buf); @@ -239,6 +242,8 @@ yylex(void) if (i >= BUFSIZE-1) parse_err("Too long identifier, max allowed length is %d",BUFSIZE-1); } + if (!i) + parse_err("Variable identifier must not be empty"); if (c > 0) ungetc(c,conf); buf[i] = 0; diff --git a/umpf.c b/umpf.c index 663294f..52a8449 100644 --- a/umpf.c +++ b/umpf.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "umpf.h" @@ -13,6 +14,7 @@ void init(void) { + signal(SIGPIPE, SIG_IGN); list_init(&input_code); var_hash = new_var_hash(); const_tab = xmalloc(BUFSIZE); @@ -96,6 +98,7 @@ main(int argc, char** argv) int res, i, opt; char* conffile = NULL; + save_gids(); while ((opt = getopt(argc, argv, "c:m:")) != -1) { switch (opt) { case 'm': @@ -118,7 +121,6 @@ main(int argc, char** argv) default_mailbox = cat("/var/mail/", p->pw_name); } - save_gids(); init(); /* returning from longjump? save the mail and exit */ -- 2.39.2