13 char mbox_write_buf[BUFSIZE];
18 new_header(char* buf, struct list* h)
23 new = xmalloc(sizeof(struct hlist));
27 new->value = xstrdup("");
30 new->value = xstrdup(p+1);
31 p = strrchr(new->value, '\n');
35 new->name = xstrdup(buf);
37 list_add_last(h, &new->car);
43 struct list* l = xmalloc(sizeof(struct list));
45 int i = 0; /* current position */
49 buf = xmalloc(BUFSIZE);
52 while ((c = getchar()) != EOF){
56 if (i >= curbufsize-2)
57 buf = xrealloc(buf, curbufsize *= 2);
63 if ((c = getchar()) != ' ' && c != '\t'){
86 int curbufsize = MAIL_LEN;
90 buf = xmalloc(MAIL_LEN);
91 b = xmalloc(sizeof(struct email));
96 /* read mail body, if it is too big, try to make tmp file */
97 while ((c = getchar()) != EOF){
99 if (i >= curbufsize - 1) {
100 tmpfile = xstrdup("/tmp/umpf.XXXXXX");
101 fd = mkstemp(tmpfile);
102 /* cannot create tmpfile, try to continue reading */
104 bye(EX_TEMPFAIL, "%m");
108 b->tmpfile = tmpfile;
110 res = write(fd, buf, MAIL_LEN);
111 if (res < MAIL_LEN) {
113 bye(EX_TEMPFAIL, "%m");
120 /* save rest of the body to the tmpfile */
123 while ((c = getchar()) != EOF){
128 res = write(fd, buf, MAIL_LEN);
129 if (res < MAIL_LEN) {
131 bye(EX_TEMPFAIL, "%m");
135 res = write(fd, buf, j);
138 bye(EX_TEMPFAIL, "%m");
145 print_headers(struct list* l)
150 printf("%s:%s\n",p->name,p->value);
154 flush_mbox_buffer(int fd)
156 if (mbox_write_err || !mbox_write_pos)
160 res = write(fd, mbox_write_buf, mbox_write_pos);
167 write_char_to_mailbox(char c, int fd)
171 if (mbox_write_pos >= BUFSIZE){
172 res = write(fd, mbox_write_buf, BUFSIZE);
178 mbox_write_buf[mbox_write_pos++] = c;
194 read_email(struct email* em)
199 if (! email_opened) {
204 if (! headers_sent) {
206 int curbufsize = BUFSIZE;
207 buf = xmalloc(BUFSIZE);
210 LIST_FOREACH(ph, em->headers){
211 int needed = strlen(ph->name) + strlen(ph->value) + 3;
212 if (curbufsize < pos + needed)
213 buf = xrealloc(buf, curbufsize*=2);
214 strcpy(buf + pos, ph->name);
215 pos += strlen(ph->name);
217 strcpy(buf + pos, ph->value);
218 pos += strlen(ph->value);
229 buf = xstrdup(em->body);
230 chars_written = em->body_len;
231 //printf("%d: %s\n", em->body_len, em->body);
237 lseek(em->fd, 0, SEEK_SET);
239 buf = xmalloc(MAIL_LEN + 1);
240 r = read(em->fd, buf, MAIL_LEN);
249 write_email_to_fd(int fd, struct email* email)
256 buf = read_email(email);
257 wr = write(fd, buf, chars_written);
258 if (wr < chars_written)
260 } while (chars_written);
265 /* try to copy e-mail to mailbox, if it fails,
266 truncate mailbox to the original size */
268 copy_email(int fd, struct email* email)
272 mb_end = lseek(fd, 0, SEEK_END);
283 LIST_FOREACH(ph, email->headers){
284 for (pc = ph->name; *pc; pc++)
285 write_char_to_mailbox(*pc, fd);
286 write_char_to_mailbox(':', fd);
287 for (pc = ph->value; *pc; pc++)
288 write_char_to_mailbox(*pc, fd);
289 write_char_to_mailbox('\n', fd);
292 write_char_to_mailbox('\n', fd);
294 /* FIXME: do not forget change Content-Length */
296 for (pc = email->body; pc < email->body + email->body_len; pc++){
297 write_char_to_mailbox(*pc, fd);
299 if ((pc + 5 < email->body + email->body_len)
300 && pc[1] == 'F' && pc[2] == 'r'
301 && pc[3] == 'o' && pc[4] == 'm'
303 write_char_to_mailbox('>', fd);
309 for(i = 0; i < email->body_len; i+=MAIL_LEN) {
311 if (i >= email->body_len)
312 len = len - (i - email->body_len);
313 read(email->fd, buf, len); //FIXME: check it?
314 for (pc = buf; pc < buf + len; pc++) {
315 write_char_to_mailbox(*pc, fd);
317 if ((pc + 5 < email->body + email->body_len)
318 && pc[1] == 'F' && pc[2] == 'r'
319 && pc[3] == 'o' && pc[4] == 'm'
321 write_char_to_mailbox('>', fd);
327 flush_mbox_buffer(fd);
331 /* try to truncate to the original length */
332 ftruncate(fd, mb_end);
340 deliver_local_email(char* folder, struct email* email)
343 int is_default_mailbox = 0;
346 if (!strcmp(default_mailbox, folder))
347 is_default_mailbox = 1;
349 fd = open_mailbox(folder, is_default_mailbox);
351 if (is_default_mailbox)
353 else /* try to save to default mailbox instead */
354 return deliver_local_email(default_mailbox, email);
357 res = copy_email(fd, email);
360 /* try to deliver to the default mailbox */
361 if (is_default_mailbox)
364 return deliver_local_email(default_mailbox, email);
367 close_mailbox(fd, folder, is_default_mailbox);