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;
181 /* try to copy e-mail to mailbox, if it fails,
182 truncate mailbox to the original size */
184 copy_email(int fd, struct email* email)
188 mb_end = lseek(fd, 0, SEEK_END);
199 LIST_FOREACH(ph, email->headers){
200 for (pc = ph->name; *pc; pc++)
201 write_char_to_mailbox(*pc, fd);
202 write_char_to_mailbox(':', fd);
203 for (pc = ph->value; *pc; pc++)
204 write_char_to_mailbox(*pc, fd);
205 write_char_to_mailbox('\n', fd);
208 write_char_to_mailbox('\n', fd);
210 /* FIXME: do not forget change Content-Length */
212 for (pc = email->body; pc < email->body + email->body_len; pc++){
213 write_char_to_mailbox(*pc, fd);
215 if ((pc + 5 < email->body + email->body_len)
216 && pc[1] == 'F' && pc[2] == 'r'
217 && pc[3] == 'o' && pc[4] == 'm'
219 write_char_to_mailbox('>', fd);
225 for(i = 0; i < email->body_len; i+=MAIL_LEN) {
227 if (i >= email->body_len)
228 len = len - (i - email->body_len);
229 read(email->fd, buf, len); //FIXME: check it?
230 for (pc = buf; pc < buf + len; pc++) {
231 write_char_to_mailbox(*pc, fd);
233 if ((pc + 5 < email->body + email->body_len)
234 && pc[1] == 'F' && pc[2] == 'r'
235 && pc[3] == 'o' && pc[4] == 'm'
237 write_char_to_mailbox('>', fd);
243 flush_mbox_buffer(fd);
247 /* try to truncate to the original length */
248 ftruncate(fd, mb_end);
256 write_email_to_fd(int fd, struct email* email)
262 LIST_FOREACH(ph, email->headers){
263 written = write(fd, ph->name, strlen(ph->name));
264 if (written < (ssize_t) strlen(ph->name))
266 written = write(fd, ":", 1);
269 written = write(fd, ph->value, strlen(ph->value));
270 if (written < (ssize_t) strlen(ph->value))
272 written = write(fd, "\n", 1);
276 written = write(fd, "\n", 1);
282 written = write(fd, email->body, email->body_len);
283 if (written < email->body_len)
288 for(i = 0; i < email->body_len; i+=MAIL_LEN) {
290 if (i >= email->body_len)
291 len = len - (i - email->body_len);
292 read(email->fd, buf, len); //FIXME: check it?
301 deliver_local_email(char* folder, struct email* email)
304 int is_default_mailbox = 0;
307 if (!strcmp(default_mailbox, folder))
308 is_default_mailbox = 1;
310 fd = open_mailbox(folder, is_default_mailbox);
312 if (is_default_mailbox)
314 else /* try to save to default mailbox instead */
315 return deliver_local_email(default_mailbox, email);
318 res = copy_email(fd, email);
321 /* try to deliver to the default mailbox */
322 if (is_default_mailbox)
325 return deliver_local_email(default_mailbox, email);
328 close_mailbox(fd, folder, is_default_mailbox);