void client_send_mailbox_flags(struct client *client, bool selecting) { struct mailbox_status status; unsigned int count = array_count(client->keywords.names); const char *const *keywords; string_t *str; if (!selecting && count == client->keywords.announce_count) { /* no changes to keywords and we're not selecting a mailbox */ return; } client->keywords.announce_count = count; mailbox_get_open_status(client->mailbox, STATUS_PERMANENT_FLAGS, &status); keywords = count == 0 ? NULL : array_idx(client->keywords.names, 0); str = t_str_new(128); str_append(str, "* FLAGS ("); imap_write_flags(str, MAIL_FLAGS_NONRECENT, keywords); str_append_c(str, ')'); client_send_line(client, str_c(str)); if (!status.permanent_keywords) keywords = NULL; str_truncate(str, 0); str_append(str, "* OK [PERMANENTFLAGS ("); imap_write_flags(str, status.permanent_flags, keywords); if (status.allow_new_keywords) { if (status.permanent_flags != 0 || keywords != NULL) str_append_c(str, ' '); str_append(str, "\\*"); } str_append(str, ")] "); if (mailbox_is_readonly(client->mailbox)) str_append(str, "Read-only mailbox."); else str_append(str, "Flags permitted."); client_send_line(client, str_c(str)); }
int imap_expunge(struct mailbox *box, struct mail_search_arg *next_search_arg, unsigned int *expunged_count) { struct mail_search_context *ctx; struct mailbox_transaction_context *t; struct mail *mail; struct mail_search_args *search_args; bool expunges = FALSE; if (mailbox_is_readonly(box)) { /* silently ignore */ return 0; } search_args = mail_search_build_init(); search_args->args = p_new(search_args->pool, struct mail_search_arg, 1); search_args->args->type = SEARCH_FLAGS; search_args->args->value.flags = MAIL_DELETED; search_args->args->next = next_search_arg; /* Refresh the flags so we'll expunge all messages marked as \Deleted by any session. */ t = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_REFRESH); ctx = mailbox_search_init(t, search_args, NULL, 0, NULL); mail_search_args_unref(&search_args); while (mailbox_search_next(ctx, &mail)) { *expunged_count += 1; mail_expunge(mail); expunges = TRUE; } if (mailbox_search_deinit(&ctx) < 0) { mailbox_transaction_rollback(&t); return -1; } else { if (mailbox_transaction_commit(&t) < 0) return -1; } return expunges ? 1 : 0; }
void index_storage_get_open_status(struct mailbox *box, enum mailbox_status_items items, struct mailbox_status *status_r) { const struct mail_index_header *hdr; /* we can get most of the status items without any trouble */ hdr = mail_index_get_header(box->view); status_r->messages = hdr->messages_count; if ((items & STATUS_RECENT) != 0) { if ((box->flags & MAILBOX_FLAG_DROP_RECENT) != 0) { /* recent flags are set and dropped by the previous sync while index was locked. if we updated the recent flags here we'd have a race condition. */ i_assert(box->synced); } else { /* make sure recent count is set, in case we haven't synced yet */ index_sync_update_recent_count(box); } status_r->recent = index_mailbox_get_recent_count(box); i_assert(status_r->recent <= status_r->messages); } if ((items & STATUS_UNSEEN) != 0) { if (box->view_pvt == NULL || (mailbox_get_private_flags_mask(box) & MAIL_SEEN) == 0) { status_r->unseen = hdr->messages_count - hdr->seen_messages_count; } else { status_r->unseen = index_storage_count_pvt_unseen(box); } } status_r->uidvalidity = hdr->uid_validity; status_r->uidnext = hdr->next_uid; status_r->first_recent_uid = hdr->first_recent_uid; if ((items & STATUS_HIGHESTMODSEQ) != 0) { status_r->nonpermanent_modseqs = mail_index_is_in_memory(box->index); status_r->no_modseq_tracking = !mail_index_have_modseq_tracking(box->index); status_r->highest_modseq = mail_index_modseq_get_highest(box->view); if (status_r->highest_modseq == 0) { /* modseqs not enabled yet, but we can't return 0 */ status_r->highest_modseq = 1; } } if ((items & STATUS_HIGHESTPVTMODSEQ) != 0 && box->view_pvt != NULL) { status_r->highest_pvt_modseq = mail_index_modseq_get_highest(box->view_pvt); if (status_r->highest_pvt_modseq == 0) { /* modseqs not enabled yet, but we can't return 0 */ status_r->highest_pvt_modseq = 1; } } if ((items & STATUS_FIRST_UNSEEN_SEQ) != 0) { if (box->view_pvt == NULL || (mailbox_get_private_flags_mask(box) & MAIL_SEEN) == 0) { mail_index_lookup_first(box->view, 0, MAIL_SEEN, &status_r->first_unseen_seq); } else { status_r->first_unseen_seq = index_storage_find_first_pvt_unseen_seq(box); } } if ((items & STATUS_LAST_CACHED_SEQ) != 0) get_last_cached_seq(box, &status_r->last_cached_seq); if ((items & STATUS_KEYWORDS) != 0) status_r->keywords = mail_index_get_keywords(box->index); if ((items & STATUS_PERMANENT_FLAGS) != 0) { if (!mailbox_is_readonly(box)) { status_r->permanent_flags = MAIL_FLAGS_NONRECENT; status_r->permanent_keywords = TRUE; status_r->allow_new_keywords = !box->disallow_new_keywords; } } }
static int tst_mailboxexists_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { struct sieve_stringlist *mailbox_names; string_t *mailbox_item; bool trace = FALSE; bool all_exist = TRUE; int ret; /* * Read operands */ /* Read notify uris */ if ( (ret=sieve_opr_stringlist_read (renv, address, "mailbox-names", &mailbox_names)) <= 0 ) return ret; /* * Perform operation */ if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_TESTS) ) { sieve_runtime_trace(renv, 0, "mailboxexists test"); sieve_runtime_trace_descend(renv); trace = sieve_runtime_trace_active(renv, SIEVE_TRLVL_MATCHING); } if ( renv->scriptenv->user != NULL ) { int ret; mailbox_item = NULL; while ( (ret=sieve_stringlist_next_item(mailbox_names, &mailbox_item)) > 0 ) { struct mail_namespace *ns; const char *mailbox = str_c(mailbox_item); struct mailbox *box; /* Find the namespace */ ns = mail_namespace_find(renv->scriptenv->user->namespaces, mailbox); if ( ns == NULL) { if ( trace ) { sieve_runtime_trace(renv, 0, "mailbox `%s' not found", str_sanitize(mailbox, 80)); } all_exist = FALSE; break; } /* Open the box */ box = mailbox_alloc(ns->list, mailbox, 0); if ( mailbox_open(box) < 0 ) { if ( trace ) { sieve_runtime_trace(renv, 0, "mailbox `%s' cannot be opened", str_sanitize(mailbox, 80)); } all_exist = FALSE; mailbox_free(&box); break; } /* Also fail when it is readonly */ if ( mailbox_is_readonly(box) ) { if ( trace ) { sieve_runtime_trace(renv, 0, "mailbox `%s' is read-only", str_sanitize(mailbox, 80)); } all_exist = FALSE; mailbox_free(&box); break; } /* FIXME: check acl for 'p' or 'i' ACL permissions as required by RFC */ if ( trace ) { sieve_runtime_trace(renv, 0, "mailbox `%s' exists", str_sanitize(mailbox, 80)); } /* Close mailbox */ mailbox_free(&box); } if ( ret < 0 ) { sieve_runtime_trace_error(renv, "invalid mailbox name item"); return SIEVE_EXEC_BIN_CORRUPT; } } if ( trace ) { if ( all_exist ) sieve_runtime_trace(renv, 0, "all mailboxes are available"); else sieve_runtime_trace(renv, 0, "some mailboxes are unavailable"); } sieve_interpreter_set_test_result(renv->interp, all_exist); return SIEVE_EXEC_OK; }