Commit b44590e7 b44590e747b7578e45e775a12e869322c161846f by Alain Magloire

attribute.c body.c header.c io.c mbx_pop.c mbx_unix.c

 	mbx_unixscan.c message.c include/private/message0.h
 	include/public/io.h
cleanup, finish the POP client code hopefully.
1 parent ba5f7a3e
...@@ -40,8 +40,7 @@ attribute_destroy (attribute_t *pattr) ...@@ -40,8 +40,7 @@ attribute_destroy (attribute_t *pattr)
40 { 40 {
41 if (pattr && *pattr) 41 if (pattr && *pattr)
42 { 42 {
43 attribute_t attr = *pattr; 43 free (*pattr);
44 free (attr);
45 /* loose the link */ 44 /* loose the link */
46 *pattr = NULL; 45 *pattr = NULL;
47 } 46 }
......
...@@ -58,11 +58,8 @@ body_destroy (body_t *pbody, void *owner) ...@@ -58,11 +58,8 @@ body_destroy (body_t *pbody, void *owner)
58 if (body->owner == owner) 58 if (body->owner == owner)
59 { 59 {
60 if (body->file) 60 if (body->file)
61 {
62 fclose (body->file); 61 fclose (body->file);
63 body->file = NULL; 62 free (body->filename);
64 }
65 free (body->filename); body->filename = NULL;
66 stream_destroy (&(body->stream), body); 63 stream_destroy (&(body->stream), body);
67 } 64 }
68 *pbody = NULL; 65 *pbody = NULL;
......
...@@ -53,14 +53,12 @@ struct _header ...@@ -53,14 +53,12 @@ struct _header
53 53
54 /* owner ? */ 54 /* owner ? */
55 void *owner; 55 void *owner;
56 int ref_count;
57 }; 56 };
58 57
59 int 58 int
60 header_create (header_t *ph, const char *blurb, size_t len, void *owner) 59 header_create (header_t *ph, const char *blurb, size_t len, void *owner)
61 { 60 {
62 header_t h; 61 header_t h;
63 int status;
64 h = calloc (1, sizeof (*h)); 62 h = calloc (1, sizeof (*h));
65 if (h == NULL) 63 if (h == NULL)
66 return ENOMEM; 64 return ENOMEM;
...@@ -68,15 +66,8 @@ header_create (header_t *ph, const char *blurb, size_t len, void *owner) ...@@ -68,15 +66,8 @@ header_create (header_t *ph, const char *blurb, size_t len, void *owner)
68 66
69 header_parse (h, (char *)blurb, len); 67 header_parse (h, (char *)blurb, len);
70 68
71 status = stream_create (&(h->stream), MU_STREAM_READ|MU_STREAM_WRITE, h);
72 if (status != 0)
73 return status;
74
75 stream_set_read (h->stream, header_read, h);
76 stream_set_write (h->stream, header_write, h);
77
78 *ph = h; 69 *ph = h;
79 return status; 70 return 0;
80 } 71 }
81 72
82 void 73 void
...@@ -86,16 +77,11 @@ header_destroy (header_t *ph, void *owner) ...@@ -86,16 +77,11 @@ header_destroy (header_t *ph, void *owner)
86 { 77 {
87 header_t h = *ph; 78 header_t h = *ph;
88 79
89 /* if destroy is call always decremente */
90 h->ref_count--;
91
92 /* can we destroy ? */ 80 /* can we destroy ? */
93 if ((h->owner && h->owner == owner) || 81 if (h->owner == owner)
94 (h->owner == NULL && h->ref_count <= 0))
95 { 82 {
96 /* io */ 83 /* io */
97 stream_destroy (&(h->stream), h); 84 stream_destroy (&(h->stream), h);
98
99 free (h->hdr); 85 free (h->hdr);
100 free (h->blurb); 86 free (h->blurb);
101 free (h); 87 free (h);
...@@ -427,6 +413,14 @@ header_get_stream (header_t header, stream_t *pstream) ...@@ -427,6 +413,14 @@ header_get_stream (header_t header, stream_t *pstream)
427 { 413 {
428 if (header == NULL || pstream == NULL) 414 if (header == NULL || pstream == NULL)
429 return EINVAL; 415 return EINVAL;
416 if (header->stream == NULL)
417 {
418 int status = stream_create (&(header->stream), MU_STREAM_RDWR, header);
419 if (status != 0)
420 return status;
421 stream_set_read (header->stream, header_read, header);
422 stream_set_write (header->stream, header_write, header);
423 }
430 *pstream = header->stream; 424 *pstream = header->stream;
431 return 0; 425 return 0;
432 } 426 }
......
...@@ -46,11 +46,9 @@ struct _message ...@@ -46,11 +46,9 @@ struct _message
46 stream_t stream; 46 stream_t stream;
47 body_t body; 47 body_t body;
48 attribute_t attribute; 48 attribute_t attribute;
49 size_t num;
50 49
51 /* who is the owner */ 50 /* who is the owner */
52 void *owner; 51 void *owner;
53 int ref_count;
54 52
55 event_t event; 53 event_t event;
56 size_t event_num; 54 size_t event_num;
......
...@@ -71,14 +71,16 @@ extern int stream_set_read __P ((stream_t, ...@@ -71,14 +71,16 @@ extern int stream_set_read __P ((stream_t,
71 size_t, off_t, size_t *)), 71 size_t, off_t, size_t *)),
72 void *owner)); 72 void *owner));
73 73
74 extern int stream_write __P ((stream_t, const char *, size_t, off_t, size_t *)); 74 extern int stream_write __P ((stream_t, const char *, size_t,
75 off_t, size_t *));
75 extern int stream_set_write __P ((stream_t, 76 extern int stream_set_write __P ((stream_t,
76 int (*_write) __P ((stream_t, const char *, 77 int (*_write) __P ((stream_t, const char *,
77 size_t, off_t, 78 size_t, off_t,
78 size_t *)), 79 size_t *)),
79 void *owner)); 80 void *owner));
80 81
81 extern int stream_get_flags __P ((stream_t , int *flags)); 82 extern int stream_get_flags __P ((stream_t, int *pflags));
83 extern int stream_set_flags __P ((stream_t, int flags, void *owner));
82 84
83 /* misc */ 85 /* misc */
84 extern int file_stream_create __P ((stream_t *stream, const char *filename, 86 extern int file_stream_create __P ((stream_t *stream, const char *filename,
......
...@@ -42,11 +42,12 @@ stream_destroy (stream_t *pstream, void *owner) ...@@ -42,11 +42,12 @@ stream_destroy (stream_t *pstream, void *owner)
42 if (pstream && *pstream) 42 if (pstream && *pstream)
43 { 43 {
44 stream_t stream = *pstream; 44 stream_t stream = *pstream;
45 if (!(stream->flags & MU_STREAM_NO_CHECK) && stream->owner != owner) 45 if ((stream->flags & MU_STREAM_NO_CHECK) || stream->owner == owner)
46 return; 46 {
47 if (stream->_destroy) 47 if (stream->_destroy)
48 stream->_destroy (stream); 48 stream->_destroy (stream);
49 free (stream); 49 free (stream);
50 }
50 *pstream = NULL; 51 *pstream = NULL;
51 } 52 }
52 } 53 }
...@@ -193,3 +194,14 @@ stream_get_flags (stream_t stream, int *pfl) ...@@ -193,3 +194,14 @@ stream_get_flags (stream_t stream, int *pfl)
193 *pfl = stream->flags; 194 *pfl = stream->flags;
194 return 0; 195 return 0;
195 } 196 }
197
198 int
199 stream_set_flags (stream_t stream, int fl, void *owner)
200 {
201 if (stream == NULL)
202 return EINVAL;
203 if (stream->owner != owner)
204 return EACCES;
205 stream->flags = fl;
206 return 0;
207 }
......
...@@ -111,7 +111,7 @@ typedef struct _mailbox_pop_message * mailbox_pop_message_t; ...@@ -111,7 +111,7 @@ typedef struct _mailbox_pop_message * mailbox_pop_message_t;
111 struct _mailbox_pop_message 111 struct _mailbox_pop_message
112 { 112 {
113 bio_t bio; 113 bio_t bio;
114 int started, inbody; 114 int inbody;
115 size_t num; 115 size_t num;
116 off_t body_size; 116 off_t body_size;
117 message_t message; 117 message_t message;
...@@ -230,10 +230,33 @@ mailbox_pop_create (mailbox_t *pmbox, const char *name) ...@@ -230,10 +230,33 @@ mailbox_pop_create (mailbox_t *pmbox, const char *name)
230 } 230 }
231 231
232 static void 232 static void
233 mailbox_pop_destroy (mailbox_t *mbox) 233 mailbox_pop_destroy (mailbox_t *pmbox)
234 { 234 {
235 (void)mbox; 235 if (pmbox && *pmbox)
236 return; 236 {
237 if ((*pmbox)->data)
238 {
239 mailbox_pop_data_t mpd = (*pmbox)->data;
240 size_t i;
241 for (i = 0; i < mpd->pmessages_count; i++)
242 {
243 if (mpd->pmessages[i])
244 {
245 bio_destroy (&(mpd->pmessages[i]->bio));
246 message_destroy (&(mpd->pmessages[i]->message),
247 mpd->pmessages[i]);
248 }
249 free (mpd->pmessages[i]);
250 }
251 free (mpd->pmessages);
252 free (mpd);
253 }
254 free ((*pmbox)->name);
255 free ((*pmbox)->event);
256 if ((*pmbox)->url)
257 url_destroy (&((*pmbox)->url));
258 *pmbox = NULL;
259 }
237 } 260 }
238 261
239 static struct termios stored_settings; 262 static struct termios stored_settings;
...@@ -471,15 +494,45 @@ static int ...@@ -471,15 +494,45 @@ static int
471 mailbox_pop_close (mailbox_t mbox) 494 mailbox_pop_close (mailbox_t mbox)
472 { 495 {
473 mailbox_pop_data_t mpd; 496 mailbox_pop_data_t mpd;
474 //mailbox_pop_message_t mpm; 497 void *func = mailbox_pop_close;
498 int status;
499 bio_t bio;
475 500
476 if (mbox == NULL || (mpd = mbox->data) == NULL) 501 if (mbox == NULL || (mpd = mbox->data) == NULL)
477 return EINVAL; 502 return EINVAL;
478 503
504 if (mpd->func && mpd->func != func)
505 return EBUSY;
506
507 mpd->func = func;
508 bio = mpd->bio;
509
479 if (mpd->fd != -1) 510 if (mpd->fd != -1)
511 {
512 switch (mpd->state)
513 {
514 case 0:
515 bio->len = sprintf (bio->buffer, "QUIT\r\n");
516 bio->ptr = bio->buffer;
517 mpd->state = 1;
518 case 1:
519 status = bio_write (mpd->bio);
520 if (status != 0)
521 {
522 if (status != EAGAIN && status != EINTR)
523 {
524 mpd->func = mpd->id = NULL;
525 mpd->state = 0;
526 }
527 return status;
528 }
480 close (mpd->fd); 529 close (mpd->fd);
481 mpd->fd = -1; 530 mpd->fd = -1;
531 }
532 }
482 533
534 mpd->func = mpd->id = NULL;
535 mpd->state = 0;
483 return 0; 536 return 0;
484 } 537 }
485 538
...@@ -619,8 +672,8 @@ mailbox_pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg) ...@@ -619,8 +672,8 @@ mailbox_pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg)
619 mpd->mpm = NULL; 672 mpd->mpm = NULL;
620 return ERANGE; 673 return ERANGE;
621 } 674 }
622 mpd->state = 5;
623 } 675 }
676 mpd->state = 5;
624 /* get the header */ 677 /* get the header */
625 case 5: 678 case 5:
626 { 679 {
...@@ -646,16 +699,12 @@ mailbox_pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg) ...@@ -646,16 +699,12 @@ mailbox_pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg)
646 699
647 /* our ticket out */ 700 /* our ticket out */
648 if (bio->buffer[0] == '\0') 701 if (bio->buffer[0] == '\0')
649 {
650 mpd->mpm->bio->buffer[mpd->mpm->bio->maxlen + 1] = '\0';
651 break; 702 break;
652 }
653 703
654 nread = (bio->nl) ? bio->nl - bio->buffer : 704 nread = bio->nl - bio->buffer;
655 bio->ptr - bio->buffer + 1;
656 705
657 tbuf = realloc (mpd->mpm->bio->buffer, 706 tbuf = realloc (mpd->mpm->bio->buffer,
658 mpd->mpm->bio->maxlen + nread + 1); 707 mpd->mpm->bio->maxlen + nread);
659 if (tbuf == NULL) 708 if (tbuf == NULL)
660 { 709 {
661 mpd->func = mpd->id = NULL; 710 mpd->func = mpd->id = NULL;
...@@ -667,7 +716,7 @@ mailbox_pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg) ...@@ -667,7 +716,7 @@ mailbox_pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg)
667 return ENOMEM; 716 return ENOMEM;
668 } 717 }
669 else 718 else
670 mpd->mpm->bio->buffer = (void *)tbuf; 719 mpd->mpm->bio->buffer = tbuf;
671 memcpy (mpd->mpm->bio->buffer + mpd->mpm->bio->maxlen, 720 memcpy (mpd->mpm->bio->buffer + mpd->mpm->bio->maxlen,
672 bio->buffer, nread); 721 bio->buffer, nread);
673 mpd->mpm->bio->maxlen += nread; 722 mpd->mpm->bio->maxlen += nread;
...@@ -748,12 +797,12 @@ mailbox_pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg) ...@@ -748,12 +797,12 @@ mailbox_pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg)
748 } 797 }
749 stream_set_read (stream, mailbox_pop_readstream, mpd->mpm); 798 stream_set_read (stream, mailbox_pop_readstream, mpd->mpm);
750 stream_set_fd (stream, mailbox_pop_getfd, mpd->mpm); 799 stream_set_fd (stream, mailbox_pop_getfd, mpd->mpm);
800 stream_set_flags (stream, mpd->flags, mpd->mpm);
751 body_set_size (body, mailbox_pop_body_size, mpd->mpm); 801 body_set_size (body, mailbox_pop_body_size, mpd->mpm);
752 //body_set_lines (body, mailbox_pop_body_lines, mpd->mpm); 802 //body_set_lines (body, mailbox_pop_body_lines, mpd->mpm);
753 body_set_stream (body, stream, mpd->mpm); 803 body_set_stream (body, stream, mpd->mpm);
754 } 804 }
755 805
756
757 /* add it to the list */ 806 /* add it to the list */
758 { 807 {
759 mailbox_pop_message_t *m ; 808 mailbox_pop_message_t *m ;
...@@ -888,19 +937,74 @@ mailbox_pop_expunge (mailbox_t mbox) ...@@ -888,19 +937,74 @@ mailbox_pop_expunge (mailbox_t mbox)
888 mailbox_pop_data_t mpd; 937 mailbox_pop_data_t mpd;
889 size_t i; 938 size_t i;
890 attribute_t attr; 939 attribute_t attr;
940 bio_t bio;
941 int status;
942 void *func = mailbox_pop_expunge;
891 943
892 if (mbox == NULL || 944 if (mbox == NULL ||
893 (mpd = (mailbox_pop_data_t) mbox->data) == NULL) 945 (mpd = (mailbox_pop_data_t) mbox->data) == NULL)
894 return EINVAL; 946 return EINVAL;
895 for (i = 0; i < mpd->messages_count; i++) 947
948 /* busy ? */
949 if (mpd->func && mpd->func != func)
950 return EBUSY;
951
952 mpd->func = func;
953 bio = mpd->bio;
954
955 for (i = (int)mpd->id; i < mpd->messages_count; mpd->id = (void *)++i)
896 { 956 {
897 if (message_get_attribute (mpd->pmessages[i]->message, &attr) != 0) 957 if (message_get_attribute (mpd->pmessages[i]->message, &attr) == 0)
898 { 958 {
959 /* send DELETE */
899 if (attribute_is_deleted (attr)) 960 if (attribute_is_deleted (attr))
900 { 961 {
962 switch (mpd->state)
963 {
964 case 0:
965 bio->len = sprintf (bio->buffer, "DELE %d\r\n",
966 mpd->pmessages[i]->num);
967 bio->ptr = bio->buffer;
968 mpd->state = 1;
969 case 1:
970 status = bio_write (bio);
971 if (status != 0)
972 {
973 if (status != EAGAIN && status != EINTR)
974 {
975 mpd->func = mpd->id = NULL;
976 mpd->state = 0;
977 fprintf(stderr, "PROBLEM write %d\n", status);
901 } 978 }
979 return status;
902 } 980 }
981 mpd->state = 2;
982 case 2:
983 status = bio_readline (bio);
984 if (status != 0)
985 {
986 if (status != EAGAIN && status != EINTR)
987 {
988 mpd->func = mpd->id = NULL;
989 mpd->state = 0;
990 fprintf(stderr, "PROBLEM readline %d\n", status);
991 }
992 return status;
903 } 993 }
994 if (strncasecmp (bio->buffer, "+OK", 3) != 0)
995 {
996 mpd->func = mpd->id = NULL;
997 mpd->state = 0;
998 fprintf(stderr, "PROBLEM strcmp\n");
999 return ERANGE;
1000 }
1001 mpd->state = 0;
1002 } /* switch (state) */
1003 } /* if attribute_is_deleted() */
1004 } /* message_get_attribute() */
1005 } /* for */
1006 mpd->func = mpd->id = NULL;
1007 mpd->state = 0;
904 1008
905 return 0; 1009 return 0;
906 } 1010 }
...@@ -1180,8 +1284,6 @@ bio_readline (bio_t bio) ...@@ -1180,8 +1284,6 @@ bio_readline (bio_t bio)
1180 memmove (bio->buffer, bio->nl + 1, bio->ptr - bio->nl); 1284 memmove (bio->buffer, bio->nl + 1, bio->ptr - bio->nl);
1181 bio->ptr = bio->buffer + (bio->ptr - bio->nl) - 1; 1285 bio->ptr = bio->buffer + (bio->ptr - bio->nl) - 1;
1182 bio->nl = memchr (bio->buffer, '\n', bio->ptr - bio->buffer + 1); 1286 bio->nl = memchr (bio->buffer, '\n', bio->ptr - bio->buffer + 1);
1183 //if (bio->nl == NULL)
1184 //bio->nl = bio->buffer;
1185 } 1287 }
1186 else 1288 else
1187 bio->nl = bio->ptr = bio->buffer; 1289 bio->nl = bio->ptr = bio->buffer;
...@@ -1198,10 +1300,11 @@ bio_readline (bio_t bio) ...@@ -1198,10 +1300,11 @@ bio_readline (bio_t bio)
1198 bio->nl = memchr (bio->buffer, '\n', len); 1300 bio->nl = memchr (bio->buffer, '\n', len);
1199 if (bio->nl == NULL) 1301 if (bio->nl == NULL)
1200 { 1302 {
1201 if (len >= bio->maxlen) 1303 if (len >= (bio->maxlen - 1))
1202 { 1304 {
1203 char *tbuf = realloc (bio->buffer, 1305 char *tbuf;
1204 (2*(bio->maxlen) + 1)*(sizeof(char))); 1306 tbuf = realloc (bio->buffer,
1307 (2*(bio->maxlen) + 2)*(sizeof(char)));
1205 if (tbuf == NULL) 1308 if (tbuf == NULL)
1206 return ENOMEM; 1309 return ENOMEM;
1207 bio->buffer = tbuf; 1310 bio->buffer = tbuf;
......
...@@ -312,9 +312,10 @@ mailbox_unix_destroy (mailbox_t *pmbox) ...@@ -312,9 +312,10 @@ mailbox_unix_destroy (mailbox_t *pmbox)
312 if (mum == NULL) 312 if (mum == NULL)
313 continue; 313 continue;
314 /* Destroy the attach messages */ 314 /* Destroy the attach messages */
315 message_destroy (&(mum->message), mum);
316 attribute_destroy (&(mum->old_attr)); 315 attribute_destroy (&(mum->old_attr));
317 attribute_destroy (&(mum->new_attr)); 316 message_destroy (&(mum->message), mum);
317 /* new_attr free by message_destroy() */
318 /* attribute_destroy (&(mum->new_attr)); */
318 free (mum); 319 free (mum);
319 } 320 }
320 free (mud->umessages); 321 free (mud->umessages);
...@@ -474,6 +475,11 @@ mailbox_unix_open (mailbox_t mbox, int flags) ...@@ -474,6 +475,11 @@ mailbox_unix_open (mailbox_t mbox, int flags)
474 } 475 }
475 funlockfile (mud->file); 476 funlockfile (mud->file);
476 mud->flags = flags; 477 mud->flags = flags;
478
479 /* give an appriate way to lock */
480 if (mbox->locker == NULL)
481 locker_create (&(mbox->locker), mbox->name,
482 strlen (mbox->name), MU_LOCKER_PID | MU_LOCKER_FCNTL);
477 } 483 }
478 mailbox_unix_iunlock (mbox); 484 mailbox_unix_iunlock (mbox);
479 return 0; 485 return 0;
...@@ -547,7 +553,7 @@ mailbox_unix_num_deleted (mailbox_t mbox, size_t *pnum) ...@@ -547,7 +553,7 @@ mailbox_unix_num_deleted (mailbox_t mbox, size_t *pnum)
547 two copies. 553 two copies.
548 */ 554 */
549 static FILE * 555 static FILE *
550 mailbox_unix_tmpfile (mailbox_t mbox, char *tmpmbox) 556 mailbox_unix_tmpfile (mailbox_t mbox, char **pbox)
551 { 557 {
552 mailbox_unix_data_t mud = (mailbox_unix_data_t)mbox->data; 558 mailbox_unix_data_t mud = (mailbox_unix_data_t)mbox->data;
553 int fd; 559 int fd;
...@@ -557,34 +563,34 @@ mailbox_unix_tmpfile (mailbox_t mbox, char *tmpmbox) ...@@ -557,34 +563,34 @@ mailbox_unix_tmpfile (mailbox_t mbox, char *tmpmbox)
557 # define P_tmpdir "/tmp" 563 # define P_tmpdir "/tmp"
558 #endif 564 #endif
559 565
560 tmpmbox = calloc (1, strlen (P_tmpdir) + strlen ("MBOX_") + 566 *pbox = calloc (1, strlen (P_tmpdir) + strlen ("MBOX_") +
561 strlen (mud->basename) + 1); 567 strlen (mud->basename) + 1);
562 if (tmpmbox == NULL) 568 if (*pbox == NULL)
563 return NULL; 569 return NULL;
564 sprintf (tmpmbox, "%s/%s%s", P_tmpdir, "MBOX_", mud->basename); 570 sprintf (*pbox, "%s/%s%s", P_tmpdir, "MBOX_", mud->basename);
565 571
566 /* FIXME: I don't think this is the righ approach 572 /* FIXME: I don't think this is the righ approach
567 * Creating an anonymous file would be better ? 573 * Creating an anonymous file would be better ?
568 * no trace left behind. 574 * no trace left behind.
569 */ 575 */
570 /* Create the file. It must not exist. If it does exist, fail. */ 576 /* Create the file. It must not exist. If it does exist, fail. */
571 fd = open(tmpmbox, O_RDWR|O_CREAT|O_EXCL, 0600); 577 fd = open(*pbox, O_RDWR|O_CREAT|O_EXCL, 0600);
572 if (fd < 0) 578 if (fd < 0)
573 { 579 {
574 fprintf(stderr,"Can't create %s\n", tmpmbox); 580 fprintf(stderr,"Can't create %s\n", *pbox);
575 fprintf(stderr,"delete file <%s>, Please\n", tmpmbox); 581 fprintf(stderr,"delete file <%s>, Please\n", *pbox);
576 return NULL; 582 return NULL;
577 } 583 }
578 fp = fdopen(fd, "w+"); 584 fp = fdopen(fd, "w+");
579 if (fp == 0) 585 if (fp == 0)
580 { 586 {
581 close(fd); 587 close(fd);
582 free (tmpmbox); 588 free (*pbox);
583 tmpmbox = NULL; 589 *pbox = NULL;
584 } 590 }
585 591
586 /* really I should just remove the file here */ 592 /* really I should just remove the file here */
587 /* remove(tmpmbox); */ 593 /* remove(*pbox); */
588 return fp; 594 return fp;
589 } 595 }
590 596
...@@ -612,7 +618,7 @@ mailbox_unix_expunge (mailbox_t mbox) ...@@ -612,7 +618,7 @@ mailbox_unix_expunge (mailbox_t mbox)
612 if (mud->messages_count == 0) 618 if (mud->messages_count == 0)
613 return 0; 619 return 0;
614 620
615 tempfile = mailbox_unix_tmpfile (mbox, tmpmbox); 621 tempfile = mailbox_unix_tmpfile (mbox, &tmpmbox);
616 if (tempfile == NULL) 622 if (tempfile == NULL)
617 return errno; 623 return errno;
618 624
...@@ -644,7 +650,8 @@ mailbox_unix_expunge (mailbox_t mbox) ...@@ -644,7 +650,8 @@ mailbox_unix_expunge (mailbox_t mbox)
644 650
645 /* 651 /*
646 * We can not be NONBLOCKING here. 652 * We can not be NONBLOCKING here.
647 * It would irresponsable. 653 * It would irresponsable. Then again, it suppose
654 * to be a __LOCAL__ file system
648 */ 655 */
649 if ((oflags = fcntl (fileno (mud->file), F_GETFL, 0)) < 0) 656 if ((oflags = fcntl (fileno (mud->file), F_GETFL, 0)) < 0)
650 { 657 {
...@@ -672,7 +679,8 @@ mailbox_unix_expunge (mailbox_t mbox) ...@@ -672,7 +679,8 @@ mailbox_unix_expunge (mailbox_t mbox)
672 for (j = 0; j < mud->messages_count; j++) 679 for (j = 0; j < mud->messages_count; j++)
673 { 680 {
674 mum = mud->umessages[j]; 681 mum = mud->umessages[j];
675 if (! attribute_is_equal (mum->old_attr, mum->new_attr)) 682 if (mum->new_attr &&
683 ! attribute_is_equal (mum->old_attr, mum->new_attr))
676 break; 684 break;
677 } 685 }
678 686
...@@ -681,7 +689,7 @@ mailbox_unix_expunge (mailbox_t mbox) ...@@ -681,7 +689,7 @@ mailbox_unix_expunge (mailbox_t mbox)
681 { 689 {
682 /* nothing change, bail out */ 690 /* nothing change, bail out */
683 status = 0; 691 status = 0;
684 goto bailout; 692 goto bailout_ok;
685 } 693 }
686 694
687 /* set the marker position */ 695 /* set the marker position */
...@@ -732,31 +740,12 @@ mailbox_unix_expunge (mailbox_t mbox) ...@@ -732,31 +740,12 @@ mailbox_unix_expunge (mailbox_t mbox)
732 } 740 }
733 /* put the new attributes */ 741 /* put the new attributes */
734 { 742 {
735 attribute_t attr = mum->new_attr; 743 char abuf[64];
736 fputs ("Status: ", tempfile); 744 size_t na = 0;
737 total += 8; 745 abuf[0] = '\0';
738 if (attribute_is_seen (attr)) 746 attribute_to_string (mum->new_attr, abuf, sizeof(abuf), &na);
739 { 747 fputs (abuf, tempfile);
740 fputc ('R', tempfile); 748 total += na;
741 total++;
742 }
743 if (attribute_is_answered (attr))
744 {
745 fputc ('A', tempfile);
746 total++;
747 }
748 if (attribute_is_flagged (attr))
749 {
750 fputc ('F', tempfile);
751 total++;
752 }
753 if (attribute_is_read (attr))
754 {
755 fputc ('O', tempfile);
756 total++;
757 }
758 fputc ('\n', tempfile);
759 total++;
760 } 749 }
761 /* skip the status field */ 750 /* skip the status field */
762 if (fseek (mud->file, current, SEEK_SET) == -1) 751 if (fseek (mud->file, current, SEEK_SET) == -1)
...@@ -843,7 +832,7 @@ mailbox_unix_expunge (mailbox_t mbox) ...@@ -843,7 +832,7 @@ mailbox_unix_expunge (mailbox_t mbox)
843 } 832 }
844 } 833 }
845 /* Seek and rewrite it */ 834 /* Seek and rewrite it */
846 if (total <= 0 || fseek (mud->file, marker, SEEK_SET) < 0) 835 if (total < 0 || fseek (mud->file, marker, SEEK_SET) < 0)
847 { 836 {
848 status = errno; 837 status = errno;
849 goto bailout; 838 goto bailout;
...@@ -877,10 +866,11 @@ mailbox_unix_expunge (mailbox_t mbox) ...@@ -877,10 +866,11 @@ mailbox_unix_expunge (mailbox_t mbox)
877 866
878 /* FIXME: update the num of all the messages */ 867 /* FIXME: update the num of all the messages */
879 868
869 bailout_ok:
880 /* Don't remove the tmp mbox in case of errors */ 870 /* Don't remove the tmp mbox in case of errors */
881 remove (tmpmbox); 871 remove (tmpmbox);
882 872
883 bailout: 873 bailout:
884 free (tmpmbox); 874 free (tmpmbox);
885 /* Release the locks */ 875 /* Release the locks */
886 if (oflags > 0) 876 if (oflags > 0)
...@@ -1181,11 +1171,14 @@ mailbox_unix_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg) ...@@ -1181,11 +1171,14 @@ mailbox_unix_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg)
1181 } 1171 }
1182 stream_set_read (stream, mailbox_unix_readstream, mum); 1172 stream_set_read (stream, mailbox_unix_readstream, mum);
1183 stream_set_fd (stream, mailbox_unix_getfd, mum); 1173 stream_set_fd (stream, mailbox_unix_getfd, mum);
1174 stream_set_flags (stream, mud->flags, mum);
1184 body_set_stream (body, stream, mum); 1175 body_set_stream (body, stream, mum);
1185 body_set_size (body, mailbox_unix_body_size, mum); 1176 body_set_size (body, mailbox_unix_body_size, mum);
1186 body_set_lines (body, mailbox_unix_body_lines, mum); 1177 body_set_lines (body, mailbox_unix_body_lines, mum);
1187 1178
1188 /* set the attribute */ 1179 /* set the attribute */
1180 attribute_create (&(mum->new_attr));
1181 mum->new_attr->flag = mum->old_attr->flag;
1189 status = message_set_attribute (msg, mum->new_attr, mum); 1182 status = message_set_attribute (msg, mum->new_attr, mum);
1190 if (status != 0) 1183 if (status != 0)
1191 { 1184 {
...@@ -1247,9 +1240,6 @@ mailbox_unix_append_message (mailbox_t mbox, message_t msg) ...@@ -1247,9 +1240,6 @@ mailbox_unix_append_message (mailbox_t mbox, message_t msg)
1247 } 1240 }
1248 1241
1249 /* header */ 1242 /* header */
1250 if (st.st_size != 0)
1251 fputc ('\n', mud->file);
1252
1253 message_get_header (msg, &hdr); 1243 message_get_header (msg, &hdr);
1254 /* generate a "From " separator */ 1244 /* generate a "From " separator */
1255 { 1245 {
...@@ -1289,6 +1279,7 @@ mailbox_unix_append_message (mailbox_t mbox, message_t msg) ...@@ -1289,6 +1279,7 @@ mailbox_unix_append_message (mailbox_t mbox, message_t msg)
1289 fwrite (buffer, sizeof (*buffer), nread, mud->file); 1279 fwrite (buffer, sizeof (*buffer), nread, mud->file);
1290 off += nread; 1280 off += nread;
1291 } while (nread > 0); 1281 } while (nread > 0);
1282 fputc ('\n', mud->file);
1292 } 1283 }
1293 fflush(mud->file); 1284 fflush(mud->file);
1294 funlockfile (mud->file); 1285 funlockfile (mud->file);
......
...@@ -267,16 +267,15 @@ do \ ...@@ -267,16 +267,15 @@ do \
267 } \ 267 } \
268 } while (0) 268 } while (0)
269 269
270 // size_t num = 2 * ((mud)->messages_count) + 10;
270 /* allocate slots for the new messages */ 271 /* allocate slots for the new messages */
271 #define ALLOCATE_MSGS(mbox,mud,file) \ 272 #define ALLOCATE_MSGS(mbox,mud,file) \
272 do \ 273 do \
273 { \ 274 { \
274 if (mud->umessages_count == 0 || \ 275 if ((mud)->messages_count >= (mud)->umessages_count) \
275 ((mud)->umessages_count + 1) <= (mud)->messages_count) \
276 { \ 276 { \
277 mailbox_unix_message_t *m; \ 277 mailbox_unix_message_t *m; \
278 size_t i; \ 278 size_t num = ((mud)->umessages_count) + 1; \
279 size_t num = 2 * ((mud)->messages_count) + 10; \
280 m = realloc ((mud)->umessages, num * sizeof (*m)); \ 279 m = realloc ((mud)->umessages, num * sizeof (*m)); \
281 if (m == NULL) \ 280 if (m == NULL) \
282 { \ 281 { \
...@@ -286,24 +285,16 @@ do \ ...@@ -286,24 +285,16 @@ do \
286 return ENOMEM; \ 285 return ENOMEM; \
287 } \ 286 } \
288 (mud)->umessages = m; \ 287 (mud)->umessages = m; \
289 if ((mud)->umessages_count) \ 288 (mud)->umessages[num - 1] = calloc (1, sizeof (*(mum))); \
290 i = (mud)->umessages_count + 1; \ 289 if ((mud)->umessages[num - 1] == NULL) \
291 else \
292 i = 0; \
293 for (; i < num; i++) \
294 { \
295 (mud)->umessages[i] = calloc (1, sizeof (*(mum))); \
296 if ((mud)->umessages[i] == NULL) \
297 { \ 290 { \
298 fclose (file); \ 291 fclose (file); \
299 mailbox_unix_iunlock (mbox); \ 292 mailbox_unix_iunlock (mbox); \
300 mailbox_unix_unlock (mbox); \ 293 mailbox_unix_unlock (mbox); \
301 return ENOMEM; \ 294 return ENOMEM; \
302 } \ 295 } \
303 ATTRIBUTE_CREATE (((mud)->umessages[i])->old_attr, mbox); \ 296 ATTRIBUTE_CREATE (((mud)->umessages[num - 1])->old_attr, mbox); \
304 ATTRIBUTE_CREATE (((mud)->umessages[i])->new_attr, mbox); \ 297 (mud)->umessages_count = num; \
305 } \
306 (mud)->umessages_count = num - 1; \
307 } \ 298 } \
308 } while (0) 299 } while (0)
309 300
...@@ -433,7 +424,6 @@ mailbox_unix_scan (mailbox_t mbox, size_t msgno, size_t *pcount) ...@@ -433,7 +424,6 @@ mailbox_unix_scan (mailbox_t mbox, size_t msgno, size_t *pcount)
433 ATTRIBUTE_SET(buf, mum, 'o', 'O', MU_ATTRIBUTE_SEEN); 424 ATTRIBUTE_SET(buf, mum, 'o', 'O', MU_ATTRIBUTE_SEEN);
434 ATTRIBUTE_SET(buf, mum, 'a', 'A', MU_ATTRIBUTE_ANSWERED); 425 ATTRIBUTE_SET(buf, mum, 'a', 'A', MU_ATTRIBUTE_ANSWERED);
435 ATTRIBUTE_SET(buf, mum, 'd', 'D', MU_ATTRIBUTE_DELETED); 426 ATTRIBUTE_SET(buf, mum, 'd', 'D', MU_ATTRIBUTE_DELETED);
436 mum->new_attr->flag = mum->old_attr->flag;
437 } 427 }
438 } 428 }
439 429
......
...@@ -39,22 +39,12 @@ int ...@@ -39,22 +39,12 @@ int
39 message_create (message_t *pmsg, void *owner) 39 message_create (message_t *pmsg, void *owner)
40 { 40 {
41 message_t msg; 41 message_t msg;
42 stream_t stream;
43 int status;
44 42
45 if (pmsg == NULL) 43 if (pmsg == NULL)
46 return EINVAL; 44 return EINVAL;
47 msg = calloc (1, sizeof (*msg)); 45 msg = calloc (1, sizeof (*msg));
48 if (msg == NULL) 46 if (msg == NULL)
49 return ENOMEM; 47 return ENOMEM;
50 status = stream_create (&stream, MU_STREAM_RDWR, msg);
51 if (status != 0)
52 {
53 free (msg);
54 return status;
55 }
56 stream_set_read (stream, message_read, msg);
57 stream_set_write (stream, message_write, msg);
58 msg->owner = owner; 48 msg->owner = owner;
59 *pmsg = msg; 49 *pmsg = msg;
60 return 0; 50 return 0;
...@@ -66,47 +56,31 @@ message_destroy (message_t *pmsg, void *owner) ...@@ -66,47 +56,31 @@ message_destroy (message_t *pmsg, void *owner)
66 if (pmsg && *pmsg) 56 if (pmsg && *pmsg)
67 { 57 {
68 message_t msg = *pmsg; 58 message_t msg = *pmsg;
69 int destroy = 0;
70
71 /* always decremente */
72 msg->ref_count--;
73 59
74 if (msg->owner && msg->owner == owner) 60 if (msg->owner == owner)
75 destroy = 1;
76
77 if (msg->owner == NULL && msg->ref_count <= 0)
78 { 61 {
79 destroy = 1;
80 owner = msg;
81 }
82
83 if (destroy)
84 {
85 attribute_t attribute = msg->attribute;
86 stream_t stream = msg->stream;
87 header_t header = msg->header;
88 body_t body = msg->body;
89
90 /* notify the listeners */ 62 /* notify the listeners */
63 if (msg->event_num)
64 {
91 message_notification (msg, MU_EVT_MSG_DESTROY); 65 message_notification (msg, MU_EVT_MSG_DESTROY);
66 free (msg->event);
67 }
92 /* header */ 68 /* header */
93 header_destroy (&header, owner); 69 header_destroy (&(msg->header), owner);
94 /* attribute */ 70 /* attribute */
95 attribute_destroy (&attribute); 71 attribute_destroy (&(msg->attribute));
96 /* stream */ 72 /* stream */
97 stream_destroy (&stream, owner); 73 stream_destroy (&(msg->stream), owner);
98 74
99 /* if sometype of floating/temporary message */ 75 /* if sometype of floating/temporary message */
100 body_destroy (&body, owner); 76 body_destroy (&(msg->body), owner);
101 /* notifications are done */ 77 /* notifications are done */
102 free (msg->event);
103 78
104 /* check again for resurrection before free()ing 79 /* check again for resurrection before free()ing
105 * the memory maybe it was clone, if yes we can not 80 * the memory maybe it was clone, if yes we can not
106 * free the pointer. 81 * free the pointer.
107 * 82 *
108 */ 83 */
109 if (msg->ref_count <= 0)
110 free (msg); 84 free (msg);
111 } 85 }
112 /* loose the link */ 86 /* loose the link */
...@@ -347,7 +321,7 @@ message_get_attribute (message_t msg, attribute_t *pattribute) ...@@ -347,7 +321,7 @@ message_get_attribute (message_t msg, attribute_t *pattribute)
347 { 321 {
348 if (msg == NULL || pattribute == NULL) 322 if (msg == NULL || pattribute == NULL)
349 return EINVAL; 323 return EINVAL;
350 if (msg->attribute == NULL && msg->owner == NULL) 324 if (msg->attribute == NULL)
351 { 325 {
352 attribute_t attribute; 326 attribute_t attribute;
353 int status = attribute_create (&attribute); 327 int status = attribute_create (&attribute);
......