From 9e573377db97de70dc6661d752c29b9e1ed1d54a Mon Sep 17 00:00:00 2001 From: Anicka Bernathova Date: Wed, 22 Jul 2009 12:33:57 +0200 Subject: [PATCH] fix some minor bug, cope with From line correctly --- ham.c | 55 +++++++++++++++++++++++------------------- lex.c | 6 +++-- umpf.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ umpf.h | 1 + 4 files changed, 111 insertions(+), 26 deletions(-) diff --git a/ham.c b/ham.c index e54ec5e..fa0cc3d 100644 --- a/ham.c +++ b/ham.c @@ -101,6 +101,8 @@ make_hlist(int fd) char* buf; int i = 0; /* current position */ int c, last = 0; + int first_line = 1; + int want_from_line = 0; list_init(l); buf = xmalloc(BUFSIZE); @@ -110,11 +112,28 @@ make_hlist(int fd) if (c == '\r') continue; - if (i >= curbufsize-2) + if (i >= curbufsize-3) buf = xrealloc(buf, curbufsize *= 2); - buf[i++] = c; + if (first_line && + ( (!i && c != 'F') || (i == 1 && c != 'r') || (i == 2 && c != 'o') + || (i == 3 && c != 'm') || (i == 4 && c != ' ') ) + ) + first_line = 0; + else { + if (first_line && i == 4) + want_from_line = 1; + } + + buf[i++] = c; if (c == '\n'){ + if (want_from_line) { + buf[i] = 0; + fromline = xstrdup(buf); + want_from_line = 0; + i = 0; + continue; + } if (last == '\n') break; if ((c = give_me_char(fd)) != ' ' && c != '\t'){ @@ -266,7 +285,7 @@ read_email(struct email* em) LIST_FOREACH(ph, em->headers){ int needed = strlen(ph->name) + strlen(ph->value) + 4; - if (curbufsize < pos + needed) + while (curbufsize < pos + needed) buf = xrealloc(buf, curbufsize*=2); strcpy(buf + pos, ph->name); pos += strlen(ph->name); @@ -338,33 +357,21 @@ copy_email(int fd, struct email* email) /* From line */ struct hlist* ph; int i, len; - char* fromline; - char* from = NULL; time_t t; time(&t); char* date = ctime(&t); int datelen = strlen(date); - - LIST_FOREACH(ph, email->headers) { - if (!strcasecmp(ph->name, "From")) { - from = ph->value; - break; - } - } - len = 5 + datelen + 1; - if (from) - len += strlen(from); - - fromline = xmalloc(len); - if (from) - sprintf(fromline, "From %s %s", from, date); - else - sprintf(fromline, "From %s", date); - len = strlen(fromline); + if (! fromline) { + len = 5 + datelen + 1; + fromline = xmalloc(len); + sprintf(fromline, "From %s", date); + len = strlen(fromline); + } else + len = strlen(fromline); for (i = 0; i < len; i++) write_char_to_mailbox(fromline[i], fd); - + /* headers */ char* pc; LIST_FOREACH(ph, email->headers){ @@ -374,7 +381,7 @@ copy_email(int fd, struct email* email) write_char_to_mailbox(' ', fd); for (pc = ph->value; *pc; pc++) write_char_to_mailbox(*pc, fd); - write_char_to_mailbox('\n', fd); + write_char_to_mailbox('\n', fd); } write_char_to_mailbox('\n', fd); diff --git a/lex.c b/lex.c index 9512630..e16a724 100644 --- a/lex.c +++ b/lex.c @@ -239,7 +239,8 @@ yylex(void) if (i >= BUFSIZE-1) parse_err("Too long identifier, max allowed length is %d",BUFSIZE-1); } - ungetc(c,conf); + if (c > 0) + ungetc(c,conf); buf[i] = 0; yylval.str = xstrdup(buf); @@ -257,7 +258,8 @@ yylex(void) parse_err("Keyword too long"); } buf[i] = 0; - ungetc(c,conf); + if (c > 0) + ungetc(c,conf); n = (sizeof(kwds)/sizeof(struct keys)); for (i = 0; i < n; i++){ diff --git a/umpf.c b/umpf.c index 5918a0d..663294f 100644 --- a/umpf.c +++ b/umpf.c @@ -3,6 +3,8 @@ #include #include #include +#include +#include #include "umpf.h" @@ -19,6 +21,75 @@ init(void) empty = ""; } +char* buf; +int buflen; +char tmpbuf[BUFSIZE]; +int tmpbufpos; +int tmpread; + +char* +read_line(int fd) +{ + if (! buflen) + buf = xmalloc(BUFSIZE); + char* p = buf; + do { + if (tmpbufpos >= tmpread) { + tmpread = read(fd, tmpbuf, BUFSIZE); + tmpbufpos = 0; + } + if (!tmpread) + return NULL; + if (p >= (buf + buflen - 1)) + buf = xrealloc(buf, buflen *= 2); + *p++ = tmpbuf[tmpbufpos++]; + } while (*p != '\n'); + *++p = 0; + + return buf; +} + +char* +get_home_from_passwd(void) +{ + struct passwd* pas; + pas = getpwuid(getuid()); + if (! pas) + die("Cannot get uid, please specify config file path"); + + char* login = pas->pw_name; + int len = strlen(pas->pw_name); + char* buf; + char* p, *q; + int r, i; + + int fd; + fd = open("/etc/passwd", O_RDONLY); + if (fd < 0) + die("Cannot open /etc/passwd, please specify config file path"); + + do { + buf = read_line(fd); + r = strncmp(buf, login, len); + if (!r) + break; + } while (buf); + if (!r) + die("Cannot find your login %s in /etc/passwd, please specify config file path", login); + p = buf; + for (i = 0; i < 5; i++) { + p = strchr(p, ':'); + if (! p) + die("Cannot parse /etc/passwd, please specify config file path"); + } + q = p + 1; + while (*q && *q != '\n' && *q != ':') + q++; + *q = 0; + + return xstrdup(p + 1); +} + int main(int argc, char** argv) { @@ -42,6 +113,8 @@ main(int argc, char** argv) struct passwd* p; p = getpwuid(getuid()); + if (! p) + die("Cannot get uid, please specify default mailbox"); default_mailbox = cat("/var/mail/", p->pw_name); } @@ -57,6 +130,8 @@ main(int argc, char** argv) char* home; home = getenv("HOME"); + if (! home) + home = get_home_from_passwd(); if (! home) goto skip_conf; diff --git a/umpf.h b/umpf.h index f0bf8bb..0d0697f 100644 --- a/umpf.h +++ b/umpf.h @@ -233,6 +233,7 @@ void set_cur_mail_length_var(int len, struct list* hash); char* default_mailbox; int chars_written; int curr_email_len; +char* fromline; struct list* current_headers; struct email* current_body; -- 2.39.2