summaryrefslogtreecommitdiff
path: root/libmu_sieve/actions.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmu_sieve/actions.c')
-rw-r--r--libmu_sieve/actions.c108
1 files changed, 105 insertions, 3 deletions
diff --git a/libmu_sieve/actions.c b/libmu_sieve/actions.c
index 344924fb1..4ceb49c96 100644
--- a/libmu_sieve/actions.c
+++ b/libmu_sieve/actions.c
@@ -1,5 +1,5 @@
/* GNU Mailutils -- a suite of utilities for electronic mail
- Copyright (C) 1999-2019 Free Software Foundation, Inc.
+ Copyright (C) 1999-2024 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -73,6 +73,104 @@ sieve_action_discard (mu_sieve_machine_t mach)
return 0;
}
+static void
+sieve_mailbox_deallocator (void *ptr)
+{
+ if (ptr)
+ {
+ mu_mailbox_t mbox = ptr;
+ mu_mailbox_close (mbox);
+ mu_mailbox_destroy (&mbox);
+ }
+}
+
+static int
+sieve_mailbox_open (mu_sieve_machine_t mach, char const *filename, int flags,
+ mu_mailbox_t *ret_mbox)
+{
+ int rc;
+ mu_mailbox_t mbox;
+
+ if ((rc = mu_mailbox_create_default (&mbox, filename)))
+ {
+ mu_debug (MU_DEBCAT_MESSAGE, MU_DEBUG_ERROR,
+ ("mu_mailbox_create_default (%s) failed: %s\n",
+ filename,
+ mu_strerror (rc)));
+ return rc;
+ }
+
+ flags |= MU_STREAM_APPEND | MU_STREAM_CREAT;
+ if ((rc = mu_mailbox_open (mbox, flags)) != 0)
+ {
+ mu_debug (MU_DEBCAT_MESSAGE, MU_DEBUG_ERROR,
+ ("mu_mailbox_open (%s) failed: %s", filename,
+ mu_strerror (rc)));
+ if (rc == ENFILE || rc == EMFILE)
+ {
+ if (mu_assoc_pop (mach->mailboxes, NULL, NULL) == 0)
+ {
+ if ((rc = mu_mailbox_open (mbox, flags)) == 0)
+ goto ret;
+ else
+ {
+ mu_debug (MU_DEBCAT_MESSAGE, MU_DEBUG_ERROR,
+ ("second mu_mailbox_open (%s) failed: %s", filename,
+ mu_strerror (rc)));
+ }
+ }
+ }
+ mu_mailbox_destroy (&mbox);
+ return rc;
+ }
+ ret:
+ *ret_mbox = mbox;
+ return 0;
+}
+
+static int
+sieve_get_mailbox (mu_sieve_machine_t mach, char const *filename, int flags,
+ mu_mailbox_t *ret_mbox)
+{
+ int rc;
+ mu_mailbox_t mbox, *mbox_ptr;
+
+ if (!mach->mailboxes)
+ {
+ rc = mu_assoc_create (&mach->mailboxes, MU_ASSOC_LRU);
+ if (rc)
+ {
+ mu_sieve_error (mach, _("failed to create mailbox storage table: %s"),
+ mu_strerror (rc));
+ mu_sieve_abort (mach);
+ }
+ mu_assoc_set_destroy_item (mach->mailboxes, sieve_mailbox_deallocator);
+
+ }
+
+ switch (rc = mu_assoc_install_ref (mach->mailboxes, filename, &mbox_ptr))
+ {
+ case 0:
+ if ((rc = sieve_mailbox_open (mach, filename, flags, &mbox)) != 0)
+ mu_assoc_shift (mach->mailboxes, NULL, NULL);
+ else
+ *mbox_ptr = mbox;
+ break;
+
+ case MU_ERR_EXISTS:
+ mbox = *mbox_ptr;
+ rc = 0;
+ break;
+
+ default:
+ mu_sieve_error (mach, _("failed to retrieve mailbox %s: %s"),
+ filename, mu_strerror (rc));
+ mu_sieve_abort (mach);
+ }
+ *ret_mbox = mbox;
+ return rc;
+}
+
static int
sieve_action_fileinto (mu_sieve_machine_t mach)
{
@@ -80,7 +178,8 @@ sieve_action_fileinto (mu_sieve_machine_t mach)
int mbflags = 0;
char *filename;
char *perms;
-
+ mu_mailbox_t mbox;
+
mu_sieve_get_arg (mach, 0, SVT_STRING, &filename);
if (mu_sieve_get_tag (mach, "permissions", SVT_STRING, &perms))
@@ -100,8 +199,11 @@ sieve_action_fileinto (mu_sieve_machine_t mach)
if (mu_sieve_is_dry_run (mach))
return 0;
- rc = mu_message_save_to_mailbox (mach->msg, filename, mbflags);
+ rc = sieve_get_mailbox (mach, filename, mbflags, &mbox);
if (rc)
+ return rc;
+
+ if ((rc = mu_mailbox_append_message (mbox, mach->msg)) != 0)
mu_sieve_error (mach, _("cannot save to mailbox: %s"),
mu_strerror (rc));
else

Return to:

Send suggestions and report system problems to the System administrator.