Bugfixes in AMD code.
* libproto/include/amd.h (new_msg_file_name): Add an argument indicating whether an actual expunsion is going to take place, as opposed to saving message flags. * libproto/maildir/mbox.c (maildir_new_message_name): Sync with above changes. * libproto/mh/mbox.c (_mh_new_message_name): Likewise. * mailbox/amd.c (_amd_message_save): Handle unlink requests (new_msg_file_name returning NULL name). This avoids creating temp files. (amd_expunge): Remove messages that have had MU_ATTRIBUTE_DELETED on mailbox open, if the underlying mailbox implementation allows that.
Showing
4 changed files
with
42 additions
and
18 deletions
... | @@ -72,7 +72,7 @@ struct _amd_data | ... | @@ -72,7 +72,7 @@ struct _amd_data |
72 | const mu_message_t); | 72 | const mu_message_t); |
73 | void (*msg_free) (struct _amd_message *); | 73 | void (*msg_free) (struct _amd_message *); |
74 | int (*cur_msg_file_name) (struct _amd_message *, char **); | 74 | int (*cur_msg_file_name) (struct _amd_message *, char **); |
75 | int (*new_msg_file_name) (struct _amd_message *, int attr_flags, char **); | 75 | int (*new_msg_file_name) (struct _amd_message *, int, int, char **); |
76 | int (*scan0) (mu_mailbox_t mailbox, size_t msgno, size_t *pcount, | 76 | int (*scan0) (mu_mailbox_t mailbox, size_t msgno, size_t *pcount, |
77 | int do_notify); | 77 | int do_notify); |
78 | int (*mailbox_size) (mu_mailbox_t mailbox, mu_off_t *psize); | 78 | int (*mailbox_size) (mu_mailbox_t mailbox, mu_off_t *psize); | ... | ... |
... | @@ -342,14 +342,13 @@ maildir_cur_message_name (struct _amd_message *amsg, char **pname) | ... | @@ -342,14 +342,13 @@ maildir_cur_message_name (struct _amd_message *amsg, char **pname) |
342 | } | 342 | } |
343 | 343 | ||
344 | static int | 344 | static int |
345 | maildir_new_message_name (struct _amd_message *amsg, int flags, char **pname) | 345 | maildir_new_message_name (struct _amd_message *amsg, int flags, int expunge, |
346 | char **pname) | ||
346 | { | 347 | { |
347 | struct _maildir_message *msg = (struct _maildir_message *) amsg; | 348 | struct _maildir_message *msg = (struct _maildir_message *) amsg; |
348 | if (flags & MU_ATTRIBUTE_DELETED) | 349 | if (expunge && (flags & MU_ATTRIBUTE_DELETED)) |
349 | { | 350 | { |
350 | /* Force amd.c to unlink the file. | 351 | /* Force amd.c to unlink the file. */ |
351 | FIXME: We could also add a 'T' info to it. Should | ||
352 | we have an option deciding which approach to take? */ | ||
353 | *pname = NULL; | 352 | *pname = NULL; |
354 | } | 353 | } |
355 | else if (strcmp (msg->dir, CURSUF) == 0) | 354 | else if (strcmp (msg->dir, CURSUF) == 0) | ... | ... |
... | @@ -126,7 +126,9 @@ _mh_cur_message_name (struct _amd_message *amsg, char **pname) | ... | @@ -126,7 +126,9 @@ _mh_cur_message_name (struct _amd_message *amsg, char **pname) |
126 | /* Return newfilename for the message. | 126 | /* Return newfilename for the message. |
127 | NOTE: Allocates memory. */ | 127 | NOTE: Allocates memory. */ |
128 | static int | 128 | static int |
129 | _mh_new_message_name (struct _amd_message *amsg, int flags, char **pname) | 129 | _mh_new_message_name (struct _amd_message *amsg, int flags, |
130 | int expunge MU_ARG_UNUSED, | ||
131 | char **pname) | ||
130 | { | 132 | { |
131 | int status = 0; | 133 | int status = 0; |
132 | struct _mh_message *mhm = (struct _mh_message *) amsg; | 134 | struct _mh_message *mhm = (struct _mh_message *) amsg; | ... | ... |
... | @@ -600,7 +600,7 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm, | ... | @@ -600,7 +600,7 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm, |
600 | int expunge) | 600 | int expunge) |
601 | { | 601 | { |
602 | mu_stream_t stream = NULL; | 602 | mu_stream_t stream = NULL; |
603 | char *name = NULL, *buf = NULL, *msg_name; | 603 | char *name = NULL, *buf = NULL, *msg_name, *old_name; |
604 | size_t n, off = 0; | 604 | size_t n, off = 0; |
605 | size_t bsize; | 605 | size_t bsize; |
606 | size_t nlines, nbytes; | 606 | size_t nlines, nbytes; |
... | @@ -618,9 +618,27 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm, | ... | @@ -618,9 +618,27 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm, |
618 | if (status) | 618 | if (status) |
619 | return status; | 619 | return status; |
620 | 620 | ||
621 | status = amd->new_msg_file_name (mhm, mhm->attr_flags, expunge, &msg_name); | ||
622 | if (status) | ||
623 | return status; | ||
624 | if (!msg_name) | ||
625 | { | ||
626 | /* Unlink the original file */ | ||
627 | char *old_name; | ||
628 | status = amd->cur_msg_file_name (mhm, &old_name); | ||
629 | free (msg_name); | ||
630 | if (status == 0 && unlink (old_name)) | ||
631 | status = errno; | ||
632 | free (old_name); | ||
633 | return status; | ||
634 | } | ||
635 | |||
621 | fp = _amd_tempfile (mhm->amd, &name); | 636 | fp = _amd_tempfile (mhm->amd, &name); |
622 | if (!fp) | 637 | if (!fp) |
638 | { | ||
639 | free (msg_name); | ||
623 | return errno; | 640 | return errno; |
641 | } | ||
624 | 642 | ||
625 | /* Try to allocate large buffer */ | 643 | /* Try to allocate large buffer */ |
626 | for (; bsize > 1; bsize /= 2) | 644 | for (; bsize > 1; bsize /= 2) |
... | @@ -628,7 +646,12 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm, | ... | @@ -628,7 +646,12 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm, |
628 | break; | 646 | break; |
629 | 647 | ||
630 | if (!bsize) | 648 | if (!bsize) |
649 | { | ||
650 | unlink (name); | ||
651 | free (name); | ||
652 | free (msg_name); | ||
631 | return ENOMEM; | 653 | return ENOMEM; |
654 | } | ||
632 | 655 | ||
633 | /* Copy flags */ | 656 | /* Copy flags */ |
634 | mu_message_get_header (msg, &hdr); | 657 | mu_message_get_header (msg, &hdr); |
... | @@ -724,10 +747,6 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm, | ... | @@ -724,10 +747,6 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm, |
724 | free (buf); | 747 | free (buf); |
725 | fclose (fp); | 748 | fclose (fp); |
726 | 749 | ||
727 | status = amd->new_msg_file_name (mhm, mhm->attr_flags, &msg_name); | ||
728 | if (status == 0) | ||
729 | { | ||
730 | char *old_name; | ||
731 | status = amd->cur_msg_file_name (mhm, &old_name); | 750 | status = amd->cur_msg_file_name (mhm, &old_name); |
732 | if (status == 0) | 751 | if (status == 0) |
733 | { | 752 | { |
... | @@ -759,7 +778,6 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm, | ... | @@ -759,7 +778,6 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm, |
759 | mhm->orig_flags = mhm->attr_flags; | 778 | mhm->orig_flags = mhm->attr_flags; |
760 | } | 779 | } |
761 | free (msg_name); | 780 | free (msg_name); |
762 | } | ||
763 | free (name); | 781 | free (name); |
764 | 782 | ||
765 | return status; | 783 | return status; |
... | @@ -1065,8 +1083,6 @@ amd_expunge (mu_mailbox_t mailbox) | ... | @@ -1065,8 +1083,6 @@ amd_expunge (mu_mailbox_t mailbox) |
1065 | 1083 | ||
1066 | if (mhm->attr_flags & MU_ATTRIBUTE_DELETED) | 1084 | if (mhm->attr_flags & MU_ATTRIBUTE_DELETED) |
1067 | { | 1085 | { |
1068 | if (!(mhm->orig_flags & MU_ATTRIBUTE_DELETED)) | ||
1069 | { | ||
1070 | int rc; | 1086 | int rc; |
1071 | char *old_name; | 1087 | char *old_name; |
1072 | char *new_name; | 1088 | char *new_name; |
... | @@ -1074,7 +1090,8 @@ amd_expunge (mu_mailbox_t mailbox) | ... | @@ -1074,7 +1090,8 @@ amd_expunge (mu_mailbox_t mailbox) |
1074 | rc = amd->cur_msg_file_name (mhm, &old_name); | 1090 | rc = amd->cur_msg_file_name (mhm, &old_name); |
1075 | if (rc) | 1091 | if (rc) |
1076 | return rc; | 1092 | return rc; |
1077 | rc = amd->new_msg_file_name (mhm, mhm->attr_flags, &new_name); | 1093 | rc = amd->new_msg_file_name (mhm, mhm->attr_flags, 1, |
1094 | &new_name); | ||
1078 | if (rc) | 1095 | if (rc) |
1079 | { | 1096 | { |
1080 | free (old_name); | 1097 | free (old_name); |
... | @@ -1083,15 +1100,21 @@ amd_expunge (mu_mailbox_t mailbox) | ... | @@ -1083,15 +1100,21 @@ amd_expunge (mu_mailbox_t mailbox) |
1083 | 1100 | ||
1084 | if (new_name) | 1101 | if (new_name) |
1085 | { | 1102 | { |
1103 | /* FIXME: It may be a good idea to have a capability flag | ||
1104 | in struct _amd_data indicating that no actual removal | ||
1105 | is needed (e.g. for traditional MH). It will allow to | ||
1106 | bypass lots of no-op code here. */ | ||
1107 | if (strcmp (old_name, new_name)) | ||
1086 | /* Rename original message */ | 1108 | /* Rename original message */ |
1087 | rename (old_name, new_name); | 1109 | rename (old_name, new_name); |
1088 | free (new_name); | ||
1089 | } | 1110 | } |
1090 | else | 1111 | else |
1091 | /* Unlink original file */ | 1112 | /* Unlink original file */ |
1092 | unlink (old_name); | 1113 | unlink (old_name); |
1114 | |||
1093 | free (old_name); | 1115 | free (old_name); |
1094 | } | 1116 | free (new_name); |
1117 | |||
1095 | _amd_message_delete (amd, mhm); | 1118 | _amd_message_delete (amd, mhm); |
1096 | updated = 1; | 1119 | updated = 1; |
1097 | /* Do not increase i! */ | 1120 | /* Do not increase i! */ | ... | ... |
-
Please register or sign in to post a comment