#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sysexits.h>
#include <unistd.h>
}
last = c;
}
- //free(buf);
+ free_string(buf);
return l;
}
{
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;
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;
}
}
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++;
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;
}
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
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);