Change attribute handling in Maildir format.
* include/mailutils/message.h (MU_MSG_ATTRIBUTE_MODIFIED) (MU_MSG_HEADER_MODIFIED,MU_MSG_BODY_MODIFIED): New flags. * libmailutils/mailbox/message.c (mu_message_is_modified): Return a bitmask from the above values. * libmailutils/property/create.c (mu_property_create_init): Return error code. * include/mailutils/sys/amd.h (_amd_data) <chattr_msg> <capabilities, prop>: New members. <uidvalidity>: Remove. * libmailutils/base/amd.c: Use MH-style proplist to keep the mailbox properties: uidvalidity, last uid and to cache its size. Store message attributes in the message header only if the mailbox implementation is unable to keep them elsewhere. Use chattr_msg method (if provided) to flush changes in message attributes. * libproto/maildir/folder.c (_maildir_list_p): Ignore .mh* and .mu* files. * libproto/mh/folder.c (_mh_list_p): Likewise. * libproto/maildir/mbox.c: Implement all Maildir flags (except P). Implement the chattr_msg method. * libproto/mh/mbox.c: Remove special handling for uidvalidity. * mh/tests/folder.at: Ignore .mu-prop in directory listings.
Showing
10 changed files
with
366 additions
and
178 deletions
... | @@ -53,6 +53,11 @@ extern void mu_message_destroy (mu_message_t *, void *owner); | ... | @@ -53,6 +53,11 @@ extern void mu_message_destroy (mu_message_t *, void *owner); |
53 | extern int mu_message_create_copy (mu_message_t *to, mu_message_t from); | 53 | extern int mu_message_create_copy (mu_message_t *to, mu_message_t from); |
54 | 54 | ||
55 | extern void *mu_message_get_owner (mu_message_t); | 55 | extern void *mu_message_get_owner (mu_message_t); |
56 | |||
57 | #define MU_MSG_ATTRIBUTE_MODIFIED 0x01 | ||
58 | #define MU_MSG_HEADER_MODIFIED 0x02 | ||
59 | #define MU_MSG_BODY_MODIFIED 0x04 | ||
60 | |||
56 | extern int mu_message_is_modified (mu_message_t); | 61 | extern int mu_message_is_modified (mu_message_t); |
57 | extern int mu_message_clear_modified (mu_message_t); | 62 | extern int mu_message_clear_modified (mu_message_t); |
58 | extern int mu_message_get_mailbox (mu_message_t, mu_mailbox_t *); | 63 | extern int mu_message_get_mailbox (mu_message_t, mu_mailbox_t *); | ... | ... |
... | @@ -43,7 +43,13 @@ | ... | @@ -43,7 +43,13 @@ |
43 | mu_monitor_wrlock (mbox->monitor); \ | 43 | mu_monitor_wrlock (mbox->monitor); \ |
44 | } while (0); | 44 | } while (0); |
45 | 45 | ||
46 | # define MU_AMD_SIZE_FILE_NAME ".mu-size" | 46 | #define _MU_AMD_PROP_UIDVALIDITY "uid-validity" |
47 | #define _MU_AMD_PROP_NEXT_UID "next-uid" | ||
48 | #define _MU_AMD_PROP_SIZE "size" | ||
49 | |||
50 | #define _MU_AMD_PROP_FILE_NAME ".mu-prop" | ||
51 | /* Legacy (2.x) size file name */ | ||
52 | #define _MU_AMD_SIZE_FILE_NAME ".mu-size" | ||
47 | 53 | ||
48 | struct _amd_data; | 54 | struct _amd_data; |
49 | struct _amd_message | 55 | struct _amd_message |
... | @@ -64,6 +70,10 @@ struct _amd_message | ... | @@ -64,6 +70,10 @@ struct _amd_message |
64 | struct _amd_data *amd; /* Back pointer. */ | 70 | struct _amd_data *amd; /* Back pointer. */ |
65 | }; | 71 | }; |
66 | 72 | ||
73 | /* AMD capabilities */ | ||
74 | #define MU_AMD_STATUS 0x01 /* format keeps status flags */ | ||
75 | #define MU_AMD_IMAPBASE 0x02 /* format keeps IMAP base */ | ||
76 | |||
67 | struct _amd_data | 77 | struct _amd_data |
68 | { | 78 | { |
69 | size_t msg_size; /* Size of struct _amd_message */ | 79 | size_t msg_size; /* Size of struct _amd_message */ |
... | @@ -83,16 +93,19 @@ struct _amd_data | ... | @@ -83,16 +93,19 @@ struct _amd_data |
83 | size_t (*next_uid) (struct _amd_data *mhd); | 93 | size_t (*next_uid) (struct _amd_data *mhd); |
84 | int (*remove) (struct _amd_data *); | 94 | int (*remove) (struct _amd_data *); |
85 | int (*delete_msg) (struct _amd_data *, struct _amd_message *); | 95 | int (*delete_msg) (struct _amd_data *, struct _amd_message *); |
96 | int (*chattr_msg) (struct _amd_message *, int); | ||
86 | 97 | ||
87 | /* List of messages: */ | 98 | /* List of messages: */ |
88 | size_t msg_count; /* number of messages in the list */ | 99 | size_t msg_count; /* number of messages in the list */ |
89 | size_t msg_max; /* maximum message buffer capacity */ | 100 | size_t msg_max; /* maximum message buffer capacity */ |
90 | struct _amd_message **msg_array; | 101 | struct _amd_message **msg_array; |
91 | 102 | ||
92 | unsigned long uidvalidity; | 103 | int capabilities; |
93 | int has_new_msg; /* New messages have been appended */ | 104 | int has_new_msg; /* New messages have been appended */ |
94 | char *name; /* Directory name */ | 105 | char *name; /* Directory name */ |
95 | 106 | ||
107 | mu_property_t prop; /* Properties: uidvalidity, nextuid, etc. */ | ||
108 | |||
96 | /* Pool of open message streams */ | 109 | /* Pool of open message streams */ |
97 | struct _amd_message *msg_pool[MAX_OPEN_STREAMS]; | 110 | struct _amd_message *msg_pool[MAX_OPEN_STREAMS]; |
98 | int pool_first; /* Index to the first used entry in msg_pool */ | 111 | int pool_first; /* Index to the first used entry in msg_pool */ | ... | ... |
... | @@ -130,6 +130,147 @@ struct _amd_body_stream | ... | @@ -130,6 +130,147 @@ struct _amd_body_stream |
130 | mu_off_t off; | 130 | mu_off_t off; |
131 | }; | 131 | }; |
132 | 132 | ||
133 | /* AMD Properties */ | ||
134 | int | ||
135 | _amd_prop_fetch_off (struct _amd_data *amd, const char *name, mu_off_t *pval) | ||
136 | { | ||
137 | const char *p; | ||
138 | mu_off_t n = 0; | ||
139 | |||
140 | if (!amd->prop || mu_property_sget_value (amd->prop, name, &p)) | ||
141 | return MU_ERR_NOENT; | ||
142 | if (!pval) | ||
143 | return 0; | ||
144 | for (; *p; p++) | ||
145 | { | ||
146 | if (!mu_isdigit (*p)) | ||
147 | return EINVAL; | ||
148 | n = n * 10 + *p - '0'; | ||
149 | } | ||
150 | *pval = n; | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | int | ||
155 | _amd_prop_fetch_size (struct _amd_data *amd, const char *name, size_t *pval) | ||
156 | { | ||
157 | mu_off_t n; | ||
158 | int rc = _amd_prop_fetch_off (amd, name, &n); | ||
159 | if (rc == 0) | ||
160 | { | ||
161 | size_t s = n; | ||
162 | if (s != n) | ||
163 | return ERANGE; | ||
164 | if (pval) | ||
165 | *pval = s; | ||
166 | } | ||
167 | return rc; | ||
168 | } | ||
169 | |||
170 | int | ||
171 | _amd_prop_fetch_ulong (struct _amd_data *amd, const char *name, | ||
172 | unsigned long *pval) | ||
173 | { | ||
174 | mu_off_t n; | ||
175 | int rc = _amd_prop_fetch_off (amd, name, &n); | ||
176 | if (rc == 0) | ||
177 | { | ||
178 | unsigned long s = n; | ||
179 | if (s != n) | ||
180 | return ERANGE; | ||
181 | if (pval) | ||
182 | *pval = s; | ||
183 | } | ||
184 | return rc; | ||
185 | } | ||
186 | |||
187 | int | ||
188 | _amd_prop_store_off (struct _amd_data *amd, const char *name, mu_off_t val) | ||
189 | { | ||
190 | char nbuf[128]; | ||
191 | char *p; | ||
192 | int sign = 0; | ||
193 | |||
194 | p = nbuf + sizeof nbuf; | ||
195 | *--p = 0; | ||
196 | if (val < 0) | ||
197 | { | ||
198 | sign = 1; | ||
199 | val = - val; | ||
200 | } | ||
201 | do | ||
202 | { | ||
203 | unsigned d = val % 10; | ||
204 | if (p == nbuf) | ||
205 | return ERANGE; | ||
206 | *--p = d + '0'; | ||
207 | val /= 10; | ||
208 | } | ||
209 | while (val); | ||
210 | if (sign) | ||
211 | { | ||
212 | if (p == nbuf) | ||
213 | return ERANGE; | ||
214 | *--p = '-'; | ||
215 | } | ||
216 | return mu_property_set_value (amd->prop, name, p, 1); | ||
217 | } | ||
218 | |||
219 | /* Backward-compatible size file support */ | ||
220 | static int | ||
221 | read_size_file (struct _amd_data *amd) | ||
222 | { | ||
223 | FILE *fp; | ||
224 | int rc; | ||
225 | char *name = mu_make_file_name (amd->name, _MU_AMD_SIZE_FILE_NAME); | ||
226 | if (!name) | ||
227 | return 1; | ||
228 | fp = fopen (name, "r"); | ||
229 | if (fp) | ||
230 | { | ||
231 | unsigned long size; | ||
232 | if (fscanf (fp, "%lu", &size) == 1) | ||
233 | { | ||
234 | rc = _amd_prop_store_off (amd, _MU_AMD_PROP_SIZE, size); | ||
235 | } | ||
236 | else | ||
237 | rc = 1; | ||
238 | fclose (fp); | ||
239 | unlink (name); | ||
240 | } | ||
241 | else | ||
242 | rc = 1; | ||
243 | free (name); | ||
244 | return rc; | ||
245 | } | ||
246 | |||
247 | static int | ||
248 | _amd_prop_create (struct _amd_data *amd) | ||
249 | { | ||
250 | int rc; | ||
251 | struct mu_mh_prop *mhprop; | ||
252 | mhprop = calloc (1, sizeof (mhprop[0])); | ||
253 | if (!mhprop) | ||
254 | return ENOMEM; | ||
255 | mhprop->filename = mu_make_file_name (amd->name, _MU_AMD_PROP_FILE_NAME); | ||
256 | if (!mhprop->filename) | ||
257 | { | ||
258 | free (mhprop); | ||
259 | return errno; | ||
260 | } | ||
261 | rc = mu_property_create_init (&amd->prop, mu_mh_property_init, mhprop); | ||
262 | if (rc) | ||
263 | { | ||
264 | mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR, | ||
265 | ("mu_property_create_init: %s", | ||
266 | mu_strerror (rc))); | ||
267 | free (mhprop->filename); | ||
268 | free (mhprop); | ||
269 | } | ||
270 | else | ||
271 | read_size_file (amd); | ||
272 | return rc; | ||
273 | } | ||
133 | 274 | ||
134 | /* Operations on message array */ | 275 | /* Operations on message array */ |
135 | 276 | ||
... | @@ -246,8 +387,8 @@ amd_array_expand (struct _amd_data *amd, size_t index) | ... | @@ -246,8 +387,8 @@ amd_array_expand (struct _amd_data *amd, size_t index) |
246 | return 0; | 387 | return 0; |
247 | } | 388 | } |
248 | 389 | ||
249 | /* Shrink the message array by removing element at INDEX-COUNT and | 390 | /* Shrink the message array by removing the element at INDEX-COUNT and |
250 | shifting left by COUNT positions all the elements on the right of | 391 | shifting left by COUNT positions all the elements to the right of |
251 | it. */ | 392 | it. */ |
252 | int | 393 | int |
253 | amd_array_shrink (struct _amd_data *amd, size_t index, size_t count) | 394 | amd_array_shrink (struct _amd_data *amd, size_t index, size_t count) |
... | @@ -273,7 +414,7 @@ amd_init_mailbox (mu_mailbox_t mailbox, size_t amd_size, | ... | @@ -273,7 +414,7 @@ amd_init_mailbox (mu_mailbox_t mailbox, size_t amd_size, |
273 | return EINVAL; | 414 | return EINVAL; |
274 | 415 | ||
275 | amd = mailbox->data = calloc (1, amd_size); | 416 | amd = mailbox->data = calloc (1, amd_size); |
276 | if (mailbox->data == NULL) | 417 | if (amd == NULL) |
277 | return ENOMEM; | 418 | return ENOMEM; |
278 | 419 | ||
279 | /* Back pointer. */ | 420 | /* Back pointer. */ |
... | @@ -334,6 +475,8 @@ amd_destroy (mu_mailbox_t mailbox) | ... | @@ -334,6 +475,8 @@ amd_destroy (mu_mailbox_t mailbox) |
334 | } | 475 | } |
335 | free (amd->msg_array); | 476 | free (amd->msg_array); |
336 | 477 | ||
478 | mu_property_destroy (&amd->prop); | ||
479 | |||
337 | if (amd->name) | 480 | if (amd->name) |
338 | free (amd->name); | 481 | free (amd->name); |
339 | 482 | ||
... | @@ -374,6 +517,9 @@ amd_open (mu_mailbox_t mailbox, int flags) | ... | @@ -374,6 +517,9 @@ amd_open (mu_mailbox_t mailbox, int flags) |
374 | W_OK : R_OK | X_OK)) | 517 | W_OK : R_OK | X_OK)) |
375 | return errno; | 518 | return errno; |
376 | 519 | ||
520 | /* Create/read properties. It is not an error if this fails. */ | ||
521 | _amd_prop_create (amd); | ||
522 | |||
377 | if (mailbox->locker == NULL) | 523 | if (mailbox->locker == NULL) |
378 | mu_locker_create (&mailbox->locker, "/dev/null", 0); | 524 | mu_locker_create (&mailbox->locker, "/dev/null", 0); |
379 | 525 | ||
... | @@ -405,7 +551,6 @@ amd_close (mu_mailbox_t mailbox) | ... | @@ -405,7 +551,6 @@ amd_close (mu_mailbox_t mailbox) |
405 | amd->msg_count = 0; /* number of messages in the list */ | 551 | amd->msg_count = 0; /* number of messages in the list */ |
406 | amd->msg_max = 0; /* maximum message buffer capacity */ | 552 | amd->msg_max = 0; /* maximum message buffer capacity */ |
407 | 553 | ||
408 | amd->uidvalidity = 0; | ||
409 | mu_monitor_unlock (mailbox->monitor); | 554 | mu_monitor_unlock (mailbox->monitor); |
410 | 555 | ||
411 | return 0; | 556 | return 0; |
... | @@ -547,6 +692,27 @@ _amd_attach_message (mu_mailbox_t mailbox, struct _amd_message *mhm, | ... | @@ -547,6 +692,27 @@ _amd_attach_message (mu_mailbox_t mailbox, struct _amd_message *mhm, |
547 | } | 692 | } |
548 | 693 | ||
549 | static int | 694 | static int |
695 | _amd_scan0 (struct _amd_data *amd, size_t msgno, size_t *pcount, | ||
696 | int do_notify) | ||
697 | { | ||
698 | int status = amd->scan0 (amd->mailbox, msgno, pcount, do_notify); | ||
699 | if (status != 0) | ||
700 | return status; | ||
701 | /* Reset the uidvalidity. */ | ||
702 | if (amd->msg_count > 0) | ||
703 | { | ||
704 | unsigned long uidval; | ||
705 | if (_amd_prop_fetch_ulong (amd, _MU_AMD_PROP_UIDVALIDITY, &uidval) || | ||
706 | !uidval) | ||
707 | { | ||
708 | uidval = (unsigned long)time (NULL); | ||
709 | _amd_prop_store_off (amd, _MU_AMD_PROP_UIDVALIDITY, uidval); | ||
710 | } | ||
711 | } | ||
712 | return 0; | ||
713 | } | ||
714 | |||
715 | static int | ||
550 | amd_get_message (mu_mailbox_t mailbox, size_t msgno, mu_message_t *pmsg) | 716 | amd_get_message (mu_mailbox_t mailbox, size_t msgno, mu_message_t *pmsg) |
551 | { | 717 | { |
552 | int status; | 718 | int status; |
... | @@ -562,7 +728,7 @@ amd_get_message (mu_mailbox_t mailbox, size_t msgno, mu_message_t *pmsg) | ... | @@ -562,7 +728,7 @@ amd_get_message (mu_mailbox_t mailbox, size_t msgno, mu_message_t *pmsg) |
562 | /* If we did not start a scanning yet do it now. */ | 728 | /* If we did not start a scanning yet do it now. */ |
563 | if (amd->msg_count == 0) | 729 | if (amd->msg_count == 0) |
564 | { | 730 | { |
565 | status = amd->scan0 (mailbox, 1, NULL, 0); | 731 | status = _amd_scan0 (amd, 1, NULL, 0); |
566 | if (status != 0) | 732 | if (status != 0) |
567 | return status; | 733 | return status; |
568 | } | 734 | } |
... | @@ -647,7 +813,6 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm, | ... | @@ -647,7 +813,6 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm, |
647 | mu_body_t body; | 813 | mu_body_t body; |
648 | const char *sbuf; | 814 | const char *sbuf; |
649 | mu_envelope_t env = NULL; | 815 | mu_envelope_t env = NULL; |
650 | char statbuf[MU_STATUS_BUF_SIZE]; | ||
651 | 816 | ||
652 | status = mu_message_size (msg, &bsize); | 817 | status = mu_message_size (msg, &bsize); |
653 | if (status) | 818 | if (status) |
... | @@ -724,17 +889,6 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm, | ... | @@ -724,17 +889,6 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm, |
724 | } | 889 | } |
725 | mu_stream_destroy (&stream); | 890 | mu_stream_destroy (&stream); |
726 | 891 | ||
727 | /* Add imapbase */ | ||
728 | if (!(amd->mailbox->flags & MU_STREAM_APPEND) | ||
729 | && amd->next_uid | ||
730 | && (!amd->msg_array || (amd->msg_array[0] == mhm))) /*FIXME*/ | ||
731 | { | ||
732 | nbytes += fprintf (fp, "X-IMAPbase: %lu %u\n", | ||
733 | (unsigned long) amd->uidvalidity, | ||
734 | (unsigned) amd->next_uid (amd)); | ||
735 | nlines++; | ||
736 | } | ||
737 | |||
738 | mu_message_get_envelope (msg, &env); | 892 | mu_message_get_envelope (msg, &env); |
739 | if (mu_envelope_sget_date (env, &sbuf) == 0) | 893 | if (mu_envelope_sget_date (env, &sbuf) == 0) |
740 | { | 894 | { |
... | @@ -755,7 +909,11 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm, | ... | @@ -755,7 +909,11 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm, |
755 | nlines++; | 909 | nlines++; |
756 | } | 910 | } |
757 | 911 | ||
912 | if (!(amd->capabilities & MU_AMD_STATUS)) | ||
913 | { | ||
758 | /* Add status */ | 914 | /* Add status */ |
915 | char statbuf[MU_STATUS_BUF_SIZE]; | ||
916 | |||
759 | mu_message_get_attribute (msg, &attr); | 917 | mu_message_get_attribute (msg, &attr); |
760 | mu_attribute_to_string (attr, statbuf, sizeof (statbuf), &n); | 918 | mu_attribute_to_string (attr, statbuf, sizeof (statbuf), &n); |
761 | if (n) | 919 | if (n) |
... | @@ -763,6 +921,8 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm, | ... | @@ -763,6 +921,8 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm, |
763 | nbytes += fprintf (fp, "Status: %s\n", statbuf); | 921 | nbytes += fprintf (fp, "Status: %s\n", statbuf); |
764 | nlines++; | 922 | nlines++; |
765 | } | 923 | } |
924 | } | ||
925 | |||
766 | nbytes += fprintf (fp, "\n"); | 926 | nbytes += fprintf (fp, "\n"); |
767 | nlines++; | 927 | nlines++; |
768 | 928 | ||
... | @@ -858,7 +1018,7 @@ amd_append_message (mu_mailbox_t mailbox, mu_message_t msg) | ... | @@ -858,7 +1018,7 @@ amd_append_message (mu_mailbox_t mailbox, mu_message_t msg) |
858 | /* If we did not start a scanning yet do it now. */ | 1018 | /* If we did not start a scanning yet do it now. */ |
859 | if (amd->msg_count == 0) | 1019 | if (amd->msg_count == 0) |
860 | { | 1020 | { |
861 | status = amd->scan0 (mailbox, 1, NULL, 0); | 1021 | status = _amd_scan0 (amd, 1, NULL, 0); |
862 | if (status != 0) | 1022 | if (status != 0) |
863 | { | 1023 | { |
864 | free (mhm); | 1024 | free (mhm); |
... | @@ -923,7 +1083,7 @@ amd_messages_count (mu_mailbox_t mailbox, size_t *pcount) | ... | @@ -923,7 +1083,7 @@ amd_messages_count (mu_mailbox_t mailbox, size_t *pcount) |
923 | return EINVAL; | 1083 | return EINVAL; |
924 | 1084 | ||
925 | if (!amd_is_updated (mailbox)) | 1085 | if (!amd_is_updated (mailbox)) |
926 | return amd->scan0 (mailbox, amd->msg_count, pcount, 0); | 1086 | return _amd_scan0 (amd, amd->msg_count, pcount, 0); |
927 | 1087 | ||
928 | if (pcount) | 1088 | if (pcount) |
929 | *pcount = amd->msg_count; | 1089 | *pcount = amd->msg_count; |
... | @@ -943,7 +1103,7 @@ amd_messages_recent (mu_mailbox_t mailbox, size_t *pcount) | ... | @@ -943,7 +1103,7 @@ amd_messages_recent (mu_mailbox_t mailbox, size_t *pcount) |
943 | /* If we did not start a scanning yet do it now. */ | 1103 | /* If we did not start a scanning yet do it now. */ |
944 | if (amd->msg_count == 0) | 1104 | if (amd->msg_count == 0) |
945 | { | 1105 | { |
946 | int status = amd->scan0 (mailbox, 1, NULL, 0); | 1106 | int status = _amd_scan0 (amd, 1, NULL, 0); |
947 | if (status != 0) | 1107 | if (status != 0) |
948 | return status; | 1108 | return status; |
949 | } | 1109 | } |
... | @@ -967,7 +1127,7 @@ amd_message_unseen (mu_mailbox_t mailbox, size_t *pmsgno) | ... | @@ -967,7 +1127,7 @@ amd_message_unseen (mu_mailbox_t mailbox, size_t *pmsgno) |
967 | /* If we did not start a scanning yet do it now. */ | 1127 | /* If we did not start a scanning yet do it now. */ |
968 | if (amd->msg_count == 0) | 1128 | if (amd->msg_count == 0) |
969 | { | 1129 | { |
970 | int status = amd->scan0 (mailbox, 1, NULL, 0); | 1130 | int status = _amd_scan0 (amd, 1, NULL, 0); |
971 | if (status != 0) | 1131 | if (status != 0) |
972 | return status; | 1132 | return status; |
973 | } | 1133 | } |
... | @@ -983,70 +1143,9 @@ amd_message_unseen (mu_mailbox_t mailbox, size_t *pmsgno) | ... | @@ -983,70 +1143,9 @@ amd_message_unseen (mu_mailbox_t mailbox, size_t *pmsgno) |
983 | return 0; | 1143 | return 0; |
984 | } | 1144 | } |
985 | 1145 | ||
986 | static char * | ||
987 | make_size_file_name (struct _amd_data *amd) | ||
988 | { | ||
989 | size_t size = strlen (amd->name) + 1 + sizeof (MU_AMD_SIZE_FILE_NAME); | ||
990 | char *name = malloc (size); | ||
991 | if (name) | ||
992 | { | ||
993 | strcpy (name, amd->name); | ||
994 | strcat (name, "/"); | ||
995 | strcat (name, MU_AMD_SIZE_FILE_NAME); | ||
996 | } | ||
997 | return name; | ||
998 | } | ||
999 | |||
1000 | static int | 1146 | static int |
1001 | read_size_file (struct _amd_data *amd, mu_off_t *psize) | 1147 | _compute_mailbox_size_recursive (struct _amd_data *amd, const char *name, |
1002 | { | 1148 | mu_off_t *psize) |
1003 | FILE *fp; | ||
1004 | int rc; | ||
1005 | char *name = make_size_file_name (amd); | ||
1006 | if (!name) | ||
1007 | return 1; | ||
1008 | fp = fopen (name, "r"); | ||
1009 | if (fp) | ||
1010 | { | ||
1011 | unsigned long size; | ||
1012 | if (fscanf (fp, "%lu", &size) == 1) | ||
1013 | { | ||
1014 | *psize = size; | ||
1015 | rc = 0; | ||
1016 | } | ||
1017 | else | ||
1018 | rc = 1; | ||
1019 | fclose (fp); | ||
1020 | } | ||
1021 | else | ||
1022 | rc = 1; | ||
1023 | free (name); | ||
1024 | return rc; | ||
1025 | } | ||
1026 | |||
1027 | static int | ||
1028 | write_size_file (struct _amd_data *amd, mu_off_t size) | ||
1029 | { | ||
1030 | FILE *fp; | ||
1031 | int rc; | ||
1032 | char *name = make_size_file_name (amd); | ||
1033 | if (!name) | ||
1034 | return 1; | ||
1035 | fp = fopen (name, "w"); | ||
1036 | if (fp) | ||
1037 | { | ||
1038 | fprintf (fp, "%lu", (unsigned long) size); | ||
1039 | fclose (fp); | ||
1040 | rc = 0; | ||
1041 | } | ||
1042 | else | ||
1043 | rc = 1; | ||
1044 | free (name); | ||
1045 | return rc; | ||
1046 | } | ||
1047 | |||
1048 | static int | ||
1049 | compute_mailbox_size (struct _amd_data *amd, const char *name, mu_off_t *psize) | ||
1050 | { | 1149 | { |
1051 | DIR *dir; | 1150 | DIR *dir; |
1052 | struct dirent *entry; | 1151 | struct dirent *entry; |
... | @@ -1099,7 +1198,7 @@ compute_mailbox_size (struct _amd_data *amd, const char *name, mu_off_t *psize) | ... | @@ -1099,7 +1198,7 @@ compute_mailbox_size (struct _amd_data *amd, const char *name, mu_off_t *psize) |
1099 | if (S_ISREG (sb.st_mode)) | 1198 | if (S_ISREG (sb.st_mode)) |
1100 | *psize += sb.st_size; | 1199 | *psize += sb.st_size; |
1101 | else if (S_ISDIR (sb.st_mode)) | 1200 | else if (S_ISDIR (sb.st_mode)) |
1102 | compute_mailbox_size (amd, buf, psize); | 1201 | _compute_mailbox_size_recursive (amd, buf, psize); |
1103 | } | 1202 | } |
1104 | /* FIXME: else? */ | 1203 | /* FIXME: else? */ |
1105 | break; | 1204 | break; |
... | @@ -1113,6 +1212,20 @@ compute_mailbox_size (struct _amd_data *amd, const char *name, mu_off_t *psize) | ... | @@ -1113,6 +1212,20 @@ compute_mailbox_size (struct _amd_data *amd, const char *name, mu_off_t *psize) |
1113 | } | 1212 | } |
1114 | 1213 | ||
1115 | static int | 1214 | static int |
1215 | compute_mailbox_size (struct _amd_data *amd, mu_off_t *psize) | ||
1216 | { | ||
1217 | mu_off_t size = 0; | ||
1218 | int rc = _compute_mailbox_size_recursive (amd, amd->name, &size); | ||
1219 | if (rc == 0) | ||
1220 | { | ||
1221 | rc = _amd_prop_store_off (amd, _MU_AMD_PROP_SIZE, size); | ||
1222 | if (rc == 0 && psize) | ||
1223 | *psize = size; | ||
1224 | } | ||
1225 | return rc; | ||
1226 | } | ||
1227 | |||
1228 | static int | ||
1116 | amd_remove_mbox (mu_mailbox_t mailbox) | 1229 | amd_remove_mbox (mu_mailbox_t mailbox) |
1117 | { | 1230 | { |
1118 | int rc; | 1231 | int rc; |
... | @@ -1123,11 +1236,22 @@ amd_remove_mbox (mu_mailbox_t mailbox) | ... | @@ -1123,11 +1236,22 @@ amd_remove_mbox (mu_mailbox_t mailbox) |
1123 | rc = amd->remove (amd); | 1236 | rc = amd->remove (amd); |
1124 | if (rc == 0) | 1237 | if (rc == 0) |
1125 | { | 1238 | { |
1126 | char *name = make_size_file_name (amd); | 1239 | char *name; |
1240 | |||
1241 | name = mu_make_file_name (amd->name, _MU_AMD_SIZE_FILE_NAME); | ||
1127 | if (!name) | 1242 | if (!name) |
1128 | return ENOMEM; | 1243 | return ENOMEM; |
1129 | if (unlink (name) && errno != ENOENT) | 1244 | if (unlink (name) && errno != ENOENT) |
1130 | rc = errno; | 1245 | rc = errno; |
1246 | else | ||
1247 | { | ||
1248 | free (name); | ||
1249 | name = mu_make_file_name (amd->name, _MU_AMD_PROP_FILE_NAME); | ||
1250 | if (!name) | ||
1251 | return ENOMEM; | ||
1252 | if (unlink (name) && errno != ENOENT) | ||
1253 | rc = errno; | ||
1254 | } | ||
1131 | free (name); | 1255 | free (name); |
1132 | } | 1256 | } |
1133 | 1257 | ||
... | @@ -1147,6 +1271,55 @@ amd_remove_mbox (mu_mailbox_t mailbox) | ... | @@ -1147,6 +1271,55 @@ amd_remove_mbox (mu_mailbox_t mailbox) |
1147 | } | 1271 | } |
1148 | 1272 | ||
1149 | static int | 1273 | static int |
1274 | _amd_update_message (struct _amd_data *amd, struct _amd_message *mhm, | ||
1275 | int expunge, int *upd) | ||
1276 | { | ||
1277 | int flg, rc; | ||
1278 | |||
1279 | if (mhm->message) | ||
1280 | flg = mu_message_is_modified (mhm->message); | ||
1281 | else if (mhm->attr_flags & MU_ATTRIBUTE_MODIFIED) | ||
1282 | flg = MU_MSG_ATTRIBUTE_MODIFIED; | ||
1283 | |||
1284 | if (!flg) | ||
1285 | return 0; | ||
1286 | |||
1287 | if (flg == MU_MSG_ATTRIBUTE_MODIFIED && amd->chattr_msg) | ||
1288 | { | ||
1289 | rc = amd->chattr_msg (mhm, expunge); | ||
1290 | if (rc) | ||
1291 | { | ||
1292 | mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR, | ||
1293 | ("_amd_update_message: chattr_msg failed: %s", | ||
1294 | mu_strerror (rc))); | ||
1295 | return rc; | ||
1296 | } | ||
1297 | } | ||
1298 | else | ||
1299 | { | ||
1300 | rc = _amd_attach_message (amd->mailbox, mhm, NULL); | ||
1301 | if (rc) | ||
1302 | { | ||
1303 | mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR, | ||
1304 | ("_amd_update_message: _amd_attach_message failed: %s", | ||
1305 | mu_strerror (rc))); | ||
1306 | return rc; | ||
1307 | } | ||
1308 | |||
1309 | rc = _amd_message_save (amd, mhm, expunge); | ||
1310 | if (rc) | ||
1311 | { | ||
1312 | mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR, | ||
1313 | ("_amd_update_message: _amd_message_save failed: %s", | ||
1314 | mu_strerror (rc))); | ||
1315 | return rc; | ||
1316 | } | ||
1317 | } | ||
1318 | *upd = 1; | ||
1319 | return rc; | ||
1320 | } | ||
1321 | |||
1322 | static int | ||
1150 | amd_expunge (mu_mailbox_t mailbox) | 1323 | amd_expunge (mu_mailbox_t mailbox) |
1151 | { | 1324 | { |
1152 | struct _amd_data *amd = mailbox->data; | 1325 | struct _amd_data *amd = mailbox->data; |
... | @@ -1232,13 +1405,7 @@ amd_expunge (mu_mailbox_t mailbox) | ... | @@ -1232,13 +1405,7 @@ amd_expunge (mu_mailbox_t mailbox) |
1232 | } | 1405 | } |
1233 | else | 1406 | else |
1234 | { | 1407 | { |
1235 | if ((mhm->attr_flags & MU_ATTRIBUTE_MODIFIED) | 1408 | _amd_update_message (amd, mhm, 1, &updated);/*FIXME: Error checking*/ |
1236 | || (mhm->message && mu_message_is_modified (mhm->message))) | ||
1237 | { | ||
1238 | _amd_attach_message (mailbox, mhm, NULL); | ||
1239 | _amd_message_save (amd, mhm, 1); | ||
1240 | updated = 1; | ||
1241 | } | ||
1242 | } | 1409 | } |
1243 | } | 1410 | } |
1244 | 1411 | ||
... | @@ -1263,10 +1430,7 @@ amd_expunge (mu_mailbox_t mailbox) | ... | @@ -1263,10 +1430,7 @@ amd_expunge (mu_mailbox_t mailbox) |
1263 | 1430 | ||
1264 | if (updated && !amd->mailbox_size) | 1431 | if (updated && !amd->mailbox_size) |
1265 | { | 1432 | { |
1266 | mu_off_t size = 0; | 1433 | compute_mailbox_size (amd, NULL); |
1267 | int rc = compute_mailbox_size (amd, amd->name, &size); | ||
1268 | if (rc == 0) | ||
1269 | write_size_file (amd, size); | ||
1270 | } | 1434 | } |
1271 | return 0; | 1435 | return 0; |
1272 | } | 1436 | } |
... | @@ -1297,22 +1461,12 @@ amd_sync (mu_mailbox_t mailbox) | ... | @@ -1297,22 +1461,12 @@ amd_sync (mu_mailbox_t mailbox) |
1297 | for ( ; i < amd->msg_count; i++) | 1461 | for ( ; i < amd->msg_count; i++) |
1298 | { | 1462 | { |
1299 | mhm = amd->msg_array[i]; | 1463 | mhm = amd->msg_array[i]; |
1300 | 1464 | _amd_update_message (amd, mhm, 0, &updated); | |
1301 | if ((mhm->attr_flags & MU_ATTRIBUTE_MODIFIED) | ||
1302 | || (mhm->message && mu_message_is_modified (mhm->message))) | ||
1303 | { | ||
1304 | _amd_attach_message (mailbox, mhm, NULL); | ||
1305 | _amd_message_save (amd, mhm, 0); | ||
1306 | updated = 1; | ||
1307 | } | ||
1308 | } | 1465 | } |
1309 | 1466 | ||
1310 | if (updated && !amd->mailbox_size) | 1467 | if (updated && !amd->mailbox_size) |
1311 | { | 1468 | { |
1312 | mu_off_t size = 0; | 1469 | compute_mailbox_size (amd, NULL); |
1313 | int rc = compute_mailbox_size (amd, amd->name, &size); | ||
1314 | if (rc == 0) | ||
1315 | write_size_file (amd, size); | ||
1316 | } | 1470 | } |
1317 | 1471 | ||
1318 | return 0; | 1472 | return 0; |
... | @@ -1328,13 +1482,12 @@ amd_uidvalidity (mu_mailbox_t mailbox, unsigned long *puidvalidity) | ... | @@ -1328,13 +1482,12 @@ amd_uidvalidity (mu_mailbox_t mailbox, unsigned long *puidvalidity) |
1328 | /* If we did not start a scanning yet do it now. */ | 1482 | /* If we did not start a scanning yet do it now. */ |
1329 | if (amd->msg_count == 0) | 1483 | if (amd->msg_count == 0) |
1330 | { | 1484 | { |
1331 | status = amd->scan0 (mailbox, 1, NULL, 0); | 1485 | status = _amd_scan0 (amd, 1, NULL, 0); |
1332 | if (status != 0) | 1486 | if (status != 0) |
1333 | return status; | 1487 | return status; |
1334 | } | 1488 | } |
1335 | if (puidvalidity) | 1489 | |
1336 | *puidvalidity = amd->uidvalidity; | 1490 | return _amd_prop_fetch_ulong (amd, _MU_AMD_PROP_UIDVALIDITY, puidvalidity); |
1337 | return 0; | ||
1338 | } | 1491 | } |
1339 | 1492 | ||
1340 | static int | 1493 | static int |
... | @@ -1351,7 +1504,7 @@ amd_uidnext (mu_mailbox_t mailbox, size_t *puidnext) | ... | @@ -1351,7 +1504,7 @@ amd_uidnext (mu_mailbox_t mailbox, size_t *puidnext) |
1351 | /* If we did not start a scanning yet do it now. */ | 1504 | /* If we did not start a scanning yet do it now. */ |
1352 | if (amd->msg_count == 0) | 1505 | if (amd->msg_count == 0) |
1353 | { | 1506 | { |
1354 | status = amd->scan0 (mailbox, 1, NULL, 0); | 1507 | status = _amd_scan0 (amd, 1, NULL, 0); |
1355 | if (status != 0) | 1508 | if (status != 0) |
1356 | return status; | 1509 | return status; |
1357 | } | 1510 | } |
... | @@ -1458,6 +1611,8 @@ amd_scan_message (struct _amd_message *mhm) | ... | @@ -1458,6 +1611,8 @@ amd_scan_message (struct _amd_message *mhm) |
1458 | size_t body_start = 0; | 1611 | size_t body_start = 0; |
1459 | struct stat st; | 1612 | struct stat st; |
1460 | char *msg_name; | 1613 | char *msg_name; |
1614 | struct _amd_data *amd = mhm->amd; | ||
1615 | int amd_capa = amd->capabilities; | ||
1461 | 1616 | ||
1462 | /* Check if the message was modified after the last scan */ | 1617 | /* Check if the message was modified after the last scan */ |
1463 | status = mhm->amd->cur_msg_file_name (mhm, &msg_name); | 1618 | status = mhm->amd->cur_msg_file_name (mhm, &msg_name); |
... | @@ -1498,17 +1653,25 @@ amd_scan_message (struct _amd_message *mhm) | ... | @@ -1498,17 +1653,25 @@ amd_scan_message (struct _amd_message *mhm) |
1498 | hlines++; | 1653 | hlines++; |
1499 | 1654 | ||
1500 | /* Process particular attributes */ | 1655 | /* Process particular attributes */ |
1501 | if (mu_c_strncasecmp (buf, "status:", 7) == 0) | 1656 | if (!(amd_capa & MU_AMD_STATUS) && |
1657 | mu_c_strncasecmp (buf, "status:", 7) == 0) | ||
1502 | { | 1658 | { |
1503 | int deleted = mhm->attr_flags & MU_ATTRIBUTE_DELETED; | 1659 | int deleted = mhm->attr_flags & MU_ATTRIBUTE_DELETED; |
1504 | mu_string_to_flags (buf, &mhm->attr_flags); | 1660 | mu_string_to_flags (buf, &mhm->attr_flags); |
1505 | mhm->attr_flags |= deleted; | 1661 | mhm->attr_flags |= deleted; |
1506 | } | 1662 | } |
1507 | else if (mu_c_strncasecmp (buf, "x-imapbase:", 11) == 0) | 1663 | else if (!(amd_capa & MU_AMD_IMAPBASE) && |
1664 | mu_c_strncasecmp (buf, "x-imapbase:", 11) == 0) | ||
1665 | { | ||
1666 | if (_amd_prop_fetch_ulong (amd, _MU_AMD_PROP_UIDVALIDITY, | ||
1667 | NULL)) | ||
1508 | { | 1668 | { |
1509 | char *p; | 1669 | char *p; |
1510 | mhm->amd->uidvalidity = strtoul (buf + 11, &p, 10); | 1670 | unsigned long uidval = strtoul (buf + 11, &p, 10); |
1511 | /* second number is next uid. Ignored */ | 1671 | /* The next number is next uid. Ignored */ |
1672 | _amd_prop_store_off (amd, _MU_AMD_PROP_UIDVALIDITY, | ||
1673 | uidval); | ||
1674 | } | ||
1512 | } | 1675 | } |
1513 | } | 1676 | } |
1514 | else | 1677 | else |
... | @@ -1545,7 +1708,7 @@ amd_scan (mu_mailbox_t mailbox, size_t msgno, size_t *pcount) | ... | @@ -1545,7 +1708,7 @@ amd_scan (mu_mailbox_t mailbox, size_t msgno, size_t *pcount) |
1545 | struct _amd_data *amd = mailbox->data; | 1708 | struct _amd_data *amd = mailbox->data; |
1546 | 1709 | ||
1547 | if (! amd_is_updated (mailbox)) | 1710 | if (! amd_is_updated (mailbox)) |
1548 | return amd->scan0 (mailbox, msgno, pcount, 1); | 1711 | return _amd_scan0 (amd, msgno, pcount, 1); |
1549 | 1712 | ||
1550 | if (pcount) | 1713 | if (pcount) |
1551 | *pcount = amd->msg_count; | 1714 | *pcount = amd->msg_count; |
... | @@ -1573,14 +1736,8 @@ amd_get_size (mu_mailbox_t mailbox, mu_off_t *psize) | ... | @@ -1573,14 +1736,8 @@ amd_get_size (mu_mailbox_t mailbox, mu_off_t *psize) |
1573 | struct _amd_data *amd = mailbox->data; | 1736 | struct _amd_data *amd = mailbox->data; |
1574 | if (amd->mailbox_size) | 1737 | if (amd->mailbox_size) |
1575 | return amd->mailbox_size (mailbox, psize); | 1738 | return amd->mailbox_size (mailbox, psize); |
1576 | *psize = 0; | 1739 | if (_amd_prop_fetch_off (amd, _MU_AMD_PROP_SIZE, psize)) |
1577 | if (read_size_file (amd, psize)) | 1740 | return compute_mailbox_size (amd, psize); |
1578 | { | ||
1579 | int rc = compute_mailbox_size (amd, amd->name, psize); | ||
1580 | if (rc == 0) | ||
1581 | write_size_file (amd, *psize); | ||
1582 | return rc; | ||
1583 | } | ||
1584 | return 0; | 1741 | return 0; |
1585 | } | 1742 | } |
1586 | 1743 | ... | ... |
... | @@ -667,10 +667,14 @@ mu_message_is_modified (mu_message_t msg) | ... | @@ -667,10 +667,14 @@ mu_message_is_modified (mu_message_t msg) |
667 | int mod = 0; | 667 | int mod = 0; |
668 | if (msg) | 668 | if (msg) |
669 | { | 669 | { |
670 | mod |= mu_header_is_modified (msg->header); | 670 | if (mu_header_is_modified (msg->header)) |
671 | mod |= mu_attribute_is_modified (msg->attribute); | 671 | mod |= MU_MSG_HEADER_MODIFIED; |
672 | mod |= mu_body_is_modified (msg->body); | 672 | if (mu_attribute_is_modified (msg->attribute)) |
673 | mod |= msg->flags; | 673 | mod |= MU_MSG_ATTRIBUTE_MODIFIED; |
674 | if (mu_body_is_modified (msg->body)) | ||
675 | mod |= MU_MSG_BODY_MODIFIED; | ||
676 | if (msg->flags & MESSAGE_MODIFIED) | ||
677 | mod |= MU_MSG_BODY_MODIFIED | MU_MSG_HEADER_MODIFIED; | ||
674 | } | 678 | } |
675 | return mod; | 679 | return mod; |
676 | } | 680 | } | ... | ... |
... | @@ -45,7 +45,7 @@ mu_property_create_init (mu_property_t *pprop, | ... | @@ -45,7 +45,7 @@ mu_property_create_init (mu_property_t *pprop, |
45 | mu_property_set_init (prop, initfun, initdata); | 45 | mu_property_set_init (prop, initfun, initdata); |
46 | *pprop = prop; | 46 | *pprop = prop; |
47 | } | 47 | } |
48 | return 0; | 48 | return rc; |
49 | } | 49 | } |
50 | 50 | ||
51 | int | 51 | int | ... | ... |
... | @@ -92,7 +92,8 @@ _maildir_list_p (mu_record_t record, const char *name, int flags MU_ARG_UNUSED) | ... | @@ -92,7 +92,8 @@ _maildir_list_p (mu_record_t record, const char *name, int flags MU_ARG_UNUSED) |
92 | return strcmp (name, TMPSUF) | 92 | return strcmp (name, TMPSUF) |
93 | && strcmp (name, CURSUF) | 93 | && strcmp (name, CURSUF) |
94 | && strcmp (name, NEWSUF) | 94 | && strcmp (name, NEWSUF) |
95 | && strcmp (name, MU_AMD_SIZE_FILE_NAME); | 95 | && !((strlen (name) > 3) && |
96 | (memcmp (name, ".mh", 3) == 0 || memcmp (name, ".mu", 3) == 0)); | ||
96 | } | 97 | } |
97 | 98 | ||
98 | static struct _mu_record _maildir_record = | 99 | static struct _mu_record _maildir_record = | ... | ... |
... | @@ -84,19 +84,24 @@ struct _maildir_message | ... | @@ -84,19 +84,24 @@ struct _maildir_message |
84 | 84 | ||
85 | 85 | ||
86 | /* Attribute handling. | 86 | /* Attribute handling. |
87 | FIXME: P (Passed), D (Draft) and F (Flagged) are not handled */ | 87 | FIXME: P (Passed) is not handled */ |
88 | 88 | ||
89 | static struct info_map { | 89 | static struct info_map { |
90 | char letter; | 90 | char letter; |
91 | int flag; | 91 | int flag; |
92 | } info_map[] = { | 92 | } info_map[] = { |
93 | { 'D', MU_ATTRIBUTE_DRAFT }, | ||
94 | { 'F', MU_ATTRIBUTE_FLAGGED }, | ||
95 | { 'P', 0 }, /* (passed): the user has resent/forwarded/bounced this | ||
96 | message to someone else. */ | ||
93 | { 'R', MU_ATTRIBUTE_READ }, | 97 | { 'R', MU_ATTRIBUTE_READ }, |
94 | { 'S', MU_ATTRIBUTE_SEEN }, | 98 | { 'S', MU_ATTRIBUTE_SEEN }, |
95 | { 'T', MU_ATTRIBUTE_DELETED }, | 99 | { 'T', MU_ATTRIBUTE_DELETED }, |
100 | { 'a', MU_ATTRIBUTE_ANSWERED }, | ||
96 | }; | 101 | }; |
97 | #define info_map_size (sizeof (info_map) / sizeof (info_map[0])) | 102 | #define info_map_size (sizeof (info_map) / sizeof (info_map[0])) |
98 | 103 | ||
99 | /* NOTE: BUF must be at least 7 bytes long */ | 104 | /* NOTE: BUF must be at least info_map_size bytes long */ |
100 | static int | 105 | static int |
101 | flags_to_info (int flags, char *buf) | 106 | flags_to_info (int flags, char *buf) |
102 | { | 107 | { |
... | @@ -254,7 +259,7 @@ maildir_mkfilename (const char *directory, const char *suffix, const char *name) | ... | @@ -254,7 +259,7 @@ maildir_mkfilename (const char *directory, const char *suffix, const char *name) |
254 | static char * | 259 | static char * |
255 | mk_info_filename (char *directory, char *suffix, char *name, int flags) | 260 | mk_info_filename (char *directory, char *suffix, char *name, int flags) |
256 | { | 261 | { |
257 | char fbuf[9]; | 262 | char fbuf[info_map_size + 1]; |
258 | char *tmp; | 263 | char *tmp; |
259 | int namelen; | 264 | int namelen; |
260 | size_t size; | 265 | size_t size; |
... | @@ -691,23 +696,6 @@ maildir_scan0 (mu_mailbox_t mailbox, size_t msgno MU_ARG_UNUSED, | ... | @@ -691,23 +696,6 @@ maildir_scan0 (mu_mailbox_t mailbox, size_t msgno MU_ARG_UNUSED, |
691 | if (pcount) | 696 | if (pcount) |
692 | *pcount = amd->msg_count; | 697 | *pcount = amd->msg_count; |
693 | 698 | ||
694 | /* Reset the uidvalidity. */ | ||
695 | if (amd->msg_count > 0) | ||
696 | { | ||
697 | if (amd->uidvalidity == 0) | ||
698 | { | ||
699 | amd->uidvalidity = (unsigned long) time (NULL); | ||
700 | /* FIXME amd->uidnext = amd->msg_count + 1;*/ | ||
701 | /* Tell that we have been modified for expunging. */ | ||
702 | if (amd->msg_count) | ||
703 | { | ||
704 | amd_message_stream_open (amd->msg_array[0]); | ||
705 | amd_message_stream_close (amd->msg_array[0]); | ||
706 | amd->msg_array[0]->attr_flags |= MU_ATTRIBUTE_MODIFIED; | ||
707 | } | ||
708 | } | ||
709 | } | ||
710 | |||
711 | /* Clean up the things */ | 699 | /* Clean up the things */ |
712 | amd_cleanup (mailbox); | 700 | amd_cleanup (mailbox); |
713 | return status; | 701 | return status; |
... | @@ -774,6 +762,42 @@ maildir_remove (struct _amd_data *amd) | ... | @@ -774,6 +762,42 @@ maildir_remove (struct _amd_data *amd) |
774 | } | 762 | } |
775 | 763 | ||
776 | 764 | ||
765 | static int | ||
766 | maildir_chattr_msg (struct _amd_message *amsg, int expunge) | ||
767 | { | ||
768 | struct _maildir_message *mp = (struct _maildir_message *) amsg; | ||
769 | struct _amd_data *amd = amsg->amd; | ||
770 | int rc; | ||
771 | char *new_name; | ||
772 | |||
773 | rc = amd->new_msg_file_name (amsg, amsg->attr_flags, expunge, &new_name); | ||
774 | if (rc) | ||
775 | return rc; | ||
776 | if (!new_name) | ||
777 | { | ||
778 | if (unlink (mp->file_name)) | ||
779 | rc = errno; | ||
780 | } | ||
781 | else | ||
782 | { | ||
783 | char *cur_name; | ||
784 | |||
785 | rc = maildir_cur_message_name (amsg, &cur_name); | ||
786 | if (rc) | ||
787 | { | ||
788 | free (new_name); | ||
789 | return rc; | ||
790 | } | ||
791 | if (rename (cur_name, new_name)) | ||
792 | rc = errno; | ||
793 | free (cur_name); | ||
794 | } | ||
795 | |||
796 | free (new_name); | ||
797 | return rc; | ||
798 | } | ||
799 | |||
800 | |||
777 | int | 801 | int |
778 | _mailbox_maildir_init (mu_mailbox_t mailbox) | 802 | _mailbox_maildir_init (mu_mailbox_t mailbox) |
779 | { | 803 | { |
... | @@ -797,6 +821,8 @@ _mailbox_maildir_init (mu_mailbox_t mailbox) | ... | @@ -797,6 +821,8 @@ _mailbox_maildir_init (mu_mailbox_t mailbox) |
797 | amd->message_uid = maildir_message_uid; | 821 | amd->message_uid = maildir_message_uid; |
798 | amd->next_uid = maildir_next_uid; | 822 | amd->next_uid = maildir_next_uid; |
799 | amd->remove = maildir_remove; | 823 | amd->remove = maildir_remove; |
824 | amd->chattr_msg = maildir_chattr_msg; | ||
825 | amd->capabilities = MU_AMD_STATUS; | ||
800 | 826 | ||
801 | /* Set our properties. */ | 827 | /* Set our properties. */ |
802 | { | 828 | { | ... | ... |
... | @@ -121,11 +121,9 @@ _mh_is_scheme (mu_record_t record, mu_url_t url, int flags) | ... | @@ -121,11 +121,9 @@ _mh_is_scheme (mu_record_t record, mu_url_t url, int flags) |
121 | static int | 121 | static int |
122 | _mh_list_p (mu_record_t record, const char *name, int flags MU_ARG_UNUSED) | 122 | _mh_list_p (mu_record_t record, const char *name, int flags MU_ARG_UNUSED) |
123 | { | 123 | { |
124 | int len; | 124 | if (name[0] == ',' || |
125 | 125 | ((strlen (name) > 3) && | |
126 | if (strcmp (name, MU_AMD_SIZE_FILE_NAME) == 0 | 126 | (memcmp (name, ".mh", 3) == 0 || memcmp (name, ".mu", 3) == 0))) |
127 | || name[0] == ',' | ||
128 | || (((len = strlen (name)) > 3) && memcmp (name, ".mh", 3) == 0)) | ||
129 | return 0; | 127 | return 0; |
130 | 128 | ||
131 | for (; *name; name++) | 129 | for (; *name; name++) | ... | ... |
... | @@ -278,22 +278,6 @@ mh_scan0 (mu_mailbox_t mailbox, size_t msgno MU_ARG_UNUSED, size_t *pcount, | ... | @@ -278,22 +278,6 @@ mh_scan0 (mu_mailbox_t mailbox, size_t msgno MU_ARG_UNUSED, size_t *pcount, |
278 | 278 | ||
279 | if (pcount) | 279 | if (pcount) |
280 | *pcount = amd->msg_count; | 280 | *pcount = amd->msg_count; |
281 | |||
282 | /* Reset the uidvalidity. */ | ||
283 | if (amd->msg_count > 0) | ||
284 | { | ||
285 | if (amd->uidvalidity == 0) | ||
286 | { | ||
287 | amd->uidvalidity = (unsigned long)time (NULL); | ||
288 | /* Tell that we have been modified for expunging. */ | ||
289 | if (amd->msg_count) | ||
290 | { | ||
291 | amd_message_stream_open (amd->msg_array[0]); | ||
292 | amd_message_stream_close (amd->msg_array[0]); | ||
293 | amd->msg_array[0]->attr_flags |= MU_ATTRIBUTE_MODIFIED; | ||
294 | } | ||
295 | } | ||
296 | } | ||
297 | } | 281 | } |
298 | /* Clean up the things */ | 282 | /* Clean up the things */ |
299 | 283 | ... | ... |
... | @@ -87,7 +87,7 @@ do | ... | @@ -87,7 +87,7 @@ do |
87 | mv Mail/inbox/$i Mail/inbox/${i}0 | 87 | mv Mail/inbox/$i Mail/inbox/${i}0 |
88 | done | 88 | done |
89 | folder -pack || exit $? | 89 | folder -pack || exit $? |
90 | find Mail/inbox | sort | 90 | find Mail/inbox -not -name '.mu-prop' | sort |
91 | ], | 91 | ], |
92 | [0], | 92 | [0], |
93 | [Mail/inbox | 93 | [Mail/inbox |
... | @@ -105,7 +105,7 @@ do | ... | @@ -105,7 +105,7 @@ do |
105 | mv Mail/inbox/$i Mail/inbox/${i}0 | 105 | mv Mail/inbox/$i Mail/inbox/${i}0 |
106 | done | 106 | done |
107 | folder --pack=1 || exit $? | 107 | folder --pack=1 || exit $? |
108 | find Mail/inbox | sort | 108 | find Mail/inbox -not -name '.mu-prop' | sort |
109 | ], | 109 | ], |
110 | [0], | 110 | [0], |
111 | [Mail/inbox | 111 | [Mail/inbox | ... | ... |
-
Please register or sign in to post a comment