bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Boschbool imap_metadata_verify_entry_name(const char *name, const char **error_r)
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch unsigned int i;
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch switch (name[i]) {
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch *error_r = "Entry name can't contain consecutive '/'";
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch *error_r = "Entry name can't contain control chars";
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch prefix = p == NULL ? name : t_strdup_until(name, p);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch ok = strcasecmp(prefix, IMAP_METADATA_PRIVATE_PREFIX) == 0 ||
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch strcasecmp(prefix, IMAP_METADATA_SHARED_PREFIX) == 0;
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch *error_r = "Entry name must begin with /private or /shared";
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Boschimap_metadata_transaction_set_error(struct imap_metadata_transaction *imtrans,
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Boschimap_metadata_entry2key(struct imap_metadata_transaction *imtrans,
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch const char *entry, enum mail_attribute_type *type_r,
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch const char **key_r)
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT_SERVER : NULL);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch /* names are case-insensitive so we'll always lowercase them */
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch if (strncmp(entry, IMAP_METADATA_PRIVATE_PREFIX,
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch *key_r = entry + strlen(IMAP_METADATA_PRIVATE_PREFIX);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch i_assert(strncmp(entry, IMAP_METADATA_SHARED_PREFIX,
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch *key_r = entry + strlen(IMAP_METADATA_SHARED_PREFIX);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch /* /private or /shared prefix has no value itself */
c07fb2247951f6bc9421d816bb7599efcd84da2eTimo Sirainen if (strncmp(*key_r, MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT,
c07fb2247951f6bc9421d816bb7599efcd84da2eTimo Sirainen strlen(MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT)) == 0) {
c07fb2247951f6bc9421d816bb7599efcd84da2eTimo Sirainen /* Dovecot's internal attribute (mailbox or server).
c07fb2247951f6bc9421d816bb7599efcd84da2eTimo Sirainen don't allow accessing this. */
c07fb2247951f6bc9421d816bb7599efcd84da2eTimo Sirainen /* Add the server-prefix (after checking for the above internal
c07fb2247951f6bc9421d816bb7599efcd84da2eTimo Sirainen attribute). */
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch *key_r = t_strconcat(key_prefix, *key_r, NULL);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Boschimap_metadata_get_mailbox_transaction(struct imap_metadata_transaction *imtrans)
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch if (imtrans->box == NULL || mailbox_open(imtrans->box) < 0)
0dab9cb35a976c49b28a11e28d5570f5191f1a7aMartti Rannanjärvi imtrans->trans = mailbox_transaction_begin(imtrans->box,
0dab9cb35a976c49b28a11e28d5570f5191f1a7aMartti Rannanjärvi MAILBOX_TRANSACTION_FLAG_EXTERNAL, __func__);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Boschint imap_metadata_set(struct imap_metadata_transaction *imtrans,
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch const char *entry, const struct mail_attribute_value *value)
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch if (!imap_metadata_entry2key(imtrans, entry, &type, &key)) {
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch imap_metadata_transaction_set_error(imtrans, MAIL_ERROR_PARAMS,
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch "Internal mailbox attributes cannot be accessed");
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch if (imap_metadata_get_mailbox_transaction(imtrans) < 0)
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch mailbox_attribute_unset(imtrans->trans, type, key) :
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch mailbox_attribute_set(imtrans->trans, type, key, value));
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Boschint imap_metadata_unset(struct imap_metadata_transaction *imtrans,
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch return imap_metadata_set(imtrans, entry, &value);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Boschint imap_metadata_get(struct imap_metadata_transaction *imtrans,
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch const char *entry, struct mail_attribute_value *value_r)
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch if (!imap_metadata_entry2key(imtrans, entry, &type, &key))
66c87722e0fd2a85cd59797326bad3d1c409dc3aAki Tuomi return mailbox_attribute_get(imtrans->box, type, key, value_r);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Boschint imap_metadata_get_stream(struct imap_metadata_transaction *imtrans,
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch const char *entry, struct mail_attribute_value *value_r)
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch if (!imap_metadata_entry2key(imtrans, entry, &type, &key))
66c87722e0fd2a85cd59797326bad3d1c409dc3aAki Tuomi return mailbox_attribute_get_stream(imtrans->box, type, key, value_r);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Boschimap_metadata_iter_init(struct imap_metadata_transaction *imtrans,
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch if (imap_metadata_entry2key(imtrans, entry, &type, &key)) {
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch key[0] == '\0' ? "" : t_strconcat(key, "/", NULL);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch iter->iter = mailbox_attribute_iter_init(imtrans->box, type,
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Boschconst char *imap_metadata_iter_next(struct imap_metadata_iter *iter)
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch return mailbox_attribute_iter_next(iter->iter);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Boschint imap_metadata_iter_deinit(struct imap_metadata_iter **_iter)
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch ret = mailbox_attribute_iter_deinit(&iter->iter);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Boschimap_metadata_transaction_begin(struct mailbox *box)
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch imtrans = i_new(struct imap_metadata_transaction, 1);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Boschimap_metadata_transaction_begin_server(struct mail_user *user)
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch ns = mail_namespace_find_inbox(user->namespaces);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch imtrans = imap_metadata_transaction_begin(box);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Boschimap_metadata_transaction_finish(struct imap_metadata_transaction **_imtrans)
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch struct imap_metadata_transaction *imtrans = *_imtrans;
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch enum mail_error *error_code_r, const char **error_r)
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch struct imap_metadata_transaction *imtrans = *_imtrans;
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch ret = mailbox_transaction_commit(&imtrans->trans);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch error = mailbox_get_last_error(imtrans->box, error_code_r);
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch struct imap_metadata_transaction *imtrans = *_imtrans;
8ccdf195768afdfbc32088d7be77dfca7dddd829Stephan Bosch mailbox_transaction_rollback(&imtrans->trans);