dict-commands.c revision 6cfe560af03491c2ea118e9698a145d8a9ee26b2
c28749e97052f09388969427adf7df641cdcdc22kais/* Copyright (c) 2005-2016 Dovecot authors, see the included COPYING file */
c28749e97052f09388969427adf7df641cdcdc22kais int (*func)(struct dict_connection_cmd *cmd, const char *line);
c28749e97052f09388969427adf7df641cdcdc22kais unsigned int trans_id;
c28749e97052f09388969427adf7df641cdcdc22kaisstatic void dict_connection_cmd_output_more(struct dict_connection_cmd *cmd);
c28749e97052f09388969427adf7df641cdcdc22kaisstatic void dict_connection_cmd_free(struct dict_connection_cmd *cmd)
c28749e97052f09388969427adf7df641cdcdc22kaisstatic void dict_connection_cmd_remove(struct dict_connection_cmd *cmd)
c28749e97052f09388969427adf7df641cdcdc22kais unsigned int i, count;
c28749e97052f09388969427adf7df641cdcdc22kais for (i = 0; i < count; i++) {
c28749e97052f09388969427adf7df641cdcdc22kaisstatic void dict_connection_cmds_flush(struct dict_connection *conn)
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna struct dict_connection_cmd *cmd, *const *first_cmdp;
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna /* command not finished yet */
c28749e97052f09388969427adf7df641cdcdc22kaisstatic void
c28749e97052f09388969427adf7df641cdcdc22kaiscmd_lookup_callback(const struct dict_lookup_result *result, void *context)
c28749e97052f09388969427adf7df641cdcdc22kais cmd->reply = i_strdup_printf("%c\n", DICT_PROTOCOL_REPLY_NOTFOUND);
c28749e97052f09388969427adf7df641cdcdc22kais cmd->reply = i_strdup_printf("%c%s\n", DICT_PROTOCOL_REPLY_FAIL,
c28749e97052f09388969427adf7df641cdcdc22kaisstatic int cmd_lookup(struct dict_connection_cmd *cmd, const char *line)
c28749e97052f09388969427adf7df641cdcdc22kais /* <key> */
c28749e97052f09388969427adf7df641cdcdc22kais dict_lookup_async(cmd->conn->dict, line, cmd_lookup_callback, cmd);
c28749e97052f09388969427adf7df641cdcdc22kaisstatic int cmd_iterate_flush(struct dict_connection_cmd *cmd)
c28749e97052f09388969427adf7df641cdcdc22kais if ((cmd->iter_flags & DICT_ITERATE_FLAG_NO_VALUE) == 0)
c28749e97052f09388969427adf7df641cdcdc22kais o_stream_nsend(cmd->conn->output, str_data(str), str_len(str));
c28749e97052f09388969427adf7df641cdcdc22kais /* continue later when there's more space
c28749e97052f09388969427adf7df641cdcdc22kais in output buffer */
c28749e97052f09388969427adf7df641cdcdc22kais /* flushed everything, continue */
c28749e97052f09388969427adf7df641cdcdc22kais /* wait for the next iteration callback */
efe05f9ecde56550699213909fd4152ef8ef6438krishnastatic int cmd_iterate(struct dict_connection_cmd *cmd, const char *line)
efe05f9ecde56550699213909fd4152ef8ef6438krishna const char *const *args;
efe05f9ecde56550699213909fd4152ef8ef6438krishna unsigned int flags;
c28749e97052f09388969427adf7df641cdcdc22kais return -1;
c28749e97052f09388969427adf7df641cdcdc22kais /* <flags> <path> */
c28749e97052f09388969427adf7df641cdcdc22kais cmd->iter = dict_iterate_init_multiple(cmd->conn->dict, args+1, flags);
c28749e97052f09388969427adf7df641cdcdc22kais dict_iterate_set_async_callback(cmd->iter, cmd_iterate_callback, cmd);
c28749e97052f09388969427adf7df641cdcdc22kaisdict_connection_transaction_lookup(struct dict_connection *conn,
c28749e97052f09388969427adf7df641cdcdc22kais unsigned int id)
c28749e97052f09388969427adf7df641cdcdc22kais array_foreach_modifiable(&conn->transactions, transaction) {
c28749e97052f09388969427adf7df641cdcdc22kaisstatic void
c28749e97052f09388969427adf7df641cdcdc22kaisdict_connection_transaction_array_remove(struct dict_connection *conn,
c28749e97052f09388969427adf7df641cdcdc22kais unsigned int id)
c28749e97052f09388969427adf7df641cdcdc22kais const struct dict_connection_transaction *transactions;
c28749e97052f09388969427adf7df641cdcdc22kais unsigned int i, count;
c28749e97052f09388969427adf7df641cdcdc22kais for (i = 0; i < count; i++) {
efe05f9ecde56550699213909fd4152ef8ef6438krishnastatic int cmd_begin(struct dict_connection_cmd *cmd, const char *line)
efe05f9ecde56550699213909fd4152ef8ef6438krishna unsigned int id;
efe05f9ecde56550699213909fd4152ef8ef6438krishna i_error("dict client: Invalid transaction ID %s", line);
efe05f9ecde56550699213909fd4152ef8ef6438krishna if (dict_connection_transaction_lookup(cmd->conn, id) != NULL) {
efe05f9ecde56550699213909fd4152ef8ef6438krishna i_error("dict client: Transaction ID %u already exists", id);
c28749e97052f09388969427adf7df641cdcdc22kais return -1;
c28749e97052f09388969427adf7df641cdcdc22kais /* <id> */
efe05f9ecde56550699213909fd4152ef8ef6438krishna trans = array_append_space(&cmd->conn->transactions);
efe05f9ecde56550699213909fd4152ef8ef6438krishna trans->ctx = dict_transaction_begin(cmd->conn->dict);
efe05f9ecde56550699213909fd4152ef8ef6438krishnadict_connection_transaction_lookup_parse(struct dict_connection *conn,
efe05f9ecde56550699213909fd4152ef8ef6438krishna const char *line,
efe05f9ecde56550699213909fd4152ef8ef6438krishna unsigned int id;
efe05f9ecde56550699213909fd4152ef8ef6438krishna i_error("dict client: Invalid transaction ID %s", line);
c28749e97052f09388969427adf7df641cdcdc22kais return -1;
efe05f9ecde56550699213909fd4152ef8ef6438krishna *trans_r = dict_connection_transaction_lookup(conn, id);
efe05f9ecde56550699213909fd4152ef8ef6438krishna i_error("dict client: Transaction ID %u doesn't exist", id);
51dd2c77f06e5663c28bd4f7a760cae4cf159e79vk return -1;
efe05f9ecde56550699213909fd4152ef8ef6438krishnacmd_commit_finish(struct dict_connection_cmd *cmd, int ret, bool async)
51dd2c77f06e5663c28bd4f7a760cae4cf159e79vk switch (ret) {
c28749e97052f09388969427adf7df641cdcdc22kais cmd->reply = i_strdup_printf("%c%u\n", chr, cmd->trans_id);
c28749e97052f09388969427adf7df641cdcdc22kais dict_connection_transaction_array_remove(cmd->conn, cmd->trans_id);
c28749e97052f09388969427adf7df641cdcdc22kaisstatic void cmd_commit_callback_async(int ret, void *context)
c28749e97052f09388969427adf7df641cdcdc22kaiscmd_commit(struct dict_connection_cmd *cmd, const char *line)
c28749e97052f09388969427adf7df641cdcdc22kais if (dict_connection_transaction_lookup_parse(cmd->conn, line, &trans) < 0)
c28749e97052f09388969427adf7df641cdcdc22kais return -1;
c28749e97052f09388969427adf7df641cdcdc22kais dict_transaction_commit_async(&trans->ctx, cmd_commit_callback, cmd);
c28749e97052f09388969427adf7df641cdcdc22kaiscmd_commit_async(struct dict_connection_cmd *cmd, const char *line)
c28749e97052f09388969427adf7df641cdcdc22kais if (dict_connection_transaction_lookup_parse(cmd->conn, line, &trans) < 0)
c28749e97052f09388969427adf7df641cdcdc22kais return -1;
c28749e97052f09388969427adf7df641cdcdc22kais dict_transaction_commit_async(&trans->ctx, cmd_commit_callback_async, cmd);
c28749e97052f09388969427adf7df641cdcdc22kaisstatic int cmd_rollback(struct dict_connection_cmd *cmd, const char *line)
c28749e97052f09388969427adf7df641cdcdc22kais if (dict_connection_transaction_lookup_parse(cmd->conn, line, &trans) < 0)
c28749e97052f09388969427adf7df641cdcdc22kais return -1;
c28749e97052f09388969427adf7df641cdcdc22kais dict_connection_transaction_array_remove(cmd->conn, trans->id);
c28749e97052f09388969427adf7df641cdcdc22kaisstatic int cmd_set(struct dict_connection_cmd *cmd, const char *line)
c28749e97052f09388969427adf7df641cdcdc22kais const char *const *args;
c28749e97052f09388969427adf7df641cdcdc22kais /* <id> <key> <value> */
c28749e97052f09388969427adf7df641cdcdc22kais return -1;
c28749e97052f09388969427adf7df641cdcdc22kais if (dict_connection_transaction_lookup_parse(cmd->conn, args[0], &trans) < 0)
c28749e97052f09388969427adf7df641cdcdc22kais return -1;
c28749e97052f09388969427adf7df641cdcdc22kaisstatic int cmd_unset(struct dict_connection_cmd *cmd, const char *line)
c28749e97052f09388969427adf7df641cdcdc22kais const char *const *args;
c28749e97052f09388969427adf7df641cdcdc22kais /* <id> <key> */
c28749e97052f09388969427adf7df641cdcdc22kais return -1;
c28749e97052f09388969427adf7df641cdcdc22kais if (dict_connection_transaction_lookup_parse(cmd->conn, args[0], &trans) < 0)
c28749e97052f09388969427adf7df641cdcdc22kais return -1;
c28749e97052f09388969427adf7df641cdcdc22kaisstatic int cmd_atomic_inc(struct dict_connection_cmd *cmd, const char *line)
c28749e97052f09388969427adf7df641cdcdc22kais const char *const *args;
c28749e97052f09388969427adf7df641cdcdc22kais long long diff;
c28749e97052f09388969427adf7df641cdcdc22kais /* <id> <key> <diff> */
c28749e97052f09388969427adf7df641cdcdc22kais return -1;
c28749e97052f09388969427adf7df641cdcdc22kais if (dict_connection_transaction_lookup_parse(cmd->conn, args[0], &trans) < 0)
c28749e97052f09388969427adf7df641cdcdc22kais return -1;
51dd2c77f06e5663c28bd4f7a760cae4cf159e79vkstatic const struct dict_cmd_func *dict_command_find(enum dict_protocol_cmd cmd)
c28749e97052f09388969427adf7df641cdcdc22kais unsigned int i;
c28749e97052f09388969427adf7df641cdcdc22kais return &cmds[i];
c28749e97052f09388969427adf7df641cdcdc22kaisint dict_command_input(struct dict_connection *conn, const char *line)
c28749e97052f09388969427adf7df641cdcdc22kais cmd_func = dict_command_find((enum dict_protocol_cmd)*line);
c28749e97052f09388969427adf7df641cdcdc22kais return -1;
c28749e97052f09388969427adf7df641cdcdc22kaisstatic void dict_connection_cmd_output_more(struct dict_connection_cmd *cmd)
51144063f3afc862c6cb3f54fd4341724f765075Krishna Yenduri first_cmdp = array_idx(&cmd->conn->cmds, 0);
51144063f3afc862c6cb3f54fd4341724f765075Krishna Yendurivoid dict_connection_cmds_output_more(struct dict_connection *conn)
51144063f3afc862c6cb3f54fd4341724f765075Krishna Yenduri struct dict_connection_cmd *cmd, *const *first_cmdp;
c28749e97052f09388969427adf7df641cdcdc22kais /* only iterators may be returning a lot of data */
c28749e97052f09388969427adf7df641cdcdc22kais /* unfinished */
c28749e97052f09388969427adf7df641cdcdc22kais /* cmd should be freed now */