Put more headers in the cache, (ugly).
Showing
6 changed files
with
377 additions
and
110 deletions
... | @@ -67,6 +67,14 @@ attribute_is_modified (attribute_t attr) | ... | @@ -67,6 +67,14 @@ attribute_is_modified (attribute_t attr) |
67 | } | 67 | } |
68 | 68 | ||
69 | int | 69 | int |
70 | attribute_clear_modified (attribute_t attr) | ||
71 | { | ||
72 | if (attr) | ||
73 | attr->flags &= ~MU_ATTRIBUTE_MODIFIED; | ||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | int | ||
70 | attribute_get_flags (attribute_t attr, int *pflags) | 78 | attribute_get_flags (attribute_t attr, int *pflags) |
71 | { | 79 | { |
72 | if (attr == NULL) | 80 | if (attr == NULL) | ... | ... |
... | @@ -76,6 +76,22 @@ body_get_owner (body_t body) | ... | @@ -76,6 +76,22 @@ body_get_owner (body_t body) |
76 | return (body) ? body->owner : NULL; | 76 | return (body) ? body->owner : NULL; |
77 | } | 77 | } |
78 | 78 | ||
79 | /* FIXME: not implemented. */ | ||
80 | int | ||
81 | body_is_modified (body_t body) | ||
82 | { | ||
83 | (void)body; | ||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | /* FIXME: not implemented. */ | ||
88 | int | ||
89 | body_clear_modified (body_t body) | ||
90 | { | ||
91 | (void)body; | ||
92 | return 0; | ||
93 | } | ||
94 | |||
79 | int | 95 | int |
80 | body_get_filename (body_t body, char *filename, size_t len, size_t *pn) | 96 | body_get_filename (body_t body, char *filename, size_t len, size_t *pn) |
81 | { | 97 | { | ... | ... |
... | @@ -97,6 +97,14 @@ header_is_modified (header_t header) | ... | @@ -97,6 +97,14 @@ header_is_modified (header_t header) |
97 | return (header) ? (header->flags & HEADER_MODIFIED) : 0; | 97 | return (header) ? (header->flags & HEADER_MODIFIED) : 0; |
98 | } | 98 | } |
99 | 99 | ||
100 | int | ||
101 | header_clear_modified (header_t header) | ||
102 | { | ||
103 | if (header) | ||
104 | header->flags &= ~HEADER_MODIFIED; | ||
105 | return 0; | ||
106 | } | ||
107 | |||
100 | /* Parsing is done in a rather simple fashion, meaning we just consider an | 108 | /* Parsing is done in a rather simple fashion, meaning we just consider an |
101 | entry to be a field-name an a field-value. So they maybe duplicate of | 109 | entry to be a field-name an a field-value. So they maybe duplicate of |
102 | field-name like "Received" they are just put in the array, see _get_value() | 110 | field-name like "Received" they are just put in the array, see _get_value() | ... | ... |
... | @@ -58,28 +58,42 @@ struct _mbox_data; | ... | @@ -58,28 +58,42 @@ struct _mbox_data; |
58 | typedef struct _mbox_data* mbox_data_t; | 58 | typedef struct _mbox_data* mbox_data_t; |
59 | typedef struct _mbox_message* mbox_message_t; | 59 | typedef struct _mbox_message* mbox_message_t; |
60 | 60 | ||
61 | /* These represent the header field-name that we are caching for speed. */ | 61 | /* Below are the headers field-names that we are caching for speed, it is |
62 | #define HDRSIZE 9 | 62 | more or less the list of headers in ENVELOPE command from IMAP. */ |
63 | #define HDRSIZE 15 | ||
64 | |||
63 | const char *fhdr_table[] = | 65 | const char *fhdr_table[] = |
64 | { | 66 | { |
65 | #define HFROM 0 | 67 | #define H_BCC 0 |
66 | "From", | 68 | "Bcc", |
67 | #define HTO 1 | 69 | #define H_CC 1 |
68 | "To", | ||
69 | #define HCC 2 | ||
70 | "Cc", | 70 | "Cc", |
71 | #define HSUBJECT 3 | 71 | #define H_CONTENT_LANGUAGE 2 |
72 | "Subject", | 72 | "Content-Language", |
73 | #define HDATE 4 | 73 | #define H_CONTENT_TRANSFER_ENCODING 3 |
74 | "Date", | 74 | "Content-Transfer-Encoding", |
75 | #define HX_IMAPBASE 5 | 75 | #define H_CONTENT_TYPE 4 |
76 | "X-IMAPbase", | ||
77 | #define HX_UIDL 6 | ||
78 | "X-UIDL", | ||
79 | #define HX_UID 7 | ||
80 | "X-UID", | ||
81 | #define HCONTENT_TYPE 8 | ||
82 | "Content-Type", | 76 | "Content-Type", |
77 | #define H_DATE 5 | ||
78 | "Date", | ||
79 | #define H_FROM 6 | ||
80 | "From", | ||
81 | #define H_IN_REPLY_TO 7 | ||
82 | "In-Reply-To", | ||
83 | #define H_MESSAGE_ID 8 | ||
84 | "Message-ID", | ||
85 | #define H_REFERENCE 9 | ||
86 | "Reply-To", | ||
87 | #define H_REPLY_TO 10 | ||
88 | "Reply-To", | ||
89 | #define H_SENDER 11 | ||
90 | "Sender", | ||
91 | #define H_SUBJECT 12 | ||
92 | "Subject", | ||
93 | #define H_TO 13 | ||
94 | "To", | ||
95 | #define H_X_UIDL 14 | ||
96 | "X-UIDL" | ||
83 | }; | 97 | }; |
84 | 98 | ||
85 | /* Keep the positions of where the headers and bodies start and end. | 99 | /* Keep the positions of where the headers and bodies start and end. |
... | @@ -146,6 +160,7 @@ struct _mbox_data | ... | @@ -146,6 +160,7 @@ struct _mbox_data |
146 | static int mbox_open __P ((mailbox_t, int)); | 160 | static int mbox_open __P ((mailbox_t, int)); |
147 | static int mbox_close __P ((mailbox_t)); | 161 | static int mbox_close __P ((mailbox_t)); |
148 | static int mbox_get_message __P ((mailbox_t, size_t, message_t *)); | 162 | static int mbox_get_message __P ((mailbox_t, size_t, message_t *)); |
163 | //static int mbox_get_message_by_uid __P ((mailbox_t, size_t, message_t *)); | ||
149 | static int mbox_append_message __P ((mailbox_t, message_t)); | 164 | static int mbox_append_message __P ((mailbox_t, message_t)); |
150 | static int mbox_messages_count __P ((mailbox_t, size_t *)); | 165 | static int mbox_messages_count __P ((mailbox_t, size_t *)); |
151 | static int mbox_messages_recent __P ((mailbox_t, size_t *)); | 166 | static int mbox_messages_recent __P ((mailbox_t, size_t *)); |
... | @@ -637,8 +652,23 @@ mbox_expunge (mailbox_t mailbox) | ... | @@ -637,8 +652,23 @@ mbox_expunge (mailbox_t mailbox) |
637 | continue; | 652 | continue; |
638 | } | 653 | } |
639 | 654 | ||
640 | if (mum->message) | 655 | /* Do the expensive mbox_append_message0() only if mark dirty. */ |
656 | if ((mum->attr_flags & MU_ATTRIBUTE_MODIFIED) || | ||
657 | (mum->message && message_is_modified (mum->message))) | ||
658 | { | ||
659 | /* The message was not instanciated, probably the dirty flag was | ||
660 | set by mbox_scan(), create one here. */ | ||
661 | if (mum->message == 0) | ||
641 | { | 662 | { |
663 | message_t msg; | ||
664 | status = mbox_get_message (mailbox, i, &msg); | ||
665 | if (status != 0) | ||
666 | { | ||
667 | fprintf (stderr, "Error expunge:%d: %s", __LINE__, | ||
668 | strerror (status)); | ||
669 | goto bailout0; | ||
670 | } | ||
671 | } | ||
642 | status = mbox_append_message0 (tmpmailbox, mum->message, | 672 | status = mbox_append_message0 (tmpmailbox, mum->message, |
643 | &total, 1, (i == save_imapbase)); | 673 | &total, 1, (i == save_imapbase)); |
644 | if (status != 0) | 674 | if (status != 0) |
... | @@ -647,6 +677,9 @@ mbox_expunge (mailbox_t mailbox) | ... | @@ -647,6 +677,9 @@ mbox_expunge (mailbox_t mailbox) |
647 | strerror (status)); | 677 | strerror (status)); |
648 | goto bailout0; | 678 | goto bailout0; |
649 | } | 679 | } |
680 | /* Clear the dirty bit. */ | ||
681 | mum->attr_flags &= ~MU_ATTRIBUTE_MODIFIED; | ||
682 | message_clear_modified (mum->message); | ||
650 | } | 683 | } |
651 | else | 684 | else |
652 | { | 685 | { |
... | @@ -811,12 +844,24 @@ mbox_expunge (mailbox_t mailbox) | ... | @@ -811,12 +844,24 @@ mbox_expunge (mailbox_t mailbox) |
811 | } | 844 | } |
812 | else | 845 | else |
813 | { | 846 | { |
847 | for (i = 0; i < HDRSIZE; i++) | ||
848 | if (mum->fhdr[i]) | ||
849 | { | ||
850 | free (mum->fhdr[i]); | ||
851 | mum->fhdr[i] = NULL; | ||
852 | } | ||
814 | memset (mum, 0, sizeof (*mum)); | 853 | memset (mum, 0, sizeof (*mum)); |
815 | } | 854 | } |
816 | } | 855 | } |
817 | mum->header_from = mum->header_from_end = 0; | 856 | mum->header_from = mum->header_from_end = 0; |
818 | mum->body = mum->body_end = 0; | 857 | mum->body = mum->body_end = 0; |
819 | mum->header_lines = mum->body_lines = 0; | 858 | mum->header_lines = mum->body_lines = 0; |
859 | for (i = 0; i < HDRSIZE; i++) | ||
860 | if (mum->fhdr[i]) | ||
861 | { | ||
862 | free (mum->fhdr[i]); | ||
863 | mum->fhdr[i] = NULL; | ||
864 | } | ||
820 | } | 865 | } |
821 | monitor_unlock (mailbox->monitor); | 866 | monitor_unlock (mailbox->monitor); |
822 | /* This is should reset the messages_count, the last argument 0 means | 867 | /* This is should reset the messages_count, the last argument 0 means |
... | @@ -1387,7 +1432,7 @@ mbox_append_message0 (mailbox_t mailbox, message_t msg, off_t *psize, | ... | @@ -1387,7 +1432,7 @@ mbox_append_message0 (mailbox_t mailbox, message_t msg, off_t *psize, |
1387 | { | 1432 | { |
1388 | char *s; | 1433 | char *s; |
1389 | size_t len = 0; | 1434 | size_t len = 0; |
1390 | envelope_t envelope; | 1435 | envelope_t envelope = NULL; |
1391 | message_get_envelope (msg, &envelope); | 1436 | message_get_envelope (msg, &envelope); |
1392 | status = envelope_sender (envelope, mud->sender, 128, &len); | 1437 | status = envelope_sender (envelope, mud->sender, 128, &len); |
1393 | if (status != 0) | 1438 | if (status != 0) |
... | @@ -1414,7 +1459,7 @@ mbox_append_message0 (mailbox_t mailbox, message_t msg, off_t *psize, | ... | @@ -1414,7 +1459,7 @@ mbox_append_message0 (mailbox_t mailbox, message_t msg, off_t *psize, |
1414 | { | 1459 | { |
1415 | char *s; | 1460 | char *s; |
1416 | size_t len = 0; | 1461 | size_t len = 0; |
1417 | envelope_t envelope; | 1462 | envelope_t envelope = NULL; |
1418 | char buffer[1024]; | 1463 | char buffer[1024]; |
1419 | message_get_envelope (msg, &envelope); | 1464 | message_get_envelope (msg, &envelope); |
1420 | status = envelope_date (envelope, mud->date, 128, &len); | 1465 | status = envelope_date (envelope, mud->date, 128, &len); |
... | @@ -1464,8 +1509,8 @@ mbox_append_message0 (mailbox_t mailbox, message_t msg, off_t *psize, | ... | @@ -1464,8 +1509,8 @@ mbox_append_message0 (mailbox_t mailbox, message_t msg, off_t *psize, |
1464 | { | 1509 | { |
1465 | char buffer[1024]; | 1510 | char buffer[1024]; |
1466 | size_t nread = 0; | 1511 | size_t nread = 0; |
1467 | stream_t is; | 1512 | stream_t is = NULL; |
1468 | header_t header; | 1513 | header_t header = NULL; |
1469 | message_get_header (msg, &header); | 1514 | message_get_header (msg, &header); |
1470 | header_get_stream (header, &is); | 1515 | header_get_stream (header, &is); |
1471 | do | 1516 | do |
... | @@ -1572,8 +1617,8 @@ mbox_append_message0 (mailbox_t mailbox, message_t msg, off_t *psize, | ... | @@ -1572,8 +1617,8 @@ mbox_append_message0 (mailbox_t mailbox, message_t msg, off_t *psize, |
1572 | { | 1617 | { |
1573 | char buffer[1024]; | 1618 | char buffer[1024]; |
1574 | size_t nread = 0; | 1619 | size_t nread = 0; |
1575 | stream_t is; | 1620 | stream_t is = NULL; |
1576 | body_t body; | 1621 | body_t body = NULL; |
1577 | message_get_body (msg, &body); | 1622 | message_get_body (msg, &body); |
1578 | body_get_stream (body, &is); | 1623 | body_get_stream (body, &is); |
1579 | do | 1624 | do |
... | @@ -1616,7 +1661,7 @@ mbox_append_message0 (mailbox_t mailbox, message_t msg, off_t *psize, | ... | @@ -1616,7 +1661,7 @@ mbox_append_message0 (mailbox_t mailbox, message_t msg, off_t *psize, |
1616 | /* Append the Message. */ | 1661 | /* Append the Message. */ |
1617 | char buffer[1024]; | 1662 | char buffer[1024]; |
1618 | size_t nread = 0; | 1663 | size_t nread = 0; |
1619 | stream_t is; | 1664 | stream_t is = NULL; |
1620 | message_get_stream (msg, &is); | 1665 | message_get_stream (msg, &is); |
1621 | do | 1666 | do |
1622 | { | 1667 | { | ... | ... |
... | @@ -162,6 +162,64 @@ do \ | ... | @@ -162,6 +162,64 @@ do \ |
162 | } \ | 162 | } \ |
163 | } while (0) | 163 | } while (0) |
164 | 164 | ||
165 | #define ISBCC(buf) (\ | ||
166 | (buf[0] == 'B' || buf[0] == 'b') \ | ||
167 | && (buf[1] == 'C' || buf[1] == 'c') \ | ||
168 | && (buf[2] == 'C' || buf[2] == 'c') \ | ||
169 | && (buf[3] == ':' || buf[3] == ' ' || buf[3] == '\t')) | ||
170 | |||
171 | #define ISCC(buf) (\ | ||
172 | (buf[0] == 'C' || buf[0] == 'c') \ | ||
173 | && (buf[1] == 'C' || buf[1] == 'c') \ | ||
174 | && (buf[2] == ':' || buf[2] == ' ' || buf[2] == '\t')) | ||
175 | |||
176 | #define ISCONTENT_LANGUAGE(buf) (\ | ||
177 | (buf[0] == 'C' || buf[0] == 'c') \ | ||
178 | && (buf[1] == 'O' || buf[1] == 'o') \ | ||
179 | && (buf[2] == 'N' || buf[2] == 'n') \ | ||
180 | && (buf[3] == 'T' || buf[3] == 't') \ | ||
181 | && (buf[4] == 'E' || buf[4] == 'e') \ | ||
182 | && (buf[5] == 'N' || buf[5] == 'n') \ | ||
183 | && (buf[6] == 'T' || buf[6] == 't') \ | ||
184 | && (buf[7] == '-') \ | ||
185 | && (buf[8] == 'L' || buf[8] == 'l') \ | ||
186 | && (buf[9] == 'A' || buf[9] == 'a') \ | ||
187 | && (buf[10] == 'N' || buf[10] == 'n') \ | ||
188 | && (buf[11] == 'G' || buf[11] == 'g') \ | ||
189 | && (buf[12] == 'U' || buf[12] == 'u') \ | ||
190 | && (buf[13] == 'A' || buf[13] == 'a') \ | ||
191 | && (buf[14] == 'G' || buf[14] == 'g') \ | ||
192 | && (buf[15] == 'E' || buf[15] == 'e') \ | ||
193 | && (buf[16] == ':' || buf[16] == ' ' || buf[16] == '\t')) | ||
194 | |||
195 | #define ISCONTENT_TRANSFER_ENCODING(buf) (\ | ||
196 | (buf[0] == 'C' || buf[0] == 'c') \ | ||
197 | && (buf[1] == 'O' || buf[1] == 'o') \ | ||
198 | && (buf[2] == 'N' || buf[2] == 'n') \ | ||
199 | && (buf[3] == 'T' || buf[3] == 't') \ | ||
200 | && (buf[4] == 'E' || buf[4] == 'e') \ | ||
201 | && (buf[5] == 'N' || buf[5] == 'n') \ | ||
202 | && (buf[6] == 'T' || buf[6] == 't') \ | ||
203 | && (buf[7] == '-') \ | ||
204 | && (buf[8] == 'T' || buf[8] == 't') \ | ||
205 | && (buf[9] == 'R' || buf[9] == 'r') \ | ||
206 | && (buf[10] == 'A' || buf[10] == 'a') \ | ||
207 | && (buf[11] == 'N' || buf[11] == 'n') \ | ||
208 | && (buf[12] == 'S' || buf[12] == 's') \ | ||
209 | && (buf[13] == 'F' || buf[13] == 'f') \ | ||
210 | && (buf[14] == 'E' || buf[14] == 'e') \ | ||
211 | && (buf[15] == 'R' || buf[15] == 'r') \ | ||
212 | && (buf[16] == '-') \ | ||
213 | && (buf[17] == 'E' || buf[17] == 'e') \ | ||
214 | && (buf[18] == 'N' || buf[18] == 'n') \ | ||
215 | && (buf[19] == 'C' || buf[19] == 'c') \ | ||
216 | && (buf[20] == 'O' || buf[20] == 'o') \ | ||
217 | && (buf[21] == 'D' || buf[21] == 'd') \ | ||
218 | && (buf[22] == 'I' || buf[22] == 'i') \ | ||
219 | && (buf[23] == 'N' || buf[23] == 'n') \ | ||
220 | && (buf[24] == 'G' || buf[24] == 'g') \ | ||
221 | && (buf[25] == ':' || buf[25] == ' ' || buf[25] == '\t')) | ||
222 | |||
165 | #define ISCONTENT_TYPE(buf) (\ | 223 | #define ISCONTENT_TYPE(buf) (\ |
166 | (buf[0] == 'C' || buf[0] == 'c') \ | 224 | (buf[0] == 'C' || buf[0] == 'c') \ |
167 | && (buf[1] == 'O' || buf[1] == 'o') \ | 225 | && (buf[1] == 'O' || buf[1] == 'o') \ |
... | @@ -177,11 +235,6 @@ do \ | ... | @@ -177,11 +235,6 @@ do \ |
177 | && (buf[11] == 'E' || buf[11] == 'e') \ | 235 | && (buf[11] == 'E' || buf[11] == 'e') \ |
178 | && (buf[12] == ':' || buf[12] == ' ' || buf[12] == '\t')) | 236 | && (buf[12] == ':' || buf[12] == ' ' || buf[12] == '\t')) |
179 | 237 | ||
180 | #define ISCC(buf) (\ | ||
181 | (buf[0] == 'C' || buf[0] == 'c') \ | ||
182 | && (buf[1] == 'C' || buf[1] == 'c') \ | ||
183 | && (buf[2] == ':' || buf[2] == ' ' || buf[2] == '\t')) | ||
184 | |||
185 | #define ISDATE(buf) (\ | 238 | #define ISDATE(buf) (\ |
186 | (buf[0] == 'D' || buf[0] == 'd') \ | 239 | (buf[0] == 'D' || buf[0] == 'd') \ |
187 | && (buf[1] == 'A' || buf[1] == 'a') \ | 240 | && (buf[1] == 'A' || buf[1] == 'a') \ |
... | @@ -196,6 +249,65 @@ do \ | ... | @@ -196,6 +249,65 @@ do \ |
196 | && (buf[3] == 'M' || buf[3] == 'm') \ | 249 | && (buf[3] == 'M' || buf[3] == 'm') \ |
197 | && (buf[4] == ':' || buf[4] == ' ' || buf[4] == '\t')) | 250 | && (buf[4] == ':' || buf[4] == ' ' || buf[4] == '\t')) |
198 | 251 | ||
252 | #define ISIN_REPLY_TO(buf) (\ | ||
253 | (buf[0] == 'I' || buf[0] == 'i') \ | ||
254 | && (buf[1] == 'N' || buf[1] == 'n') \ | ||
255 | && (buf[2] == '-' || buf[2] == '-') \ | ||
256 | && (buf[3] == 'R' || buf[3] == 'r') \ | ||
257 | && (buf[4] == 'E' || buf[4] == 'e') \ | ||
258 | && (buf[5] == 'P' || buf[5] == 'p') \ | ||
259 | && (buf[6] == 'L' || buf[6] == 'l') \ | ||
260 | && (buf[7] == 'Y' || buf[7] == 'y') \ | ||
261 | && (buf[8] == '-') \ | ||
262 | && (buf[9] == 'T' || buf[9] == 't') \ | ||
263 | && (buf[10] == 'O' || buf[10] == 'o') \ | ||
264 | && (buf[11] == ':' || buf[11] == ' ' || buf[11] == '\t')) | ||
265 | |||
266 | #define ISMESSAGE_ID(buf) (\ | ||
267 | (buf[0] == 'M' || buf[0] == 'm') \ | ||
268 | && (buf[1] == 'E' || buf[1] == 'e') \ | ||
269 | && (buf[2] == 'S' || buf[2] == 's') \ | ||
270 | && (buf[3] == 'S' || buf[3] == 's') \ | ||
271 | && (buf[4] == 'A' || buf[4] == 'a') \ | ||
272 | && (buf[5] == 'G' || buf[5] == 'g') \ | ||
273 | && (buf[6] == 'E' || buf[6] == 'e') \ | ||
274 | && (buf[7] == '-') \ | ||
275 | && (buf[8] == 'I' || buf[8] == 'i') \ | ||
276 | && (buf[9] == 'D' || buf[9] == 'd') \ | ||
277 | && (buf[10] == ':' || buf[10] == ' ' || buf[10] == '\t')) | ||
278 | |||
279 | #define ISREFERENCE(buf) (\ | ||
280 | (buf[0] == 'R' || buf[0] == 'r') \ | ||
281 | && (buf[1] == 'E' || buf[1] == 'e') \ | ||
282 | && (buf[2] == 'F' || buf[2] == 'f') \ | ||
283 | && (buf[3] == 'E' || buf[3] == 'e') \ | ||
284 | && (buf[4] == 'R' || buf[4] == 'r') \ | ||
285 | && (buf[5] == 'E' || buf[5] == 'e') \ | ||
286 | && (buf[6] == 'n' || buf[6] == 'n') \ | ||
287 | && (buf[7] == 'C' || buf[7] == 'c') \ | ||
288 | && (buf[8] == 'E' || buf[8] == 'e') \ | ||
289 | && (buf[9] == ':' || buf[9] == ' ' || buf[9] == '\t')) | ||
290 | |||
291 | #define ISREPLY_TO(buf) (\ | ||
292 | (buf[0] == 'R' || buf[0] == 'r') \ | ||
293 | && (buf[1] == 'E' || buf[1] == 'e') \ | ||
294 | && (buf[2] == 'P' || buf[2] == 'p') \ | ||
295 | && (buf[3] == 'L' || buf[3] == 'l') \ | ||
296 | && (buf[4] == 'Y' || buf[4] == 'y') \ | ||
297 | && (buf[5] == '-') \ | ||
298 | && (buf[6] == 'T' || buf[6] == 't') \ | ||
299 | && (buf[7] == 'O' || buf[7] == 'o') \ | ||
300 | && (buf[8] == ':' || buf[8] == ' ' || buf[8] == '\t')) | ||
301 | |||
302 | #define ISSENDER(buf) (\ | ||
303 | (buf[0] == 'S' || buf[0] == 's') \ | ||
304 | && (buf[1] == 'E' || buf[1] == 'e') \ | ||
305 | && (buf[2] == 'N' || buf[2] == 'n') \ | ||
306 | && (buf[3] == 'D' || buf[3] == 'd') \ | ||
307 | && (buf[4] == 'E' || buf[4] == 'e') \ | ||
308 | && (buf[5] == 'R' || buf[5] == 'r') \ | ||
309 | && (buf[6] == ':' || buf[6] == ' ' || buf[6] == '\t')) | ||
310 | |||
199 | #define ISSTATUS(buf) (\ | 311 | #define ISSTATUS(buf) (\ |
200 | (buf[0] == 'S' || buf[0] == 's') \ | 312 | (buf[0] == 'S' || buf[0] == 's') \ |
201 | && (buf[1] == 'T' || buf[1] == 't') \ | 313 | && (buf[1] == 'T' || buf[1] == 't') \ |
... | @@ -250,10 +362,17 @@ do \ | ... | @@ -250,10 +362,17 @@ do \ |
250 | && (buf[4] == 'D' || buf[4] == 'd') \ | 362 | && (buf[4] == 'D' || buf[4] == 'd') \ |
251 | && (buf[5] == ':' || buf[5] == ' ' || buf[5] == '\t')) | 363 | && (buf[5] == ':' || buf[5] == ' ' || buf[5] == '\t')) |
252 | 364 | ||
253 | /* Skip prepen spaces. */ | 365 | /* Skip prepend spaces. */ |
254 | #define SKIPSPACE(p) while (*p == ' ') p++ | 366 | #define SKIPSPACE(p) while (*p == ' ') p++ |
255 | 367 | ||
256 | /* Save/concatenate the field-value in the field. */ | 368 | #define ATOI(a,i) \ |
369 | do {\ | ||
370 | SKIPSPACE(a); \ | ||
371 | for (i = 0; *a >= '0' && *a <= '9'; a++) \ | ||
372 | i = 10 * i + (*a - '0'); \ | ||
373 | } while (0) | ||
374 | |||
375 | /* Save/concatenate the field-value in the fast header(fhd) field. */ | ||
257 | #define FAST_HEADER(field,buf,n) \ | 376 | #define FAST_HEADER(field,buf,n) \ |
258 | do { \ | 377 | do { \ |
259 | int i = 0; \ | 378 | int i = 0; \ |
... | @@ -281,41 +400,65 @@ do { \ | ... | @@ -281,41 +400,65 @@ do { \ |
281 | } \ | 400 | } \ |
282 | } while (0) | 401 | } while (0) |
283 | 402 | ||
284 | #define FAST_HCONTENT_TYPE(mum,sf,buf,n) \ | 403 | #define FAST_H_BCC(mum,save_field,buf,n) \ |
285 | FAST_HEADER(mum->fhdr[HCONTENT_TYPE],buf,n); \ | 404 | FAST_HEADER(mum->fhdr[H_BCC],buf,n); \ |
286 | sf = &(mum->fhdr[HCONTENT_TYPE]) | 405 | save_field = &(mum->fhdr[H_BCC]) |
406 | |||
407 | #define FAST_H_CC(mum,save_field,buf,n) \ | ||
408 | FAST_HEADER(mum->fhdr[H_CC],buf,n); \ | ||
409 | save_field = &(mum->fhdr[H_CC]) | ||
410 | |||
411 | #define FAST_H_CONTENT_LANGUAGE(mum,save_field,buf,n) \ | ||
412 | FAST_HEADER(mum->fhdr[H_CONTENT_LANGUAGE],buf,n); \ | ||
413 | save_field = &(mum->fhdr[H_CONTENT_LANGUAGE]) | ||
287 | 414 | ||
288 | #define FAST_HCC(mum,sf,buf,n) \ | 415 | #define FAST_H_CONTENT_TRANSFER_ENCODING(mum,save_field,buf,n) \ |
289 | FAST_HEADER(mum->fhdr[HCC],buf,n); \ | 416 | FAST_HEADER(mum->fhdr[H_CONTENT_TRANSFER_ENCODING],buf,n); \ |
290 | sf = &(mum->fhdr[HCC]) | 417 | save_field = &(mum->fhdr[H_CONTENT_TRANSFER_ENCODING]) |
291 | 418 | ||
292 | #define FAST_HDATE(mum,sf,buf,n) \ | 419 | #define FAST_H_CONTENT_TYPE(mum,save_field,buf,n) \ |
293 | FAST_HEADER(mum->fhdr[HDATE],buf,n); \ | 420 | FAST_HEADER(mum->fhdr[H_CONTENT_TYPE],buf,n); \ |
294 | sf = &(mum->fhdr[HDATE]) | 421 | save_field = &(mum->fhdr[H_CONTENT_TYPE]) |
295 | 422 | ||
296 | #define FAST_HFROM(mum,sf,buf,n) \ | 423 | #define FAST_H_DATE(mum,save_field,buf,n) \ |
297 | FAST_HEADER(mum->fhdr[HFROM],buf,n); \ | 424 | FAST_HEADER(mum->fhdr[H_DATE],buf,n); \ |
298 | sf = &(mum->fhdr[HFROM]) | 425 | save_field = &(mum->fhdr[H_DATE]) |
299 | 426 | ||
300 | #define FAST_HSUBJECT(mum,sf,buf,n) \ | 427 | #define FAST_H_FROM(mum,save_field,buf,n) \ |
301 | FAST_HEADER(mum->fhdr[HSUBJECT],buf,n); \ | 428 | FAST_HEADER(mum->fhdr[H_FROM],buf,n); \ |
302 | sf = &(mum->fhdr[HSUBJECT]) | 429 | save_field = &(mum->fhdr[H_FROM]) |
303 | 430 | ||
304 | #define FAST_HTO(mum,sf,buf,n) \ | 431 | #define FAST_H_IN_REPLY_TO(mum,save_field,buf,n) \ |
305 | FAST_HEADER(mum->fhdr[HTO],buf,n); \ | 432 | FAST_HEADER(mum->fhdr[H_IN_REPLY_TO],buf,n); \ |
306 | sf = &(mum->fhdr[HTO]) | 433 | save_field = &(mum->fhdr[H_IN_REPLY_TO]) |
307 | 434 | ||
308 | #define FAST_HX_IMAPBASE(mum,sf,buf,n) \ | 435 | #define FAST_H_MESSAGE_ID(mum,save_field,buf,n) \ |
309 | FAST_HEADER(mum->fhdr[HX_IMAPBASE],buf,n); \ | 436 | FAST_HEADER(mum->fhdr[H_MESSAGE_ID],buf,n); \ |
310 | sf = &(mum->fhdr[HX_UID]) | 437 | save_field = &(mum->fhdr[H_MESSAGE_ID]) |
311 | 438 | ||
312 | #define FAST_HX_UIDL(mum,sf,buf,n) \ | 439 | #define FAST_H_REFERENCE(mum,save_field,buf,n) \ |
313 | FAST_HEADER(mum->fhdr[HX_UIDL],buf,n); \ | 440 | FAST_HEADER(mum->fhdr[H_REFERENCE],buf,n); \ |
314 | sf = &(mum->fhdr[HX_UIDL]) | 441 | save_field = &(mum->fhdr[H_REFERENCE]) |
315 | 442 | ||
316 | #define FAST_HX_UID(mum,sf,buf,n) \ | 443 | #define FAST_H_REPLY_TO(mum,save_field,buf,n) \ |
317 | FAST_HEADER(mum->fhdr[HX_UID],buf,n); \ | 444 | FAST_HEADER(mum->fhdr[H_REPLY_TO],buf,n); \ |
318 | sf = &(mum->fhdr[HX_UID]) | 445 | save_field = &(mum->fhdr[H_REPLY_TO]) |
446 | |||
447 | #define FAST_H_SENDER(mum,save_field,buf,n) \ | ||
448 | FAST_HEADER(mum->fhdr[H_SENDER],buf,n); \ | ||
449 | save_field = &(mum->fhdr[H_SENDER]) | ||
450 | |||
451 | #define FAST_H_SUBJECT(mum,save_field,buf,n) \ | ||
452 | FAST_HEADER(mum->fhdr[H_SUBJECT],buf,n); \ | ||
453 | save_field = &(mum->fhdr[H_SUBJECT]) | ||
454 | |||
455 | #define FAST_H_TO(mum,save_field,buf,n) \ | ||
456 | FAST_HEADER(mum->fhdr[H_TO],buf,n); \ | ||
457 | save_field = &(mum->fhdr[H_TO]) | ||
458 | |||
459 | #define FAST_H_X_UIDL(mum,save_field,buf,n) \ | ||
460 | FAST_HEADER(mum->fhdr[H_X_UIDL],buf,n); \ | ||
461 | save_field = &(mum->fhdr[H_X_UIDL]) | ||
319 | 462 | ||
320 | /* Notifications ADD_MESG. */ | 463 | /* Notifications ADD_MESG. */ |
321 | #define DISPATCH_ADD_MSG(mbox,mud) \ | 464 | #define DISPATCH_ADD_MSG(mbox,mud) \ |
... | @@ -445,6 +588,18 @@ mbox_scan0 (mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) | ... | @@ -445,6 +588,18 @@ mbox_scan0 (mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) |
445 | else | 588 | else |
446 | mud->messages_count = 0; | 589 | mud->messages_count = 0; |
447 | 590 | ||
591 | #if 0 | ||
592 | { | ||
593 | size_t j, k; | ||
594 | for (j = 0; j < mud->umessages_count; j++) | ||
595 | { | ||
596 | mum = mud->umessages[j]; | ||
597 | for (k = 0; k < HDRSIZE; k++) | ||
598 | if (mum->fhdr[k]) | ||
599 | free (mum->fhdr[k]); | ||
600 | } | ||
601 | } | ||
602 | #endif | ||
448 | newline = 1; | 603 | newline = 1; |
449 | errno = lines = inheader = inbody = 0; | 604 | errno = lines = inheader = inbody = 0; |
450 | 605 | ||
... | @@ -488,8 +643,7 @@ mbox_scan0 (mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) | ... | @@ -488,8 +643,7 @@ mbox_scan0 (mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) |
488 | mum->mud = mud; | 643 | mum->mud = mud; |
489 | mum->header_from = total - n; | 644 | mum->header_from = total - n; |
490 | mum->header_from_end = total; | 645 | mum->header_from_end = total; |
491 | mum->body_end = mum->body = 0; | 646 | //mum->body_end = mum->body = 0; |
492 | mum->attr_flags = 0; | ||
493 | lines = 0; | 647 | lines = 0; |
494 | sfield = NULL; | 648 | sfield = NULL; |
495 | for (j = 0; j < HDRSIZE; j++) | 649 | for (j = 0; j < HDRSIZE; j++) |
... | @@ -507,41 +661,88 @@ mbox_scan0 (mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) | ... | @@ -507,41 +661,88 @@ mbox_scan0 (mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) |
507 | ATTRIBUTE_SET(buf, mum, 'd', 'D', MU_ATTRIBUTE_DELETED); | 661 | ATTRIBUTE_SET(buf, mum, 'd', 'D', MU_ATTRIBUTE_DELETED); |
508 | sfield = NULL; | 662 | sfield = NULL; |
509 | } | 663 | } |
510 | else if (ISCONTENT_TYPE(buf)) | 664 | else if (ISBCC(buf)) |
511 | { | 665 | { |
512 | FAST_HCONTENT_TYPE(mum, sfield, buf, n); | 666 | FAST_H_BCC(mum, sfield, buf, n); |
513 | } | 667 | } |
514 | else if (ISCC(buf)) | 668 | else if (ISCC(buf)) |
515 | { | 669 | { |
516 | FAST_HCC(mum, sfield, buf, n); | 670 | FAST_H_CC(mum, sfield, buf, n); |
671 | } | ||
672 | else if (ISCONTENT_LANGUAGE(buf)) | ||
673 | { | ||
674 | FAST_H_CONTENT_LANGUAGE(mum, sfield, buf, n); | ||
675 | } | ||
676 | else if (ISCONTENT_TRANSFER_ENCODING(buf)) | ||
677 | { | ||
678 | FAST_H_CONTENT_TRANSFER_ENCODING(mum, sfield, buf, n); | ||
679 | } | ||
680 | else if (ISCONTENT_TYPE(buf)) | ||
681 | { | ||
682 | FAST_H_CONTENT_TYPE(mum, sfield, buf, n); | ||
517 | } | 683 | } |
518 | else if (ISDATE(buf)) | 684 | else if (ISDATE(buf)) |
519 | { | 685 | { |
520 | FAST_HDATE(mum, sfield, buf, n); | 686 | FAST_H_DATE(mum, sfield, buf, n); |
521 | } | 687 | } |
522 | else if (ISFROM(buf)) | 688 | else if (ISFROM(buf)) |
523 | { | 689 | { |
524 | FAST_HFROM(mum, sfield, buf, n); | 690 | char *ss = NULL; |
691 | if (mum->fhdr[H_FROM]) *ss = 1; | ||
692 | FAST_H_FROM(mum, sfield, buf, n); | ||
693 | } | ||
694 | else if (ISIN_REPLY_TO(buf)) | ||
695 | { | ||
696 | FAST_H_IN_REPLY_TO(mum, sfield, buf, n); | ||
697 | } | ||
698 | else if (ISMESSAGE_ID(buf)) | ||
699 | { | ||
700 | FAST_H_MESSAGE_ID(mum, sfield, buf, n); | ||
701 | } | ||
702 | else if (ISREFERENCE(buf)) | ||
703 | { | ||
704 | FAST_H_REFERENCE(mum, sfield, buf, n); | ||
705 | } | ||
706 | else if (ISREPLY_TO(buf)) | ||
707 | { | ||
708 | FAST_H_REPLY_TO(mum, sfield, buf, n); | ||
709 | } | ||
710 | else if (ISSENDER(buf)) | ||
711 | { | ||
712 | FAST_H_SENDER (mum, sfield, buf, n); | ||
525 | } | 713 | } |
526 | else if (ISSUBJECT(buf)) | 714 | else if (ISSUBJECT(buf)) |
527 | { | 715 | { |
528 | FAST_HSUBJECT (mum, sfield, buf, n); | 716 | char *ss = NULL; |
717 | if (mum->fhdr[H_SUBJECT]) *ss = 1; | ||
718 | FAST_H_SUBJECT (mum, sfield, buf, n); | ||
529 | } | 719 | } |
530 | else if (ISTO(buf)) | 720 | else if (ISTO(buf)) |
531 | { | 721 | { |
532 | FAST_HTO (mum, sfield, buf, n); | 722 | FAST_H_TO (mum, sfield, buf, n); |
533 | } | 723 | } |
534 | else if (ISX_IMAPBASE(buf)) | 724 | else if (ISX_UIDL(buf)) |
535 | { | 725 | { |
536 | FAST_HX_IMAPBASE (mum, sfield, buf, n); | 726 | FAST_H_X_UIDL (mum, sfield, buf, n); |
537 | } | 727 | } |
538 | else if (ISX_UIDL(buf)) | 728 | else if (ISX_IMAPBASE(buf)) |
729 | { | ||
730 | char *s = memchr (buf, ':', n); | ||
731 | if (s) | ||
539 | { | 732 | { |
540 | FAST_HX_UIDL (mum, sfield, buf, n); | 733 | s++; |
734 | ATOI(s, mud->uidvalidity); | ||
735 | ATOI(s, mud->uidnext); | ||
736 | } | ||
541 | } | 737 | } |
542 | else if (ISX_UID(buf)) | 738 | else if (ISX_UID(buf)) |
543 | { | 739 | { |
544 | FAST_HX_UID (mum, sfield, buf, n); | 740 | char *s = memchr (buf, ':', n); |
741 | if (s) | ||
742 | { | ||
743 | s++; | ||
744 | ATOI(s, mum->uid); | ||
745 | } | ||
545 | } | 746 | } |
546 | else if (sfield && (buf[0] == ' ' || buf[0] == '\t')) | 747 | else if (sfield && (buf[0] == ' ' || buf[0] == '\t')) |
547 | { | 748 | { |
... | @@ -596,65 +797,38 @@ mbox_scan0 (mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) | ... | @@ -596,65 +797,38 @@ mbox_scan0 (mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) |
596 | if (mud->messages_count > 0) | 797 | if (mud->messages_count > 0) |
597 | { | 798 | { |
598 | mum = mud->umessages[0]; | 799 | mum = mud->umessages[0]; |
599 | if (mum->fhdr[HX_IMAPBASE]) | ||
600 | { | ||
601 | char *s = mum->fhdr[HX_IMAPBASE]; | ||
602 | while (*s && !isdigit (*s)) s++; | ||
603 | mud->uidvalidity = strtoul (s, &s, 10); | ||
604 | mud->uidnext = strtoul (s, NULL, 10); | ||
605 | } | ||
606 | if (mud->uidvalidity == 0) | 800 | if (mud->uidvalidity == 0) |
607 | { | 801 | { |
608 | char u[64]; | ||
609 | mud->uidvalidity = (unsigned long)time (NULL); | 802 | mud->uidvalidity = (unsigned long)time (NULL); |
610 | mud->uidnext = mud->messages_count + 1; | 803 | mud->uidnext = mud->messages_count + 1; |
611 | if (mum->fhdr[HX_IMAPBASE]) | ||
612 | free (mum->fhdr[HX_IMAPBASE]); | ||
613 | sprintf (u, "%lu %u", mud->uidvalidity, mud->uidnext); | ||
614 | mum->fhdr[HX_IMAPBASE] = strdup (u); | ||
615 | /* Tell that we have been modified for expunging. */ | 804 | /* Tell that we have been modified for expunging. */ |
616 | mum->attr_flags |= MU_ATTRIBUTE_MODIFIED; | 805 | mum->attr_flags |= MU_ATTRIBUTE_MODIFIED; |
617 | } | 806 | } |
618 | } | 807 | } |
619 | /* Reset the IMAP uids, if necessary. */ | 808 | /* Reset the IMAP uids, if necessary. UID according to IMAP RFC is a 32 bit |
809 | ascending number for each messages */ | ||
620 | { | 810 | { |
621 | size_t uid; | 811 | size_t uid; |
622 | size_t ouid; | 812 | size_t ouid; |
623 | size_t i; | 813 | size_t i; |
624 | for (uid = ouid = i = 0; i < mud->messages_count; i++) | 814 | for (uid = ouid = i = 0; i < mud->messages_count; i++) |
625 | { | 815 | { |
626 | char *s; | ||
627 | mum = mud->umessages[i]; | 816 | mum = mud->umessages[i]; |
628 | s = mum->fhdr[HX_UID]; | 817 | uid = mum->uid; |
629 | if (s) | ||
630 | { | ||
631 | while (*s && !isdigit (*s)) s++; | ||
632 | uid = strtoul (s, &s, 10); | ||
633 | } | ||
634 | else | ||
635 | uid = 0; | ||
636 | if (uid <= ouid) | 818 | if (uid <= ouid) |
637 | { | 819 | { |
638 | char u[64]; | ||
639 | uid = ouid + 1; | 820 | uid = ouid + 1; |
640 | sprintf (u, "%d", uid); | 821 | mum->uid = ouid = uid; |
641 | if (mum->fhdr[HX_UID]) | 822 | /* Note that modification for when expunging. */ |
642 | free (mum->fhdr[HX_UID]); | ||
643 | mum->fhdr[HX_UID] = strdup (u); | ||
644 | /* Note that we have modified for expunging. */ | ||
645 | mum->attr_flags |= MU_ATTRIBUTE_MODIFIED; | 823 | mum->attr_flags |= MU_ATTRIBUTE_MODIFIED; |
646 | } | 824 | } |
647 | mum->uid = ouid = uid; | 825 | else |
826 | ouid = uid; | ||
648 | } | 827 | } |
649 | if (uid >= mud->uidnext) | 828 | if (mud->messages_count > 0 && uid >= mud->uidnext) |
650 | { | 829 | { |
651 | char u[64]; | ||
652 | mud->uidnext = uid + 1; | ||
653 | mum = mud->umessages[0]; | 830 | mum = mud->umessages[0]; |
654 | if (mum->fhdr[HX_IMAPBASE]) | 831 | mud->uidnext = uid + 1; |
655 | free (mum->fhdr[HX_IMAPBASE]); | ||
656 | sprintf (u, "%lu %u", mud->uidvalidity, uid + 1); | ||
657 | mum->fhdr[HX_IMAPBASE] = strdup (u); | ||
658 | mum->attr_flags |= MU_ATTRIBUTE_MODIFIED; | 832 | mum->attr_flags |= MU_ATTRIBUTE_MODIFIED; |
659 | } | 833 | } |
660 | } | 834 | } | ... | ... |
... | @@ -162,10 +162,26 @@ message_is_modified (message_t msg) | ... | @@ -162,10 +162,26 @@ message_is_modified (message_t msg) |
162 | int mod = 0; | 162 | int mod = 0; |
163 | mod |= header_is_modified (msg->header); | 163 | mod |= header_is_modified (msg->header); |
164 | mod |= attribute_is_modified (msg->attribute); | 164 | mod |= attribute_is_modified (msg->attribute); |
165 | mod |= body_is_modified (msg->body); | ||
165 | return mod; | 166 | return mod; |
166 | } | 167 | } |
167 | 168 | ||
168 | int | 169 | int |
170 | message_clear_modified (message_t msg) | ||
171 | { | ||
172 | if (msg) | ||
173 | { | ||
174 | if (msg->header) | ||
175 | header_clear_modified (msg->header); | ||
176 | if (msg->attribute) | ||
177 | attribute_clear_modified (msg->attribute); | ||
178 | if (msg->body) | ||
179 | body_clear_modified (msg->body); | ||
180 | } | ||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | int | ||
169 | message_set_mailbox (message_t msg, mailbox_t mailbox) | 185 | message_set_mailbox (message_t msg, mailbox_t mailbox) |
170 | { | 186 | { |
171 | if (msg == NULL) | 187 | if (msg == NULL) | ... | ... |
-
Please register or sign in to post a comment