Commit 5b3ac30a 5b3ac30a697287b6b72e3d7f717e19a159cae821 by Sergey Poznyakoff

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.
1 parent 47b3b9bc
...@@ -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! */
......