/* 6.3.6. SUBSCRIBE Command Arguments: mailbox Responses: no specific responses for this command Result: OK - subscribe completed NO - subscribe failure: can't subscribe to that name BAD - command unknown or arguments invalid */ int imap4d_subscribe (struct imap4d_session *session, struct imap4d_command *command, imap4d_tokbuf_t tok) { int rc; char *name; mu_property_t prop; if (imap4d_tokbuf_argc (tok) != 3) return io_completion_response (command, RESP_BAD, "Invalid arguments"); name = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1); prop = open_subscription (); if (!prop) return io_completion_response (command, RESP_NO, "Cannot subscribe"); rc = mu_property_set_value (prop, name, "", 1); if (rc) mu_diag_funcall (MU_DIAG_ERROR, "mu_property_set_value", name, rc); else { rc = mu_property_save (prop); if (rc) mu_diag_funcall (MU_DIAG_ERROR, "mu_property_save", NULL, rc); } mu_property_destroy (&prop); if (rc) return io_completion_response (command, RESP_NO, "Cannot subscribe"); return io_completion_response (command, RESP_OK, "Completed"); }
/* The folder is destroy if it is the last reference. */ void mu_folder_destroy (mu_folder_t *pfolder) { if (pfolder && *pfolder) { mu_folder_t folder = *pfolder; int destroy_lock = 0; mu_monitor_t monitor = folder->monitor; mu_monitor_wrlock (monitor); /* Check if this the last reference for this folder. If yes removed it from the list. */ mu_monitor_wrlock (&folder_lock); folder->ref--; /* Remove the folder from the list of known folder. */ if (folder->ref <= 0) mu_list_remove (known_folder_list, folder); /* If the list is empty we can safely remove it. */ if (mu_list_is_empty (known_folder_list)) mu_list_destroy (&known_folder_list); mu_monitor_unlock (&folder_lock); if (folder->ref <= 0) { mu_monitor_unlock (monitor); destroy_lock = 1; /* Notify the observers. */ if (folder->observable) { mu_observable_notify (folder->observable, MU_EVT_FOLDER_DESTROY, folder); mu_observable_destroy (&folder->observable, folder); } if (folder->_destroy) folder->_destroy (folder); mu_monitor_wrlock (monitor); if (folder->authority) mu_authority_destroy (&folder->authority, folder); if (folder->url) mu_url_destroy (&folder->url); if (folder->property) mu_property_destroy (&folder->property); free (folder); } mu_monitor_unlock (monitor); if (destroy_lock) mu_monitor_destroy (&monitor, folder); *pfolder = NULL; } }
/* Check and update the vacation database. Return 0 if the mail should be answered, 0 if it should not, and throw exception if an error occurs. */ static int check_db (mu_sieve_machine_t mach, mu_list_t tags, char *from) { mu_property_t prop; char *file; mu_sieve_value_t *arg; unsigned int days; int rc; mu_stream_t str; mu_locker_t locker; if (mu_sieve_tag_lookup (tags, "days", &arg)) { days = arg->v.number; if (days > DAYS_MAX) days = DAYS_MAX; } else days = DAYS_DEFAULT; file = mu_tilde_expansion ("~/.vacation", MU_HIERARCHY_DELIMITER, NULL); if (!file) { mu_sieve_error (mach, _("%lu: cannot build db file name"), (unsigned long) mu_sieve_get_message_num (mach)); mu_sieve_abort (mach); } rc = mu_locker_create (&locker, file, 0); if (rc) { mu_sieve_error (mach, _("%lu: cannot lock %s: %s"), (unsigned long) mu_sieve_get_message_num (mach), file, mu_strerror (rc)); free (file); mu_sieve_abort (mach); } rc = mu_file_stream_create (&str, file, MU_STREAM_RDWR|MU_STREAM_CREAT); if (rc) { mu_sieve_error (mach, "%lu: mu_file_stream_create(%s): %s", (unsigned long) mu_sieve_get_message_num (mach), file, mu_strerror (rc)); mu_locker_destroy (&locker); free (file); mu_sieve_abort (mach); } free (file); rc = mu_property_create_init (&prop, mu_assoc_property_init, str); if (rc) { mu_sieve_error (mach, "%lu: mu_property_create_init: %s", (unsigned long) mu_sieve_get_message_num (mach), mu_strerror (rc)); mu_locker_destroy (&locker); mu_sieve_abort (mach); } rc = mu_locker_lock (locker); if (rc) { mu_sieve_error (mach, "%lu: cannot lock vacation database: %s", (unsigned long) mu_sieve_get_message_num (mach), mu_strerror (rc)); mu_property_destroy (&prop); mu_sieve_abort (mach); } rc = test_and_update_prop (prop, from, time (NULL), days, mach); mu_property_destroy (&prop); mu_locker_unlock (locker); mu_locker_destroy (&locker); if (rc == -1) mu_sieve_abort (mach); return rc; }