12 char mbox_write_buf[BUFSIZE];
17 new_header(char* buf, struct list* h)
22 new = xmalloc(sizeof(struct hlist));
26 new->value = xstrdup("");
29 new->value = xstrdup(p+1);
30 p = strrchr(new->value, '\n');
34 new->name = xstrdup(buf);
36 list_add_last(h, &new->car);
42 struct list* l = xmalloc(sizeof(struct list));
44 int i = 0; /* current position */
48 buf = xmalloc(BUFSIZE);
51 while ((c = getchar()) != EOF){
55 if (i >= curbufsize-2)
56 buf = xrealloc(buf, curbufsize *= 2);
62 if ((c = getchar()) != ' ' && c != '\t'){
82 int c, fd, cannot_save = 0;
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) {
101 buf = xrealloc(buf, curbufsize *= 2);
104 tmpfile = xstrdup("/tmp/umpf.XXXXXX");
105 fd = mkstemp(tmpfile);
106 /* cannot create tmpfile, try to continue reading */
108 buf = xrealloc(buf, curbufsize *= 2);
110 free_string(tmpfile);
115 b->tmpfile = tmpfile;
122 /* save rest of the body to the tmpfile */
124 while ((c = getchar()) != EOF){
129 res = write(fd, buf, MAIL_LEN);
130 if (res < MAIL_LEN) {
131 int missing = MAIL_LEN - res;
132 curbufsize = 2*b->body_len;
133 buf = xrealloc(buf, curbufsize);
134 // no point to check length here
135 read(fd, buf, b->body_len - missing);
144 /* could not write all the body to the tmpfile, try to read
147 while ((c = getchar()) != EOF){
150 if (i >= curbufsize - 1) {
151 buf = xrealloc(buf, curbufsize *= 2);
161 print_headers(struct list* l)
166 printf("%s:%s\n",p->name,p->value);
170 flush_mbox_buffer(int fd)
172 if (mbox_write_err || !mbox_write_pos)
176 res = write(fd, mbox_write_buf, mbox_write_pos);
183 write_char_to_mailbox(char c, int fd)
187 if (mbox_write_pos >= BUFSIZE){
188 res = write(fd, mbox_write_buf, BUFSIZE);
194 mbox_write_buf[mbox_write_pos++] = c;
197 /* try to copy e-mail to mailbox, if it fails,
198 truncate mailbox to the original size */
200 copy_email(int fd, struct email* email)
204 mb_end = lseek(fd, 0, SEEK_END);
215 LIST_FOREACH(ph, email->headers){
216 for (pc = ph->name; *pc; pc++)
217 write_char_to_mailbox(*pc, fd);
218 write_char_to_mailbox(':', fd);
219 write_char_to_mailbox(' ', fd);
220 for (pc = ph->value; *pc; pc++)
221 write_char_to_mailbox(*pc, fd);
222 write_char_to_mailbox('\n', fd);
225 write_char_to_mailbox('\n', fd);
227 /* FIXME: do not forget change Content-Length */
229 for (pc = email->body; pc < email->body + email->body_len; pc++){
230 write_char_to_mailbox(*pc, fd);
232 if ((pc + 5 < email->body + email->body_len)
233 && pc[1] == 'F' && pc[2] == 'r'
234 && pc[3] == 'o' && pc[4] == 'm'
236 write_char_to_mailbox('>', fd);
242 for(i = 0; i < email->body_len; i+=MAIL_LEN) {
244 if (i >= email->body_len)
245 len = len - (i - email->body_len);
246 read(email->fd, buf, len); //FIXME: check it?
247 for (pc = buf; pc < buf + len; pc++) {
248 write_char_to_mailbox(*pc, fd);
250 if ((pc + 5 < email->body + email->body_len)
251 && pc[1] == 'F' && pc[2] == 'r'
252 && pc[3] == 'o' && pc[4] == 'm'
254 write_char_to_mailbox('>', fd);
260 flush_mbox_buffer(fd);
264 /* try to truncate to the original length */
265 ftruncate(fd, mb_end);
273 write_email_to_fd(int fd, struct email* email)
279 LIST_FOREACH(ph, email->headers){
280 written = write(fd, ph->name, strlen(ph->name));
281 if (written < strlen(ph->name))
283 written = write(fd, ": ", 2);
286 written = write(fd, ph->value, strlen(ph->value));
287 if (written < strlen(ph->value))
289 written = write(fd, "\n", 2);
293 written = write(fd, "\n", 2);
300 written = write(fd, email->body, email->body_len);
301 if (written < email->body_len)
306 for(i = 0; i < email->body_len; i+=MAIL_LEN) {
308 if (i >= email->body_len)
309 len = len - (i - email->body_len);
310 read(email->fd, buf, len); //FIXME: check it?
319 deliver_local_email(char* folder, struct email* email)
322 int is_default_mailbox = 0;
325 if (!strcmp(default_mailbox, folder))
326 is_default_mailbox = 1;
328 fd = open_mailbox(folder, is_default_mailbox);
330 if (is_default_mailbox)
332 else /* try to save to default mailbox instead */
333 return deliver_local_email(default_mailbox, email);
336 res = copy_email(fd, email);
339 /* try to deliver to the default mailbox */
340 if (is_default_mailbox)
343 return deliver_local_email(default_mailbox, email);
346 close_mailbox(fd, folder, is_default_mailbox);