10 #define MAIL_LEN 65536
14 char mbox_write_buf[BUFSIZE];
19 new_header(char* buf, struct list* h)
24 new = xmalloc(sizeof(struct hlist));
28 new->value = xstrdup("");
32 new->value = xstrdup(p + 2);
34 new->value = xstrdup(p + 1);
35 p = strrchr(new->value, '\n');
39 new->name = xstrdup(buf);
41 list_add_last(h, &new->car);
45 char gmc_buf[BUFSIZE];
55 gmc_read = read(fd, gmc_buf, BUFSIZE);
61 if (gmc_unget != EOF) {
73 if (gmc_pos < gmc_read) {
75 return gmc_buf[gmc_pos++];
78 gmc_read = read(fd, gmc_buf, BUFSIZE);
85 return gmc_buf[gmc_pos++];
100 struct list* l = xmalloc(sizeof(struct list));
102 int i = 0; /* current position */
105 int want_from_line = 0;
108 buf = xmalloc(BUFSIZE);
109 curbufsize = BUFSIZE;
111 while ((c = give_me_char(fd)) != EOF){
115 if (i >= curbufsize-3)
116 buf = xrealloc(buf, curbufsize *= 2);
119 ( (!i && c != 'F') || (i == 1 && c != 'r') || (i == 2 && c != 'o')
120 || (i == 3 && c != 'm') || (i == 4 && c != ' ') )
124 if (first_line && i == 4)
130 if (want_from_line) {
132 fromline = xstrdup(buf);
139 if ((c = give_me_char(fd)) != ' ' && c != '\t'){
162 int curbufsize = MAIL_LEN;
166 buf = xmalloc(MAIL_LEN);
167 b = xmalloc(sizeof(struct email));
172 /* read mail body, if it is too big, try to make tmp file */
173 while ((c = give_me_char(rfd)) != EOF){
175 if (i >= curbufsize - 1) {
176 tmpfile = xstrdup("/tmp/umpf.XXXXXX");
177 fd = mkstemp(tmpfile);
178 /* cannot create tmpfile, try to continue reading */
180 bye(EX_TEMPFAIL, "Cannot create temporary file: %m");
184 b->tmpfile = tmpfile;
186 res = write(fd, buf, MAIL_LEN);
187 if (res < MAIL_LEN) {
189 bye(EX_TEMPFAIL, "Cannot write to remporary file: %m");
196 /* save rest of the body to the tmpfile */
199 while ((c = give_me_char(rfd)) != EOF){
204 res = write(fd, buf, MAIL_LEN);
205 if (res < MAIL_LEN) {
207 bye(EX_TEMPFAIL, "Cannot write to temporary file: %m");
211 res = write(fd, buf, j);
214 bye(EX_TEMPFAIL, "Cannot write to temporary file: %m");
221 print_headers(struct list* l)
226 printf("%s:%s\n",p->name,p->value);
230 flush_mbox_buffer(int fd)
232 if (mbox_write_err || !mbox_write_pos)
236 res = write(fd, mbox_write_buf, mbox_write_pos);
243 write_char_to_mailbox(char c, int fd)
247 if (mbox_write_pos >= BUFSIZE){
248 res = write(fd, mbox_write_buf, BUFSIZE);
254 mbox_write_buf[mbox_write_pos++] = c;
270 read_email(struct email* em)
275 if (! email_opened) {
280 if (! headers_sent) {
282 int curbufsize = BUFSIZE;
283 buf = xmalloc(BUFSIZE);
286 LIST_FOREACH(ph, em->headers){
287 int needed = strlen(ph->name) + strlen(ph->value) + 4;
288 while (curbufsize < pos + needed)
289 buf = xrealloc(buf, curbufsize*=2);
290 strcpy(buf + pos, ph->name);
291 pos += strlen(ph->name);
294 strcpy(buf + pos, ph->value);
295 pos += strlen(ph->value);
306 buf = xstrdup(em->body);
307 chars_written = em->body_len;
308 //printf("%d: %s\n", em->body_len, em->body);
314 lseek(em->fd, 0, SEEK_SET);
316 buf = xmalloc(MAIL_LEN + 1);
317 r = read(em->fd, buf, MAIL_LEN);
326 write_email_to_fd(int fd, struct email* email)
333 buf = read_email(email);
334 wr = write(fd, buf, chars_written);
335 if (wr < chars_written)
337 } while (chars_written);
342 /* try to copy e-mail to mailbox, if it fails,
343 truncate mailbox to the original size */
345 copy_email(int fd, struct email* email)
349 mb_end = lseek(fd, 0, SEEK_END);
362 char* date = ctime(&t);
363 int datelen = strlen(date);
366 len = 5 + datelen + 1;
367 fromline = xmalloc(len);
368 sprintf(fromline, "From %s", date);
369 len = strlen(fromline);
371 len = strlen(fromline);
372 for (i = 0; i < len; i++)
373 write_char_to_mailbox(fromline[i], fd);
377 LIST_FOREACH(ph, email->headers){
378 for (pc = ph->name; *pc; pc++)
379 write_char_to_mailbox(*pc, fd);
380 write_char_to_mailbox(':', fd);
381 write_char_to_mailbox(' ', fd);
382 for (pc = ph->value; *pc; pc++)
383 write_char_to_mailbox(*pc, fd);
384 write_char_to_mailbox('\n', fd);
387 write_char_to_mailbox('\n', fd);
389 for (pc = email->body; pc < email->body + email->body_len; pc++){
390 write_char_to_mailbox(*pc, fd);
392 if ((pc + 5 < email->body + email->body_len)
393 && pc[1] == 'F' && pc[2] == 'r'
394 && pc[3] == 'o' && pc[4] == 'm'
396 write_char_to_mailbox('>', fd);
402 for(i = 0; i < email->body_len; i+=MAIL_LEN) {
404 if (i >= email->body_len)
405 len = len - (i - email->body_len);
406 read(email->fd, buf, len); //FIXME: check it?
407 for (pc = buf; pc < buf + len; pc++) {
408 write_char_to_mailbox(*pc, fd);
410 if ((pc + 5 < email->body + email->body_len)
411 && pc[1] == 'F' && pc[2] == 'r'
412 && pc[3] == 'o' && pc[4] == 'm'
414 write_char_to_mailbox('>', fd);
420 flush_mbox_buffer(fd);
424 /* try to truncate to the original length */
425 ftruncate(fd, mb_end);
433 deliver_local_email(char* folder, struct email* email)
436 int is_default_mailbox = 0;
439 if (!strcmp(default_mailbox, folder))
440 is_default_mailbox = 1;
442 fd = open_mailbox(folder, is_default_mailbox);
444 if (is_default_mailbox)
446 else /* try to save to default mailbox instead */
447 return deliver_local_email(default_mailbox, email);
450 res = copy_email(fd, email);
453 /* try to deliver to the default mailbox */
454 if (is_default_mailbox)
457 return deliver_local_email(default_mailbox, email);
460 close_mailbox(fd, folder, is_default_mailbox);