From 53e62982d35ea69a03d9fc3be7f1b888732da809 Mon Sep 17 00:00:00 2001 From: Josef 'Jeff' Sipek Date: Tue, 1 Dec 2020 12:13:31 -0500 Subject: [PATCH] lib-storage: Split off the mailbox attribute lua code Move the code into a separate file to mirror the native C code layout. --- src/lib-storage/Makefile.am | 3 +- src/lib-storage/mail-storage-lua.c | 152 ---------------------- src/lib-storage/mailbox-attribute-lua.c | 163 ++++++++++++++++++++++++ 3 files changed, 165 insertions(+), 153 deletions(-) create mode 100644 src/lib-storage/mailbox-attribute-lua.c diff --git a/src/lib-storage/Makefile.am b/src/lib-storage/Makefile.am index 6724127d00..4cc8b721a9 100644 --- a/src/lib-storage/Makefile.am +++ b/src/lib-storage/Makefile.am @@ -140,7 +140,8 @@ pkglib_LTLIBRARIES += libdovecot-storage-lua.la libdovecot_storage_lua_la_SOURCES = \ mail-lua.c \ mail-storage-lua.c \ - mailbox-lua.c + mailbox-lua.c \ + mailbox-attribute-lua.c libdovecot_storage_lua_la_CPPFLAGS = \ $(AM_CPPFLAGS) \ $(LUA_CFLAGS) \ diff --git a/src/lib-storage/mail-storage-lua.c b/src/lib-storage/mail-storage-lua.c index 7d55ee32d6..095104b1d6 100644 --- a/src/lib-storage/mail-storage-lua.c +++ b/src/lib-storage/mail-storage-lua.c @@ -16,158 +16,6 @@ #define LUA_SCRIPT_STORAGE "storage" #define LUA_STORAGE_MAIL_USER "struct mail_user" -/** shared functions - */ - -/* lookup mailbox attribute */ -int lua_storage_mailbox_attribute_get(struct mailbox *box, const char *key, - const char **value_r, size_t *value_len_r, - const char **error_r) -{ - struct mail_attribute_value value; - enum mail_attribute_type attr_type; - int ret; - - if (str_begins(key, "/private/")) { - attr_type = MAIL_ATTRIBUTE_TYPE_PRIVATE; - key += 9; - } else if (str_begins(key, "/shared/")) { - attr_type = MAIL_ATTRIBUTE_TYPE_SHARED; - key += 8; - } else { - *error_r = "Invalid key prefix, must be /private/ or /shared/"; - return -1; - } - - /* get the attribute */ - if ((ret = mailbox_attribute_get_stream(box, attr_type, key, &value)) < 0) { - *error_r = mailbox_get_last_error(box, NULL); - return ret; - } else if (ret == 0) { - /* was not found */ - *value_r = NULL; - *value_len_r = 0; - return 0; - } - - if (value.value_stream != NULL) { - string_t *str = t_str_new(128); - const unsigned char *data; - size_t siz; - while((ret = i_stream_read_more(value.value_stream, &data, &siz))>0) { - str_append_data(str, data, siz); - i_stream_skip(value.value_stream, siz); - } - i_assert(ret != 0); - if (ret == -1 && !value.value_stream->eof) { - /* we could not read the stream */ - *error_r = i_stream_get_error(value.value_stream); - ret = -1; - } else { - *value_r = str->data; - *value_len_r = str->used; - ret = 1; - } - i_stream_unref(&value.value_stream); - return ret; - } - - *value_r = value.value; - if (value.value != NULL) - *value_len_r = strlen(value.value); - else - *value_len_r = 0; - return 1; -} - -int lua_storage_mailbox_attribute_set(struct mailbox *box, const char *key, - const char *value, size_t value_len, - const char **error_r) -{ - struct mail_attribute_value attr_value; - enum mail_attribute_type attr_type; - int ret; - - i_assert(value != NULL || value_len == 0); - - if (str_begins(key, "/private/")) { - attr_type = MAIL_ATTRIBUTE_TYPE_PRIVATE; - key += 9; - } else if (str_begins(key, "/shared/")) { - attr_type = MAIL_ATTRIBUTE_TYPE_SHARED; - key += 8; - } else { - *error_r = "Invalid key prefix, must be /private/ or /shared/"; - return -1; - } - - struct mailbox_transaction_context *t = - mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_NO_NOTIFY, __func__); - i_zero(&attr_value); - - if (value != NULL) { - /* use stream API to allow NULs in data */ - attr_value.value_stream = i_stream_create_from_data(value, value_len); - } - - ret = mailbox_attribute_set(t, attr_type, key, &attr_value); - - if (ret < 0) { - *error_r = mailbox_get_last_error(box, NULL); - mailbox_transaction_rollback(&t); - } else if ((ret = mailbox_transaction_commit(&t)) < 0) { - *error_r = mailbox_get_last_error(box, NULL); - } - - if (attr_value.value_stream != NULL) - i_stream_unref(&attr_value.value_stream); - - return ret; -} - -int lua_storage_mailbox_attribute_list(struct mailbox *box, const char *prefix, - ARRAY_TYPE(lua_storage_keyvalue) *items_r, - const char **error_r) -{ - const char *key, *orig_prefix = prefix; - enum mail_attribute_type attr_type; - int ret; - - if (str_begins(prefix, "/private/")) { - attr_type = MAIL_ATTRIBUTE_TYPE_PRIVATE; - prefix += 9; - } else if (str_begins(prefix, "/shared/")) { - attr_type = MAIL_ATTRIBUTE_TYPE_SHARED; - prefix += 8; - } else { - *error_r = "Invalid key prefix, must be /private/ or /shared/"; - return -1; - } - - struct mailbox_attribute_iter *iter = - mailbox_attribute_iter_init(box, attr_type, prefix); - - ret = 0; - *error_r = NULL; - while((key = mailbox_attribute_iter_next(iter)) != NULL) { - struct lua_storage_keyvalue *item = array_append_space(items_r); - item->key = t_strdup_printf("%s%s", orig_prefix, key); - if (lua_storage_mailbox_attribute_get(box, item->key, &item->value, - &item->value_len, error_r) < 0) { - ret = -1; - break; - } - } - - if (mailbox_attribute_iter_deinit(&iter) < 0 || ret == -1) { - if (*error_r == NULL) - *error_r = mailbox_get_last_error(box, NULL); - return -1; - } - - return 0; -} - /** MAIL USER */ diff --git a/src/lib-storage/mailbox-attribute-lua.c b/src/lib-storage/mailbox-attribute-lua.c new file mode 100644 index 0000000000..8d615a0428 --- /dev/null +++ b/src/lib-storage/mailbox-attribute-lua.c @@ -0,0 +1,163 @@ +/* Copyright (c) 2018 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "str.h" +#include "istream.h" +#include "array.h" +#include "var-expand.h" +#include "dlua-script.h" +#include "dlua-script-private.h" +#include "mail-storage.h" +#include "mailbox-attribute.h" +#include "mail-storage-lua.h" +#include "mail-storage-lua-private.h" +#include "mail-user.h" + +/* lookup mailbox attribute */ +int lua_storage_mailbox_attribute_get(struct mailbox *box, const char *key, + const char **value_r, size_t *value_len_r, + const char **error_r) +{ + struct mail_attribute_value value; + enum mail_attribute_type attr_type; + int ret; + + if (str_begins(key, "/private/")) { + attr_type = MAIL_ATTRIBUTE_TYPE_PRIVATE; + key += 9; + } else if (str_begins(key, "/shared/")) { + attr_type = MAIL_ATTRIBUTE_TYPE_SHARED; + key += 8; + } else { + *error_r = "Invalid key prefix, must be /private/ or /shared/"; + return -1; + } + + /* get the attribute */ + if ((ret = mailbox_attribute_get_stream(box, attr_type, key, &value)) < 0) { + *error_r = mailbox_get_last_error(box, NULL); + return ret; + } else if (ret == 0) { + /* was not found */ + *value_r = NULL; + *value_len_r = 0; + return 0; + } + + if (value.value_stream != NULL) { + string_t *str = t_str_new(128); + const unsigned char *data; + size_t siz; + while((ret = i_stream_read_more(value.value_stream, &data, &siz))>0) { + str_append_data(str, data, siz); + i_stream_skip(value.value_stream, siz); + } + i_assert(ret != 0); + if (ret == -1 && !value.value_stream->eof) { + /* we could not read the stream */ + *error_r = i_stream_get_error(value.value_stream); + ret = -1; + } else { + *value_r = str->data; + *value_len_r = str->used; + ret = 1; + } + i_stream_unref(&value.value_stream); + return ret; + } + + *value_r = value.value; + if (value.value != NULL) + *value_len_r = strlen(value.value); + else + *value_len_r = 0; + return 1; +} + +int lua_storage_mailbox_attribute_set(struct mailbox *box, const char *key, + const char *value, size_t value_len, + const char **error_r) +{ + struct mail_attribute_value attr_value; + enum mail_attribute_type attr_type; + int ret; + + i_assert(value != NULL || value_len == 0); + + if (str_begins(key, "/private/")) { + attr_type = MAIL_ATTRIBUTE_TYPE_PRIVATE; + key += 9; + } else if (str_begins(key, "/shared/")) { + attr_type = MAIL_ATTRIBUTE_TYPE_SHARED; + key += 8; + } else { + *error_r = "Invalid key prefix, must be /private/ or /shared/"; + return -1; + } + + struct mailbox_transaction_context *t = + mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_NO_NOTIFY, __func__); + i_zero(&attr_value); + + if (value != NULL) { + /* use stream API to allow NULs in data */ + attr_value.value_stream = i_stream_create_from_data(value, value_len); + } + + ret = mailbox_attribute_set(t, attr_type, key, &attr_value); + + if (ret < 0) { + *error_r = mailbox_get_last_error(box, NULL); + mailbox_transaction_rollback(&t); + } else if ((ret = mailbox_transaction_commit(&t)) < 0) { + *error_r = mailbox_get_last_error(box, NULL); + } + + if (attr_value.value_stream != NULL) + i_stream_unref(&attr_value.value_stream); + + return ret; +} + +int lua_storage_mailbox_attribute_list(struct mailbox *box, const char *prefix, + ARRAY_TYPE(lua_storage_keyvalue) *items_r, + const char **error_r) +{ + const char *key, *orig_prefix = prefix; + enum mail_attribute_type attr_type; + int ret; + + if (str_begins(prefix, "/private/")) { + attr_type = MAIL_ATTRIBUTE_TYPE_PRIVATE; + prefix += 9; + } else if (str_begins(prefix, "/shared/")) { + attr_type = MAIL_ATTRIBUTE_TYPE_SHARED; + prefix += 8; + } else { + *error_r = "Invalid key prefix, must be /private/ or /shared/"; + return -1; + } + + struct mailbox_attribute_iter *iter = + mailbox_attribute_iter_init(box, attr_type, prefix); + + ret = 0; + *error_r = NULL; + while((key = mailbox_attribute_iter_next(iter)) != NULL) { + struct lua_storage_keyvalue *item = array_append_space(items_r); + item->key = t_strdup_printf("%s%s", orig_prefix, key); + if (lua_storage_mailbox_attribute_get(box, item->key, &item->value, + &item->value_len, error_r) < 0) { + ret = -1; + break; + } + } + + if (mailbox_attribute_iter_deinit(&iter) < 0 || ret == -1) { + if (*error_r == NULL) + *error_r = mailbox_get_last_error(box, NULL); + return -1; + } + + return 0; +} -- 2.47.3