]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-dict: Changed dict_iterate API.
authorTimo Sirainen <tss@iki.fi>
Sun, 7 Feb 2010 14:27:18 +0000 (16:27 +0200)
committerTimo Sirainen <tss@iki.fi>
Sun, 7 Feb 2010 14:27:18 +0000 (16:27 +0200)
--HG--
branch : HEAD

src/dict/dict-commands.c
src/dict/dict-connection.c
src/lib-dict/dict-client.c
src/lib-dict/dict-db.c
src/lib-dict/dict-file.c
src/lib-dict/dict-private.h
src/lib-dict/dict-sql.c
src/lib-dict/dict.c
src/lib-dict/dict.h
src/plugins/acl/acl-lookup-dict.c
src/plugins/expire/expire-tool.c

index 4ac7710cdf82fdf49141124714803b154d3f3dde..ca523d63bc12258e778085368e6427788e113d1c 100644 (file)
@@ -52,7 +52,7 @@ static int cmd_iterate_flush(struct dict_connection *conn)
 
        str = t_str_new(256);
        o_stream_cork(conn->output);
-       while ((ret = dict_iterate(conn->iter_ctx, &key, &value)) > 0) {
+       while (dict_iterate(conn->iter_ctx, &key, &value)) {
                str_truncate(str, 0);
                str_printfa(str, "%c%s\t%s\n", DICT_PROTOCOL_REPLY_OK,
                            key, value);
@@ -60,25 +60,25 @@ static int cmd_iterate_flush(struct dict_connection *conn)
 
                if (o_stream_get_buffer_used_size(conn->output) >
                    DICT_OUTPUT_OPTIMAL_SIZE) {
-                       if (o_stream_flush(conn->output) <= 0)
-                               break;
+                       if (o_stream_flush(conn->output) <= 0) {
+                               /* continue later */
+                               o_stream_uncork(conn->output);
+                               return 0;
+                       }
                        /* flushed everything, continue */
                }
        }
 
-       if (ret <= 0) {
-               /* finished iterating */
-               o_stream_unset_flush_callback(conn->output);
-               dict_iterate_deinit(&conn->iter_ctx);
+       /* finished iterating */
+       o_stream_unset_flush_callback(conn->output);
 
-               str_truncate(str, 0);
-               if (ret < 0)
-                       str_append_c(str, DICT_PROTOCOL_REPLY_FAIL);
-               str_append_c(str, '\n');
-               o_stream_send(conn->output, str_data(str), str_len(str));
-       }
+       str_truncate(str, 0);
+       if ((ret = dict_iterate_deinit(&conn->iter_ctx)) < 0)
+               str_append_c(str, DICT_PROTOCOL_REPLY_FAIL);
+       str_append_c(str, '\n');
+       o_stream_send(conn->output, str_data(str), str_len(str));
        o_stream_uncork(conn->output);
-       return ret <= 0 ? 1 : 0;
+       return 1;
 }
 
 static int cmd_iterate(struct dict_connection *conn, const char *line)
index 3865314c963c4d6af710e7b530d78ffca95590ab..0d8db95273c97c6d6e4571bdd9851a23e63bde1e 100644 (file)
@@ -166,7 +166,7 @@ void dict_connection_destroy(struct dict_connection *conn)
        }
 
        if (conn->iter_ctx != NULL)
-               dict_iterate_deinit(&conn->iter_ctx);
+               (void)dict_iterate_deinit(&conn->iter_ctx);
 
        io_remove(&conn->io);
        i_stream_destroy(&conn->input);
index a0561f444dffb3c3fdd5f3eb9ea8b160fb7fbaef..2e30f2a32bbc67312c3df6e9e251df4fc606de40 100644 (file)
@@ -493,8 +493,8 @@ client_dict_iterate_init(struct dict *_dict, const char *path,
        return &ctx->ctx;
 }
 
