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);
41 char gmc_buf[BUFSIZE];
51 gmc_read = read(fd, gmc_buf, BUFSIZE);
57 if (gmc_unget != EOF) {
69 if (gmc_pos < gmc_read) {
71 return gmc_buf[gmc_pos++];
74 gmc_read = read(fd, gmc_buf, BUFSIZE);
81 return gmc_buf[gmc_pos++];
96 struct list* l = xmalloc(sizeof(struct list));
98 int i = 0; /* current position */
102 buf = xmalloc(BUFSIZE);
103 curbufsize = BUFSIZE;
105 while ((c = give_me_char(fd)) != EOF){
109 if (i >= curbufsize-2)
110 buf = xrealloc(buf, curbufsize *= 2);
116 if ((c = give_me_char(fd)) != ' ' && c != '\t'){
139 int curbufsize = MAIL_LEN;
143 buf = xmalloc(MAIL_LEN);
144 b = xmalloc(sizeof(struct email));
149 /* read mail body, if it is too big, try to make tmp file */
150 while ((c = give_me_char(rfd)) != EOF){
152 if (i >= curbufsize - 1) {
153 tmpfile = xstrdup("/tmp/umpf.XXXXXX");
154 fd = mkstemp(tmpfile);
155 /* cannot create tmpfile, try to continue reading */
157 bye(EX_TEMPFAIL, "%m");
161 b->tmpfile = tmpfile;
163 res = write(fd, buf, MAIL_LEN);
164 if (res < MAIL_LEN) {
166 bye(EX_TEMPFAIL, "%m");
173 /* save rest of the body to the tmpfile */
176 while ((c = give_me_char(rfd)) != EOF){
181 res = write(fd, buf, MAIL_LEN);
182 if (res < MAIL_LEN) {
184 bye(EX_TEMPFAIL, "%m");
188 res = write(fd, buf, j);
191 bye(EX_TEMPFAIL, "%m");
198 print_headers(struct list* l)
203 printf("%s:%s\n",p->name,p->value);
207 flush_mbox_buffer(int fd)
209 if (mbox_write_err || !mbox_write_pos)
213 res = write(fd, mbox_write_buf, mbox_write_pos);
220 write_char_to_mailbox(char c, int fd)
224 if (mbox_write_pos >= BUFSIZE){
225 res = write(fd, mbox_write_buf, BUFSIZE);
231 mbox_write_buf[mbox_write_pos++] = c;
247 read_email(struct email* em)
252 if (! email_opened) {
257 if (! headers_sent) {
259 int curbufsize = BUFSIZE;
260 buf = xmalloc(BUFSIZE);
263 LIST_FOREACH(ph, em->headers){
264 int needed = strlen(ph->name) + strlen(ph->value) + 3;
265 if (curbufsize < pos + needed)
266 buf = xrealloc(buf, curbufsize*=2);
267 strcpy(buf + pos, ph->name);
268 pos += strlen(ph->name);
270 strcpy(buf + pos, ph->value);
271 pos += strlen(ph->value);
282 buf = xstrdup(em->body);
283 chars_written = em->body_len;
284 //printf("%d: %s\n", em->body_len, em->body);
290 lseek(em->fd, 0, SEEK_SET);
292 buf = xmalloc(MAIL_LEN + 1);
293 r = read(em->fd, buf, MAIL_LEN);
302 write_email_to_fd(int fd, struct email* email)
309 buf = read_email(email);
310 wr = write(fd, buf, chars_written);
311 if (wr < chars_written)
313 } while (chars_written);
318 /* try to copy e-mail to mailbox, if it fails,
319 truncate mailbox to the original size */
321 copy_email(int fd, struct email* email)
325 mb_end = lseek(fd, 0, SEEK_END);
336 LIST_FOREACH(ph, email->headers){
337 for (pc = ph->name; *pc; pc++)
338 write_char_to_mailbox(*pc, fd);
339 write_char_to_mailbox(':', fd);
340 for (pc = ph->value; *pc; pc++)
341 write_char_to_mailbox(*pc, fd);
342 write_char_to_mailbox('\n', fd);
345 write_char_to_mailbox('\n', fd);
347 /* FIXME: do not forget change Content-Length */
349 for (pc = email->body; pc < email->body + email->body_len; pc++){
350 write_char_to_mailbox(*pc, fd);
352 if ((pc + 5 < email->body + email->body_len)
353 && pc[1] == 'F' && pc[2] == 'r'
354 && pc[3] == 'o' && pc[4] == 'm'
356 write_char_to_mailbox('>', fd);
362 for(i = 0; i < email->body_len; i+=MAIL_LEN) {
364 if (i >= email->body_len)
365 len = len - (i - email->body_len);
366 read(email->fd, buf, len); //FIXME: check it?
367 for (pc = buf; pc < buf + len; pc++) {
368 write_char_to_mailbox(*pc, fd);
370 if ((pc + 5 < email->body + email->body_len)
371 && pc[1] == 'F' && pc[2] == 'r'
372 && pc[3] == 'o' && pc[4] == 'm'
374 write_char_to_mailbox('>', fd);
380 flush_mbox_buffer(fd);
384 /* try to truncate to the original length */
385 ftruncate(fd, mb_end);
393 deliver_local_email(char* folder, struct email* email)
396 int is_default_mailbox = 0;
399 if (!strcmp(default_mailbox, folder))
400 is_default_mailbox = 1;
402 fd = open_mailbox(folder, is_default_mailbox);
404 if (is_default_mailbox)
406 else /* try to save to default mailbox instead */
407 return deliver_local_email(default_mailbox, email);
410 res = copy_email(fd, email);
413 /* try to deliver to the default mailbox */
414 if (is_default_mailbox)
417 return deliver_local_email(default_mailbox, email);
420 close_mailbox(fd, folder, is_default_mailbox);