]> mj.ucw.cz Git - umpf.git/blobdiff - ham.c
fix many little bugs, release 0.1
[umpf.git] / ham.c
diff --git a/ham.c b/ham.c
index 3e6dade23fc652ace1c8ff1b9a8fa004ddf193a0..7028304dd14a37205898aba1428d3493eac8beae 100644 (file)
--- a/ham.c
+++ b/ham.c
@@ -2,6 +2,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sysexits.h>
+#include <time.h>
 
 #include <unistd.h>
 
@@ -27,7 +28,10 @@ new_header(char* buf, struct list* h)
                new->value = xstrdup("");
        else {
                *p = 0;
-               new->value = xstrdup(p+1);
+               if (*(p + 1) == ' ')
+                       new->value = xstrdup(p + 2);
+               else
+                       new->value = xstrdup(p + 1);
                p = strrchr(new->value, '\n');
                if (p && !*(p+1))
                        *p = 0;
@@ -97,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);
@@ -106,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'){
@@ -163,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;  
                        }
@@ -261,18 +284,19 @@ read_email(struct email* em)
                pos = 0;
 
                LIST_FOREACH(ph, em->headers){
-                       int needed = strlen(ph->name) + strlen(ph->value) + 3;
-                       if (curbufsize < pos + needed)
+                       int needed = strlen(ph->name) + strlen(ph->value) + 4;
+                       while (curbufsize < pos + needed)
                                buf = xrealloc(buf, curbufsize*=2);
                        strcpy(buf + pos, ph->name);
                        pos += strlen(ph->name);
                        buf[pos++] = ':';
+                       buf[pos++] = ' ';
                        strcpy(buf + pos, ph->value);
                        pos += strlen(ph->value);
                        buf[pos++] = '\n';
        
                }
-               buf[pos] = '\n';
+               buf[pos++] = '\n';
                headers_sent = 1;
                chars_written = pos;
                return buf;
@@ -302,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;
 }
@@ -330,16 +359,34 @@ copy_email(int fd, struct email* email)
        mbox_write_err = 0;
        mbox_write_pos = 0;
 
-       /* headers */
+       /* From line */
        struct hlist* ph;
+       int i, len;
+       time_t t;
+       time(&t);
+       char* date = ctime(&t);
+       int datelen = strlen(date);
+
+       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){
                for (pc = ph->name; *pc; pc++)
                        write_char_to_mailbox(*pc, fd);
                write_char_to_mailbox(':', fd); 
+               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);