]> mj.ucw.cz Git - umpf.git/blobdiff - ham.c
rewrite write_email_to_fd
[umpf.git] / ham.c
diff --git a/ham.c b/ham.c
index 4c74d937cd3305590ef64fb7e4e82dfa7b88bfee..707e6f2664346336475030cb3b5fabd492b86d32 100644 (file)
--- a/ham.c
+++ b/ham.c
@@ -1,6 +1,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sysexits.h>
 
 #include <unistd.h>
 
@@ -70,7 +71,7 @@ make_hlist(void)
                }
                        last = c;
        }
-       //free(buf);
+       free_string(buf);
        return l;
 }
 
@@ -79,10 +80,9 @@ get_body(void)
 {
        char* buf;
        struct email* b;
-       int c, fd, cannot_save = 0;
+       int c, fd;
        int will_save = 0;
        int i = 0;
-       int j = 0;
        int curbufsize = MAIL_LEN;
        char* tmpfile;
        int res;
@@ -97,23 +97,21 @@ get_body(void)
        while ((c = getchar()) != EOF){
                buf[i++] = c;
                if (i >= curbufsize - 1) {
-                       if (cannot_save) {
-                               buf = xrealloc(buf, curbufsize *= 2);
-                               continue;
-                       }
                        tmpfile = xstrdup("/tmp/umpf.XXXXXX");
                        fd = mkstemp(tmpfile);
                        /* cannot create tmpfile, try to continue reading */
-                       if (fd < 0) {
-                               buf = xrealloc(buf, curbufsize *= 2);
-                               cannot_save = 1;
-                               free(tmpfile);
-                               continue;
-                       } else {
+                       if (fd < 0)
+                               bye(EX_TEMPFAIL, "%m");
+                       else {
                                will_save = 1;
                                b->body = NULL;
                                b->tmpfile = tmpfile;
                                b->fd = fd;
+                               res = write(fd, buf, MAIL_LEN);
+                               if (res < MAIL_LEN) {
+                                       unlink(b->tmpfile);
+                                       bye(EX_TEMPFAIL, "%m");
+                               }
                                break;  
                        }
                }
@@ -121,6 +119,7 @@ get_body(void)
        b->body_len = i;
        /* save rest of the body to the tmpfile */
        if (will_save) {
+               int j = 0;
                while ((c = getchar()) != EOF){
                        buf[j++] = c;
                        b->body_len++;
@@ -128,32 +127,17 @@ get_body(void)
                                j = 0;
                                res = write(fd, buf, MAIL_LEN);
                                if (res < MAIL_LEN) {
-                                       int missing = MAIL_LEN - res;
-                                       curbufsize = 2*b->body_len;
-                                       buf = xrealloc(buf, curbufsize);
-                                       // no point to check length here
-                                       read(fd, buf, b->body_len - missing);
                                        unlink(b->tmpfile);
-                                       b->tmpfile = NULL;
-                                       b->fd = -1;
-                                       b->body = buf;
-                                       break;
+                                       bye(EX_TEMPFAIL, "%m");
                                }
                        }
                }
-               /* could not write all the body to the tmpfile, try to read
-                       the rest */
-               if (b->body) {
-                       while ((c = getchar()) != EOF){
-                               buf[j++] = c;
-                               b->body_len++;
-                               if (i >= curbufsize - 1) {
-                                       buf = xrealloc(buf, curbufsize *= 2);
-                               }
-                       }
+               res = write(fd, buf, j);
+               if (res < j) {
+                       unlink(b->tmpfile);
+                       bye(EX_TEMPFAIL, "%m");
                }
        }
-
        return b; 
 }
 
@@ -194,6 +178,90 @@ write_char_to_mailbox(char c, int fd)
        mbox_write_buf[mbox_write_pos++] = c;
 }
 
+int email_pos;
+int headers_sent;
+int email_opened;
+
+void
+open_email(void)
+{
+       email_pos = 0;
+       headers_sent = 0;
+       email_opened = 1;
+}
+
+char*
+read_email(struct email* em)
+{
+       char* buf;
+       int r, pos;
+
+       if (! email_opened) {
+               chars_written = 0;      
+               return NULL;
+       }
+
+       if (! headers_sent) {
+               struct hlist* ph;
+               int curbufsize = BUFSIZE;
+               buf = xmalloc(BUFSIZE);
+               pos = 0;
+
+               LIST_FOREACH(ph, em->headers){
+                       int needed = strlen(ph->name) + strlen(ph->value) + 3;
+                       if (curbufsize < pos + needed)
+                               buf = xrealloc(buf, curbufsize*=2);
+                       strcpy(buf + pos, ph->name);
+                       pos += strlen(ph->name);
+                       buf[pos++] = ':';
+                       strcpy(buf + pos, ph->value);
+                       pos += strlen(ph->value);
+                       buf[pos++] = '\n';
+       
+               }
+               buf[pos] = '\n';
+               headers_sent = 1;
+               chars_written = pos;
+               return buf;
+       }
+
+       if (em->body) {
+               buf = xstrdup(em->body);
+               chars_written = em->body_len; 
+               //printf("%d: %s\n", em->body_len, em->body); 
+               email_opened = 0;
+               return buf;
+       }
+
+       if (! email_pos)
+               lseek(em->fd, 0, SEEK_SET);
+
+       buf = xmalloc(MAIL_LEN + 1);
+       r = read(em->fd, buf, MAIL_LEN);
+       if (r < MAIL_LEN)
+               email_opened = 0;
+       chars_written = r;
+       
+       return buf;
+}
+
+int
+write_email_to_fd(int fd, struct email* email)
+{
+       char* buf;
+       int wr;
+
+       open_email();
+       do {
+               buf = read_email(email);
+               wr = write(fd, buf, chars_written);
+               if (wr < chars_written)
+                       return 1;
+       } while (chars_written);
+       
+       return 0;
+}
+
 /* try to copy e-mail to mailbox, if it fails,
  truncate mailbox to the original size */
 static int
@@ -216,7 +284,6 @@ copy_email(int fd, struct email* email)
                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);