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.
Showing
10 changed files
with
208 additions
and
148 deletions
... | @@ -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); | ... | ... |
-
Please register or sign in to post a comment