Skip to content

Commit

Permalink
lib-dict: dict_iterate_deinit() returns now error string
Browse files Browse the repository at this point in the history
  • Loading branch information
sirainen authored and GitLab committed May 8, 2016
1 parent c4478af commit 055389c
Show file tree
Hide file tree
Showing 14 changed files with 94 additions and 65 deletions.
6 changes: 5 additions & 1 deletion src/auth/userdb-dict.c
Expand Up @@ -141,11 +141,15 @@ static int userdb_dict_iterate_deinit(struct userdb_iterate_context *_ctx)
{
struct dict_userdb_iterate_context *ctx =
(struct dict_userdb_iterate_context *)_ctx;
const char *error;
int ret = _ctx->failed ? -1 : 0;

if (ctx->iter != NULL) {
if (dict_iterate_deinit(&ctx->iter) < 0)
if (dict_iterate_deinit(&ctx->iter, &error) < 0) {
i_error("dict_iterate(%s) failed: %s",
ctx->key_prefix, error);
ret = -1;
}
}
auth_request_unref(&ctx->ctx.auth_request);
i_free(ctx);
Expand Down
16 changes: 11 additions & 5 deletions src/dict/dict-commands.c
Expand Up @@ -33,8 +33,12 @@ static void dict_connection_cmd_output_more(struct dict_connection_cmd *cmd);

static void dict_connection_cmd_free(struct dict_connection_cmd *cmd)
{
if (cmd->iter != NULL)
(void)dict_iterate_deinit(&cmd->iter);
const char *error;

if (cmd->iter != NULL) {
if (dict_iterate_deinit(&cmd->iter, &error) < 0)
i_error("dict_iterate() failed: %s", error);
}
i_free(cmd->reply);

if (dict_connection_unref(cmd->conn))
Expand Down Expand Up @@ -106,7 +110,7 @@ static int cmd_lookup(struct dict_connection_cmd *cmd, const char *line)
static int cmd_iterate_flush(struct dict_connection_cmd *cmd)
{
string_t *str;
const char *key, *value;
const char *key, *value, *error;

str = t_str_new(256);
o_stream_cork(cmd->conn->output);
Expand Down Expand Up @@ -138,8 +142,10 @@ static int cmd_iterate_flush(struct dict_connection_cmd *cmd)
}

str_truncate(str, 0);
if (dict_iterate_deinit(&cmd->iter) < 0)
str_append_c(str, DICT_PROTOCOL_REPLY_FAIL);
if (dict_iterate_deinit(&cmd->iter, &error) < 0) {
i_error("dict_iterate() failed: %s", error);
str_printfa(str, "%c%s", DICT_PROTOCOL_REPLY_FAIL, error);
}
str_append_c(str, '\n');
o_stream_uncork(cmd->conn->output);

Expand Down
6 changes: 3 additions & 3 deletions src/doveadm/doveadm-dict.c
Expand Up @@ -186,7 +186,7 @@ static void cmd_dict_iter(int argc, char *argv[])
struct dict *dict;
struct dict_iterate_context *iter;
enum dict_iterate_flags iter_flags = 0;
const char *key, *value;
const char *key, *value, *error;

if (cmd_dict_init_full(&argc, &argv, 1, 0, cmd_dict_iter, &iter_flags, &dict) < 0)
return;
Expand All @@ -202,8 +202,8 @@ static void cmd_dict_iter(int argc, char *argv[])
if ((iter_flags & DICT_ITERATE_FLAG_NO_VALUE) == 0)
doveadm_print(value);
}
if (dict_iterate_deinit(&iter) < 0) {
i_error("dict_iterate_deinit(%s) failed", argv[0]);
if (dict_iterate_deinit(&iter, &error) < 0) {
i_error("dict_iterate_deinit(%s) failed: %s", argv[0], error);
doveadm_exit_code = EX_TEMPFAIL;
}
dict_deinit(&dict);
Expand Down
22 changes: 14 additions & 8 deletions src/lib-dict-extra/dict-fs.c
Expand Up @@ -21,7 +21,7 @@ struct fs_dict_iterate_context {
enum dict_iterate_flags flags;
pool_t value_pool;
struct fs_iter *fs_iter;
bool failed;
char *error;
};

static int
Expand Down Expand Up @@ -153,10 +153,13 @@ static bool fs_dict_iterate(struct dict_iterate_context *ctx,
const char *path, *error;
int ret;

if (iter->error != NULL)
return FALSE;

*key_r = fs_iter_next(iter->fs_iter);
if (*key_r == NULL) {
if (fs_iter_deinit(&iter->fs_iter) < 0) {
iter->failed = TRUE;
iter->error = i_strdup(fs_last_error(dict->fs));
return FALSE;
}
if (iter->paths[++iter->path_idx] == NULL)
Expand All @@ -173,8 +176,7 @@ static bool fs_dict_iterate(struct dict_iterate_context *ctx,
path = t_strconcat(iter->paths[iter->path_idx], *key_r, NULL);
if ((ret = fs_dict_lookup(ctx->dict, iter->value_pool, path, value_r, &error)) < 0) {
/* I/O error */
i_error("%s", error);
iter->failed = TRUE;
iter->error = i_strdup(error);
return FALSE;
} else if (ret == 0) {
/* file was just deleted, just skip to next one */
Expand All @@ -183,20 +185,24 @@ static bool fs_dict_iterate(struct dict_iterate_context *ctx,
return TRUE;
}

static int fs_dict_iterate_deinit(struct dict_iterate_context *ctx)
static int fs_dict_iterate_deinit(struct dict_iterate_context *ctx,
const char **error_r)
{
struct fs_dict_iterate_context *iter =
(struct fs_dict_iterate_context *)ctx;
struct fs_dict *dict = (struct fs_dict *)ctx->dict;
int ret;

if (iter->fs_iter != NULL) {
if (fs_iter_deinit(&iter->fs_iter) < 0)
iter->failed = TRUE;
if (fs_iter_deinit(&iter->fs_iter) < 0 && iter->error == NULL)
iter->error = i_strdup(fs_last_error(dict->fs));
}
ret = iter->failed ? -1 : 0;
ret = iter->error != NULL ? -1 : 0;
*error_r = t_strdup(iter->error);

pool_unref(&iter->value_pool);
i_free(iter->paths);
i_free(iter->error);
i_free(iter);
return ret;
}
Expand Down
25 changes: 12 additions & 13 deletions src/lib-dict/dict-client.c
Expand Up @@ -55,9 +55,9 @@ struct client_dict {

struct client_dict_iterate_context {
struct dict_iterate_context ctx;
char *error;

pool_t pool;
bool failed;
bool finished;
};

Expand Down Expand Up @@ -655,10 +655,8 @@ client_dict_iterate_init(struct dict *_dict, const char *const *paths,
str_append(query, dict_client_escape(paths[i]));
}
str_append_c(query, '\n');
if (client_dict_send_query(dict, str_c(query), &error) < 0) {
i_error("%s", error);
ctx->failed = TRUE;
}
if (client_dict_send_query(dict, str_c(query), &error) < 0)
ctx->error = i_strdup(error);
return &ctx->ctx;
}

Expand All @@ -671,13 +669,12 @@ static bool client_dict_iterate(struct dict_iterate_context *_ctx,
char *line, *key, *value;
const char *error;

if (ctx->failed)
if (ctx->error != NULL)
return FALSE;

/* read next reply */
if (client_dict_read_line(dict, &line, &error) < 0) {
i_error("%s", error);
ctx->failed = TRUE;
ctx->error = i_strdup(error);
return FALSE;
}

Expand All @@ -696,7 +693,7 @@ static bool client_dict_iterate(struct dict_iterate_context *_ctx,
value = strchr(key, '\t');
break;
case DICT_PROTOCOL_REPLY_FAIL:
ctx->failed = TRUE;
ctx->error = i_strdup_printf("dict-server returned failure: %s", line+1);
return FALSE;
default:
key = NULL;
Expand All @@ -705,8 +702,7 @@ static bool client_dict_iterate(struct dict_iterate_context *_ctx,
}
if (value == NULL) {
/* broken protocol */
i_error("dict client (%s) sent broken iterate reply: %s", dict->path, line);
ctx->failed = TRUE;
ctx->error = i_strdup_printf("dict client (%s) sent broken iterate reply: %s", dict->path, line);
return FALSE;
}
*value++ = '\0';
Expand All @@ -716,17 +712,20 @@ static bool client_dict_iterate(struct dict_iterate_context *_ctx,
return TRUE;
}

static int client_dict_iterate_deinit(struct dict_iterate_context *_ctx)
static int client_dict_iterate_deinit(struct dict_iterate_context *_ctx,
const char **error_r)
{
struct client_dict *dict = (struct client_dict *)_ctx->dict;
struct client_dict_iterate_context *ctx =
(struct client_dict_iterate_context *)_ctx;
int ret = ctx->failed ? -1 : 0;
int ret = ctx->error != NULL ? -1 : 0;

if (!ctx->finished)
dict->iter_replies_skip++;

*error_r = t_strdup(ctx->error);
pool_unref(&ctx->pool);
i_free(ctx->error);
i_free(ctx);
dict->in_iteration = FALSE;

Expand Down
14 changes: 7 additions & 7 deletions src/lib-dict/dict-file.c
Expand Up @@ -46,7 +46,7 @@ struct file_dict_iterate_context {
struct file_dict_iterate_path *paths;

enum dict_iterate_flags flags;
unsigned int failed:1;
const char *error;
};

static struct dotlock_settings file_dict_dotlock_settings = {
Expand Down Expand Up @@ -232,10 +232,8 @@ file_dict_iterate_init(struct dict *_dict, const char *const *paths,
ctx->flags = flags;
ctx->iter = hash_table_iterate_init(dict->hash);

if (file_dict_refresh(dict, &error) < 0) {
i_error("%s", error);
ctx->failed = TRUE;
}
if (file_dict_refresh(dict, &error) < 0)
ctx->error = p_strdup(pool, error);
return &ctx->ctx;
}

Expand Down Expand Up @@ -284,12 +282,14 @@ static bool file_dict_iterate(struct dict_iterate_context *_ctx,
return FALSE;
}

static int file_dict_iterate_deinit(struct dict_iterate_context *_ctx)
static int file_dict_iterate_deinit(struct dict_iterate_context *_ctx,
const char **error_r)
{
struct file_dict_iterate_context *ctx =
(struct file_dict_iterate_context *)_ctx;
int ret = ctx->failed ? -1 : 0;
int ret = ctx->error != NULL ? -1 : 0;

*error_r = t_strdup(ctx->error);
hash_table_iterate_deinit(&ctx->iter);
pool_unref(&ctx->pool);
return ret;
Expand Down
3 changes: 2 additions & 1 deletion src/lib-dict/dict-private.h
Expand Up @@ -19,7 +19,8 @@ struct dict_vfuncs {
enum dict_iterate_flags flags);
bool (*iterate)(struct dict_iterate_context *ctx,
const char **key_r, const char **value_r);
int (*iterate_deinit)(struct dict_iterate_context *ctx);
int (*iterate_deinit)(struct dict_iterate_context *ctx,
const char **error_r);

struct dict_transaction_context *(*transaction_init)(struct dict *dict);
int (*transaction_commit)(struct dict_transaction_context *ctx,
Expand Down
19 changes: 10 additions & 9 deletions src/lib-dict/dict-sql.c
Expand Up @@ -46,7 +46,7 @@ struct sql_dict_iterate_context {
unsigned int key_prefix_len, pattern_prefix_len, next_map_idx;
unsigned int path_idx, sql_fields_start_idx;
bool synchronous_result;
bool failed;
const char *error;
};

struct sql_dict_inc_row {
Expand Down Expand Up @@ -653,10 +653,9 @@ sql_dict_iterate_init(struct dict *_dict, const char *const *paths,

ctx->key = str_new(pool, 256);
if (sql_dict_iterate_next_query(ctx, &error) <= 0) {
i_error("sql dict iterate failed for %s: %s",
paths[0], error);
ctx->error = p_strdup_printf(pool,
"sql dict iterate failed for %s: %s", paths[0], error);
ctx->result = NULL;
ctx->failed = TRUE;
return &ctx->ctx;
}
return &ctx->ctx;
Expand All @@ -672,7 +671,7 @@ static bool sql_dict_iterate(struct dict_iterate_context *_ctx,
int ret;

_ctx->has_more = FALSE;
if (ctx->failed)
if (ctx->error != NULL)
return FALSE;

for (;;) {
Expand All @@ -695,8 +694,8 @@ static bool sql_dict_iterate(struct dict_iterate_context *_ctx,
return FALSE;
}
if (ret < 0) {
ctx->failed = TRUE;
i_error("dict sql iterate failed: %s",
ctx->error = p_strdup_printf(ctx->pool,
"dict sql iterate failed: %s",
sql_result_get_error(ctx->result));
return FALSE;
}
Expand Down Expand Up @@ -733,12 +732,14 @@ static bool sql_dict_iterate(struct dict_iterate_context *_ctx,
return TRUE;
}

static int sql_dict_iterate_deinit(struct dict_iterate_context *_ctx)
static int sql_dict_iterate_deinit(struct dict_iterate_context *_ctx,
const char **error_r)
{
struct sql_dict_iterate_context *ctx =
(struct sql_dict_iterate_context *)_ctx;
int ret = ctx->failed ? -1 : 0;
int ret = ctx->error != NULL ? -1 : 0;

*error_r = t_strdup(ctx->error);
if (ctx->result != NULL)
sql_result_unref(ctx->result);
pool_unref(&ctx->pool);
Expand Down
11 changes: 7 additions & 4 deletions src/lib-dict/dict.c
Expand Up @@ -144,7 +144,6 @@ dict_iterate_init_multiple(struct dict *dict, const char *const *paths,
i_assert(dict_key_prefix_is_valid(paths[i]));
if (dict->v.iterate_init == NULL) {
/* not supported by backend */
i_error("%s: dict iteration not supported", dict->name);
return &dict_iter_unsupported;
}
return dict->v.iterate_init(dict, paths, flags);
Expand All @@ -170,13 +169,17 @@ bool dict_iterate_has_more(struct dict_iterate_context *ctx)
return ctx->has_more;
}

int dict_iterate_deinit(struct dict_iterate_context **_ctx)
int dict_iterate_deinit(struct dict_iterate_context **_ctx,
const char **error_r)
{
struct dict_iterate_context *ctx = *_ctx;

*_ctx = NULL;
return ctx == &dict_iter_unsupported ? -1 :
ctx->dict->v.iterate_deinit(ctx);
if (ctx == &dict_iter_unsupported) {
*error_r = "Dict doesn't support iteration";
return -1;
}
return ctx->dict->v.iterate_deinit(ctx, error_r);
}

struct dict_transaction_context *dict_transaction_begin(struct dict *dict)
Expand Down
2 changes: 1 addition & 1 deletion src/lib-dict/dict.h
Expand Up @@ -96,7 +96,7 @@ bool dict_iterate_has_more(struct dict_iterate_context *ctx);
bool dict_iterate(struct dict_iterate_context *ctx,
const char **key_r, const char **value_r);
/* Returns 0 = ok, -1 = iteration failed */
int dict_iterate_deinit(struct dict_iterate_context **ctx);
int dict_iterate_deinit(struct dict_iterate_context **ctx, const char **error_r);

/* Start a new dictionary transaction. */
struct dict_transaction_context *dict_transaction_begin(struct dict *dict);
Expand Down
5 changes: 3 additions & 2 deletions src/lib-fs/fs-dict.c
Expand Up @@ -282,11 +282,12 @@ static const char *fs_dict_iter_next(struct fs_iter *_iter)
static int fs_dict_iter_deinit(struct fs_iter *_iter)
{
struct dict_fs_iter *iter = (struct dict_fs_iter *)_iter;
const char *error;
int ret;

ret = dict_iterate_deinit(&iter->dict_iter);
ret = dict_iterate_deinit(&iter->dict_iter, &error);
if (ret < 0)
fs_set_error(_iter->fs, "Dict iteration failed");
fs_set_error(_iter->fs, "Dict iteration failed: %s", error);
i_free(iter);
return ret;
}
Expand Down
8 changes: 6 additions & 2 deletions src/lib-storage/index/index-attribute.c
Expand Up @@ -302,13 +302,17 @@ int index_storage_attribute_iter_deinit(struct mailbox_attribute_iter *_iter)
{
struct index_storage_attribute_iter *iter =
(struct index_storage_attribute_iter *)_iter;
const char *error;
int ret;

if (iter->diter == NULL) {
ret = iter->dict_disabled ? 0 : -1;
} else {
if ((ret = dict_iterate_deinit(&iter->diter)) < 0)
mail_storage_set_internal_error(_iter->box->storage);
if ((ret = dict_iterate_deinit(&iter->diter, &error)) < 0) {
mail_storage_set_critical(_iter->box->storage,
"dict_iterate(%s) failed: %s",
iter->prefix, error);
}
}
i_free(iter->prefix);
i_free(iter);
Expand Down

0 comments on commit 055389c

Please sign in to comment.