-static int client_dict_iterate(struct dict_iterate_context *_ctx,
-                              const char **key_r, const char **value_r)
+static bool client_dict_iterate(struct dict_iterate_context *_ctx,
+                               const char **key_r, const char **value_r)
 {
        struct client_dict_iterate_context *ctx =
                (struct client_dict_iterate_context *)_ctx;
@@ -502,16 +502,18 @@ static int client_dict_iterate(struct dict_iterate_context *_ctx,
        char *line, *value;
 
        if (ctx->failed)
-               return -1;
+               return FALSE;
 
        /* read next reply */
        line = client_dict_read_line(dict);
-       if (line == NULL)
-               return -1;
+       if (line == NULL) {
+               ctx->failed = TRUE;
+               return FALSE;
+       }
 
        if (*line == '\0') {
                /* end of iteration */
-               return 0;
+               return FALSE;
        }
 
        /* line contains key \t value */
@@ -522,7 +524,8 @@ static int client_dict_iterate(struct dict_iterate_context *_ctx,
                value = strchr(++line, '\t');
                break;
        case DICT_PROTOCOL_REPLY_FAIL:
-               return -1;
+               ctx->failed = TRUE;
+               return FALSE;
        default:
                value = NULL;
                break;
@@ -530,24 +533,27 @@ static int client_dict_iterate(struct dict_iterate_context *_ctx,
        if (value == NULL) {
                /* broken protocol */
                i_error("dict client (%s) sent broken reply", dict->path);
-               return -1;
+               ctx->failed = TRUE;
+               return FALSE;
        }
        *value++ = '\0';
 
        *key_r = p_strdup(ctx->pool, dict_client_unescape(line));
        *value_r = p_strdup(ctx->pool, dict_client_unescape(value));
-       return 1;
+       return TRUE;
 }
 
-static void client_dict_iterate_deinit(struct dict_iterate_context *_ctx)
+static int client_dict_iterate_deinit(struct dict_iterate_context *_ctx)
 {
        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;
 
        pool_unref(&ctx->pool);
        i_free(ctx);
        dict->in_iteration = FALSE;
+       return ret;
 }
 
 static struct dict_transaction_context *
index c42d1742d856e74f10f5c789c712d50ba47a5970..6c4d136937bbaea255cc743ce2da83044ab569fd 100644 (file)
@@ -34,6 +34,7 @@ struct db_dict_iterate_context {
                            const char **key_r, const char **value_r);
 
        enum dict_iterate_flags flags;
+       bool failed;
 };
 
 struct db_dict_transaction_context {
@@ -341,24 +342,30 @@ db_dict_iterate_init(struct dict *_dict, const char *path,
        return &ctx->ctx;
 }
 
-static int db_dict_iterate(struct dict_iterate_context *_ctx,
-                          const char **key_r, const char **value_r)
+static bool db_dict_iterate(struct dict_iterate_context *_ctx,
+                           const char **key_r, const char **value_r)
 {
        struct db_dict_iterate_context *ctx =
                (struct db_dict_iterate_context *)_ctx;
+       int ret;
 
-       return ctx->iterate_next(ctx, key_r, value_r);
+       ret = ctx->iterate_next(ctx, key_r, value_r);
+       if (ret < 0)
+               ctx->failed = TRUE;
+       return ret > 0;
 }
 
-static void db_dict_iterate_deinit(struct dict_iterate_context *_ctx)
+static int db_dict_iterate_deinit(struct dict_iterate_context *_ctx)
 {
        struct db_dict_iterate_context *ctx =
                (struct db_dict_iterate_context *)_ctx;
+       int ret = ctx->failed ? -1 : 0;
 
        ctx->cursor->c_close(ctx->cursor);
        pool_unref(&ctx->pool);
        i_free(ctx->path);
        i_free(ctx);
+       return ret;
 }
 
 static struct dict_transaction_context *
index 4d2f071337ce35f1816d203a3cc15660ee304c4d..fea27c9965ba30996e26049c122f4d38a33ae111 100644 (file)
@@ -181,8 +181,8 @@ file_dict_iterate_init(struct dict *_dict, const char *path,
        return &ctx->ctx;
 }
 
-static int file_dict_iterate(struct dict_iterate_context *_ctx,
-                            const char **key_r, const char **value_r)
+static bool file_dict_iterate(struct dict_iterate_context *_ctx,
+                             const char **key_r, const char **value_r)
 {
        struct file_dict_iterate_context *ctx =
                (struct file_dict_iterate_context *)_ctx;
@@ -198,19 +198,21 @@ static int file_dict_iterate(struct dict_iterate_context *_ctx,
 
                *key_r = key;
                *value_r = value;
-               return 1;
+               return TRUE;
        }
-       return ctx->failed ? -1 : 0;
+       return FALSE;
 }
 
-static void file_dict_iterate_deinit(struct dict_iterate_context *_ctx)
+static int file_dict_iterate_deinit(struct dict_iterate_context *_ctx)
 {
        struct file_dict_iterate_context *ctx =
                (struct file_dict_iterate_context *)_ctx;
+       int ret = ctx->failed ? -1 : 0;
 
        hash_table_iterate_deinit(&ctx->iter);
        i_free(ctx->path);
        i_free(ctx);
+       return ret;
 }
 
 static struct dict_transaction_context *
index 9e29e8b3dfa0545457f0f120a7fbaaea8ae63f1a..1ff040bd00523952fbf00937927dd9683499b266 100644 (file)
@@ -16,9 +16,9 @@ struct dict_vfuncs {
        struct dict_iterate_context *
                (*iterate_init)(struct dict *dict, const char *path,
                                enum dict_iterate_flags flags);
-       int (*iterate)(struct dict_iterate_context *ctx,
-                      const char **key_r, const char **value_r);
-       void (*iterate_deinit)(struct dict_iterate_context *ctx);
+       bool (*iterate)(struct dict_iterate_context *ctx,
+                       const char **key_r, const char **value_r);
+       int (*iterate_deinit)(struct dict_iterate_context *ctx);
 
        struct dict_transaction_context *(*transaction_init)(struct dict *dict);
        int (*transaction_commit)(struct dict_transaction_context *ctx,
index 899aef870f1c534634f61afacf4a5a6cfe5ff3ed..686369354d16c6a3f1b1195bef215eaff5c9ee65 100644 (file)
@@ -42,6 +42,7 @@ struct sql_dict_iterate_context {
        string_t *key;
        const struct dict_sql_map *map;
        unsigned int key_prefix_len, pattern_prefix_len, next_map_idx;
+       bool failed;
 };
 
 struct sql_dict_inc_row {
@@ -397,8 +398,8 @@ sql_dict_iterate_init(struct dict *_dict, const char *path,
        return &ctx->ctx;
 }
 
-static int sql_dict_iterate(struct dict_iterate_context *_ctx,
-                           const char **key_r, const char **value_r)
+static bool sql_dict_iterate(struct dict_iterate_context *_ctx,
+                            const char **key_r, const char **value_r)
 {
        struct sql_dict_iterate_context *ctx =
                (struct sql_dict_iterate_context *)_ctx;
@@ -406,18 +407,21 @@ static int sql_dict_iterate(struct dict_iterate_context *_ctx,
        unsigned int i, count;
        int ret;
 
-       if (ctx->result == NULL)
-               return -1;
+       if (ctx->result == NULL) {
+               ctx->failed = TRUE;
+               return FALSE;
+       }
 
        while ((ret = sql_result_next_row(ctx->result)) == 0) {
                /* see if there are more results in the next map */
                if (!sql_dict_iterate_next_query(ctx))
-                       return 0;
+                       return FALSE;
        }
        if (ret < 0) {
+               ctx->failed = TRUE;
                i_error("dict sql iterate failed: %s",
                        sql_result_get_error(ctx->result));
-               return ret;
+               return FALSE;
        }
 
        /* convert fetched row to dict key */
@@ -442,19 +446,21 @@ static int sql_dict_iterate(struct dict_iterate_context *_ctx,
 
        *key_r = str_c(ctx->key);
        *value_r = sql_result_get_field_value(ctx->result, 0);
-       return 1;
+       return TRUE;
 }
 
-static void sql_dict_iterate_deinit(struct dict_iterate_context *_ctx)
+static int sql_dict_iterate_deinit(struct dict_iterate_context *_ctx)
 {
        struct sql_dict_iterate_context *ctx =
                (struct sql_dict_iterate_context *)_ctx;
+       int ret = ctx->failed ? -1 : 0;
 
        if (ctx->result != NULL)
                sql_result_unref(ctx->result);
        str_free(&ctx->key);
        i_free(ctx->path);
        i_free(ctx);
+       return ret;
 }
 
 static struct dict_transaction_context *
index 7e955e95352a6bec735504619df4c0366c2d593f..6f52615a0911e195d6ab5be8fdb2e27e58db8c27 100644 (file)
@@ -122,18 +122,18 @@ dict_iterate_init(struct dict *dict, const char *path,
        return dict->v.iterate_init(dict, path, flags);
 }
 
-int dict_iterate(struct dict_iterate_context *ctx,
-                const char **key_r, const char **value_r)
+bool dict_iterate(struct dict_iterate_context *ctx,
+                 const char **key_r, const char **value_r)
 {
        return ctx->dict->v.iterate(ctx, key_r, value_r);
 }
 
-void dict_iterate_deinit(struct dict_iterate_context **_ctx)
+int dict_iterate_deinit(struct dict_iterate_context **_ctx)
 {
        struct dict_iterate_context *ctx = *_ctx;
 
        *_ctx = NULL;
-       ctx->dict->v.iterate_deinit(ctx);
+       return ctx->dict->v.iterate_deinit(ctx);
 }
 
 struct dict_transaction_context *dict_transaction_begin(struct dict *dict)
index 8f15ae979421bb1bcdb6a4916d5d075c3e342f8e..3f8072dd4c28a11e8ee11f935d8ff9bb882bf677 100644 (file)
@@ -48,10 +48,10 @@ int dict_lookup(struct dict *dict, pool_t pool,
 struct dict_iterate_context *
 dict_iterate_init(struct dict *dict, const char *path, 
                  enum dict_iterate_flags flags);
-/* Returns -1 = error, 0 = finished, 1 = key/value set */
-int dict_iterate(struct dict_iterate_context *ctx,
-                const char **key_r, const char **value_r);
-void dict_iterate_deinit(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);
 
 /* Start a new dictionary transaction. */
 struct dict_transaction_context *dict_transaction_begin(struct dict *dict);
index 7878a926164922ea4420c38d37bb737d1ad4325f..18897ba438f20ce432ea440fe493c857865c5e85 100644 (file)
@@ -154,7 +154,7 @@ acl_lookup_dict_rebuild_update(struct acl_lookup_dict *dict,
        prefix = DICT_PATH_SHARED DICT_SHARED_BOXES_PATH;
        prefix_len = strlen(prefix);
        iter = dict_iterate_init(dict->dict, prefix, DICT_ITERATE_FLAG_RECURSE);
-       while ((ret = dict_iterate(iter, &key, &value)) > 0) {
+       while (dict_iterate(iter, &key, &value)) {
                /* prefix/$dest/$source */
                key += prefix_len;
                p = strchr(key, '/');
@@ -163,8 +163,7 @@ acl_lookup_dict_rebuild_update(struct acl_lookup_dict *dict,
                        array_append(&old_ids_arr, &key, 1);
                }
        }
-       dict_iterate_deinit(&iter);
-       if (ret < 0) {
+       if (dict_iterate_deinit(&iter) < 0) {
                i_error("acl: dict iteration failed, can't update dict");
                return -1;
        }
@@ -300,19 +299,16 @@ const char *
 acl_lookup_dict_iterate_visible_next(struct acl_lookup_dict_iter *iter)
 {
        const char *key, *value;
-       int ret;
 
        if (iter->dict_iter == NULL)
                return 0;
 
-       ret = dict_iterate(iter->dict_iter, &key, &value);
-       if (ret > 0) {
+       if (dict_iterate(iter->dict_iter, &key, &value)) {
                i_assert(iter->prefix_len < strlen(key));
                return key + iter->prefix_len;
        }
-       if (ret < 0)
+       if (dict_iterate_deinit(&iter->dict_iter) < 0)
                iter->failed = TRUE;
-       dict_iterate_deinit(&iter->dict_iter);
 
        if (iter->iter_idx < array_count(&iter->iter_ids)) {
                /* get to the next iterator */
@@ -328,8 +324,10 @@ int acl_lookup_dict_iterate_visible_deinit(struct acl_lookup_dict_iter **_iter)
        int ret = iter->failed ? -1 : 0;
 
        *_iter = NULL;
-       if (iter->dict_iter != NULL)
-               dict_iterate_deinit(&iter->dict_iter);
+       if (iter->dict_iter != NULL) {
+               if (dict_iterate_deinit(&iter->dict_iter) < 0)
+                       ret = -1;
+       }
        pool_unref(&iter->pool);
        return ret;
 }
index 2195a7fadd532a1e0bbdb2fab78a3c1591dc000b..18d80e422443c755f36255e9cb087143ecf80004 100644 (file)
@@ -231,7 +231,7 @@ static void expire_run(struct master_service *service, bool testrun)
                                 DICT_ITERATE_FLAG_SORT_BY_VALUE);
 
        /* We'll get the oldest values (timestamps) first */
-       while ((ret = dict_iterate(iter, &key, &value)) > 0) {
+       while (dict_iterate(iter, &key, &value)) {
                /* key = DICT_EXPIRE_PREFIX<user>/<mailbox> */
                userp = key + strlen(DICT_EXPIRE_PREFIX);
 
@@ -264,7 +264,6 @@ static void expire_run(struct master_service *service, bool testrun)
 
                if (ret < 0) {
                        /* failed to update */
-                       ret = 0;
                } else if (next_expire == 0) {
                        /* no more messages or mailbox deleted */
                        if (!testrun)
@@ -289,12 +288,11 @@ static void expire_run(struct master_service *service, bool testrun)
                        } T_END;
                }
        }
-       if (ret < 0)
+       if (dict_iterate_deinit(&iter) < 0)
                i_error("Dictionary iteration failed");
        if (testrun && userp == NULL)
                i_info("No entries in dictionary");
 
-       dict_iterate_deinit(&iter);
        if (!testrun)
                dict_transaction_commit(&trans);
        else