Commit 9bb7be19 9bb7be1916bab7ef490980694e2bfc7a6898c52a by Alain Magloire

Put more headers in the cache, (ugly).

1 parent 419da3f7
...@@ -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)))
641 { 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)
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])
287 406
288 #define FAST_HCC(mum,sf,buf,n) \ 407 #define FAST_H_CC(mum,save_field,buf,n) \
289 FAST_HEADER(mum->fhdr[HCC],buf,n); \ 408 FAST_HEADER(mum->fhdr[H_CC],buf,n); \
290 sf = &(mum->fhdr[HCC]) 409 save_field = &(mum->fhdr[H_CC])
291 410
292 #define FAST_HDATE(mum,sf,buf,n) \ 411 #define FAST_H_CONTENT_LANGUAGE(mum,save_field,buf,n) \
293 FAST_HEADER(mum->fhdr[HDATE],buf,n); \ 412 FAST_HEADER(mum->fhdr[H_CONTENT_LANGUAGE],buf,n); \
294 sf = &(mum->fhdr[HDATE]) 413 save_field = &(mum->fhdr[H_CONTENT_LANGUAGE])
295 414
296 #define FAST_HFROM(mum,sf,buf,n) \ 415 #define FAST_H_CONTENT_TRANSFER_ENCODING(mum,save_field,buf,n) \
297 FAST_HEADER(mum->fhdr[HFROM],buf,n); \ 416 FAST_HEADER(mum->fhdr[H_CONTENT_TRANSFER_ENCODING],buf,n); \
298 sf = &(mum->fhdr[HFROM]) 417 save_field = &(mum->fhdr[H_CONTENT_TRANSFER_ENCODING])
299 418
300 #define FAST_HSUBJECT(mum,sf,buf,n) \ 419 #define FAST_H_CONTENT_TYPE(mum,save_field,buf,n) \
301 FAST_HEADER(mum->fhdr[HSUBJECT],buf,n); \ 420 FAST_HEADER(mum->fhdr[H_CONTENT_TYPE],buf,n); \
302 sf = &(mum->fhdr[HSUBJECT]) 421 save_field = &(mum->fhdr[H_CONTENT_TYPE])
303 422
304 #define FAST_HTO(mum,sf,buf,n) \ 423 #define FAST_H_DATE(mum,save_field,buf,n) \
305 FAST_HEADER(mum->fhdr[HTO],buf,n); \ 424 FAST_HEADER(mum->fhdr[H_DATE],buf,n); \
306 sf = &(mum->fhdr[HTO]) 425 save_field = &(mum->fhdr[H_DATE])
307 426
308 #define FAST_HX_IMAPBASE(mum,sf,buf,n) \ 427 #define FAST_H_FROM(mum,save_field,buf,n) \
309 FAST_HEADER(mum->fhdr[HX_IMAPBASE],buf,n); \ 428 FAST_HEADER(mum->fhdr[H_FROM],buf,n); \
310 sf = &(mum->fhdr[HX_UID]) 429 save_field = &(mum->fhdr[H_FROM])
311 430
312 #define FAST_HX_UIDL(mum,sf,buf,n) \ 431 #define FAST_H_IN_REPLY_TO(mum,save_field,buf,n) \
313 FAST_HEADER(mum->fhdr[HX_UIDL],buf,n); \ 432 FAST_HEADER(mum->fhdr[H_IN_REPLY_TO],buf,n); \
314 sf = &(mum->fhdr[HX_UIDL]) 433 save_field = &(mum->fhdr[H_IN_REPLY_TO])
315 434
316 #define FAST_HX_UID(mum,sf,buf,n) \ 435 #define FAST_H_MESSAGE_ID(mum,save_field,buf,n) \
317 FAST_HEADER(mum->fhdr[HX_UID],buf,n); \ 436 FAST_HEADER(mum->fhdr[H_MESSAGE_ID],buf,n); \
318 sf = &(mum->fhdr[HX_UID]) 437 save_field = &(mum->fhdr[H_MESSAGE_ID])
438
439 #define FAST_H_REFERENCE(mum,save_field,buf,n) \
440 FAST_HEADER(mum->fhdr[H_REFERENCE],buf,n); \
441 save_field = &(mum->fhdr[H_REFERENCE])
442
443 #define FAST_H_REPLY_TO(mum,save_field,buf,n) \
444 FAST_HEADER(mum->fhdr[H_REPLY_TO],buf,n); \
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))
539 { 729 {
540 FAST_HX_UIDL (mum, sfield, buf, n); 730 char *s = memchr (buf, ':', n);
731 if (s)
732 {
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)
......