"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/lib-dict/dict-memcached-ascii.c" between
dovecot-2.3.16.tar.gz and dovecot-2.3.17.tar.gz

About: Dovecot is an IMAP and POP3 server, written with security primarily in mind.

dict-memcached-ascii.c  (dovecot-2.3.16):dict-memcached-ascii.c  (dovecot-2.3.17)
skipping to change at line 55 skipping to change at line 55
struct dict_transaction_memory_context *memctx; struct dict_transaction_memory_context *memctx;
string_t *str; string_t *str;
dict_transaction_commit_callback_t *callback; dict_transaction_commit_callback_t *callback;
void *context; void *context;
}; };
struct memcached_ascii_dict { struct memcached_ascii_dict {
struct dict dict; struct dict dict;
struct ip_addr ip; struct ip_addr ip;
char *username, *key_prefix; char *key_prefix;
in_port_t port; in_port_t port;
unsigned int timeout_msecs; unsigned int timeout_msecs;
struct timeout *to; struct timeout *to;
struct memcached_ascii_connection conn; struct memcached_ascii_connection conn;
ARRAY(enum memcached_ascii_input_state) input_states; ARRAY(enum memcached_ascii_input_state) input_states;
ARRAY(struct memcached_ascii_dict_reply) replies; ARRAY(struct memcached_ascii_dict_reply) replies;
}; };
skipping to change at line 442 skipping to change at line 442
} }
dict->conn.conn.event_parent = set->event_parent; dict->conn.conn.event_parent = set->event_parent;
connection_init_client_ip(memcached_ascii_connections, &dict->conn.conn, connection_init_client_ip(memcached_ascii_connections, &dict->conn.conn,
NULL, &dict->ip, dict->port); NULL, &dict->ip, dict->port);
event_set_append_log_prefix(dict->conn.conn.event, "memcached: "); event_set_append_log_prefix(dict->conn.conn.event, "memcached: ");
dict->dict = *driver; dict->dict = *driver;
dict->conn.reply_str = str_new(default_pool, 256); dict->conn.reply_str = str_new(default_pool, 256);
dict->conn.dict = dict; dict->conn.dict = dict;
if (strchr(set->username, DICT_USERNAME_SEPARATOR) == NULL)
dict->username = i_strdup(set->username);
else {
/* escape the username */
dict->username = i_strdup(memcached_ascii_escape_username(set->us
ername));
}
i_array_init(&dict->input_states, 4); i_array_init(&dict->input_states, 4);
i_array_init(&dict->replies, 4); i_array_init(&dict->replies, 4);
dict->dict.ioloop = io_loop_create(); dict->dict.ioloop = io_loop_create();
io_loop_set_current(old_ioloop); io_loop_set_current(old_ioloop);
*dict_r = &dict->dict; *dict_r = &dict->dict;
return 0; return 0;
} }
static void memcached_ascii_dict_deinit(struct dict *_dict) static void memcached_ascii_dict_deinit(struct dict *_dict)
skipping to change at line 478 skipping to change at line 472
connection_deinit(&dict->conn.conn); connection_deinit(&dict->conn.conn);
io_loop_set_current(dict->dict.ioloop); io_loop_set_current(dict->dict.ioloop);
io_loop_destroy(&dict->dict.ioloop); io_loop_destroy(&dict->dict.ioloop);
io_loop_set_current(old_ioloop); io_loop_set_current(old_ioloop);
str_free(&dict->conn.reply_str); str_free(&dict->conn.reply_str);
array_free(&dict->replies); array_free(&dict->replies);
array_free(&dict->input_states); array_free(&dict->input_states);
i_free(dict->key_prefix); i_free(dict->key_prefix);
i_free(dict->username);
i_free(dict); i_free(dict);
if (memcached_ascii_connections->connections == NULL) if (memcached_ascii_connections->connections == NULL)
connection_list_deinit(&memcached_ascii_connections); connection_list_deinit(&memcached_ascii_connections);
} }
static int memcached_ascii_connect(struct memcached_ascii_dict *dict, static int memcached_ascii_connect(struct memcached_ascii_dict *dict,
const char **error_r) const char **error_r)
{ {
if (dict->conn.conn.input != NULL) if (dict->conn.conn.input != NULL)
skipping to change at line 504 skipping to change at line 497
"memcached_ascii: Couldn't connect to %s:%u", "memcached_ascii: Couldn't connect to %s:%u",
net_ip2addr(&dict->ip), dict->port); net_ip2addr(&dict->ip), dict->port);
return -1; return -1;
} }
} }
return memcached_ascii_wait(dict, error_r); return memcached_ascii_wait(dict, error_r);
} }
static const char * static const char *
memcached_ascii_dict_get_full_key(struct memcached_ascii_dict *dict, memcached_ascii_dict_get_full_key(struct memcached_ascii_dict *dict,
const char *key) const char *username, const char *key)
{ {
if (str_begins(key, DICT_PATH_SHARED)) if (str_begins(key, DICT_PATH_SHARED))
key += strlen(DICT_PATH_SHARED); key += strlen(DICT_PATH_SHARED);
else if (str_begins(key, DICT_PATH_PRIVATE)) { else if (str_begins(key, DICT_PATH_PRIVATE)) {
key = t_strdup_printf("%s%c%s", dict->username, if (strchr(username, DICT_USERNAME_SEPARATOR) == NULL) {
DICT_USERNAME_SEPARATOR, key = t_strdup_printf("%s%c%s", username,
key + strlen(DICT_PATH_PRIVATE)); DICT_USERNAME_SEPARATOR,
key + strlen(DICT_PATH_PRIVATE));
} else {
/* escape the username */
key = t_strdup_printf("%s%c%s", memcached_ascii_escape_us
ername(username),
DICT_USERNAME_SEPARATOR,
key + strlen(DICT_PATH_PRIVATE));
}
} else { } else {
i_unreached(); i_unreached();
} }
if (*dict->key_prefix != '\0') if (*dict->key_prefix != '\0')
key = t_strconcat(dict->key_prefix, key, NULL); key = t_strconcat(dict->key_prefix, key, NULL);
return key; return key;
} }
static int static int
memcached_ascii_dict_lookup(struct dict *_dict, pool_t pool, const char *key, memcached_ascii_dict_lookup(struct dict *_dict,
const char **value_r, const char **error_r) const struct dict_op_settings *set,
pool_t pool, const char *key, const char **value_r,
const char **error_r)
{ {
struct memcached_ascii_dict *dict = (struct memcached_ascii_dict *)_dict; struct memcached_ascii_dict *dict = (struct memcached_ascii_dict *)_dict;
struct memcached_ascii_dict_reply *reply; struct memcached_ascii_dict_reply *reply;
enum memcached_ascii_input_state state = MEMCACHED_INPUT_STATE_GET; enum memcached_ascii_input_state state = MEMCACHED_INPUT_STATE_GET;
if (memcached_ascii_connect(dict, error_r) < 0) if (memcached_ascii_connect(dict, error_r) < 0)
return -1; return -1;
key = memcached_ascii_dict_get_full_key(dict, key); key = memcached_ascii_dict_get_full_key(dict, set->username, key);
o_stream_nsend_str(dict->conn.conn.output, o_stream_nsend_str(dict->conn.conn.output,
t_strdup_printf("get %s\r\n", key)); t_strdup_printf("get %s\r\n", key));
array_push_back(&dict->input_states, &state); array_push_back(&dict->input_states, &state);
reply = array_append_space(&dict->replies); reply = array_append_space(&dict->replies);
reply->reply_count = 1; reply->reply_count = 1;
if (memcached_ascii_wait(dict, error_r) < 0) if (memcached_ascii_wait(dict, error_r) < 0)
return -1; return -1;
skipping to change at line 560 skipping to change at line 562
pool_t pool; pool_t pool;
pool = pool_alloconly_create("file dict transaction", 2048); pool = pool_alloconly_create("file dict transaction", 2048);
ctx = p_new(pool, struct dict_transaction_memory_context, 1); ctx = p_new(pool, struct dict_transaction_memory_context, 1);
dict_transaction_memory_init(ctx, _dict, pool); dict_transaction_memory_init(ctx, _dict, pool);
return &ctx->ctx; return &ctx->ctx;
} }
static void static void
memcached_send_change(struct dict_memcached_ascii_commit_ctx *ctx, memcached_send_change(struct dict_memcached_ascii_commit_ctx *ctx,
const struct dict_op_settings_private *set,
const struct dict_transaction_memory_change *change) const struct dict_transaction_memory_change *change)
{ {
enum memcached_ascii_input_state state; enum memcached_ascii_input_state state;
const char *key, *value; const char *key, *value;
key = memcached_ascii_dict_get_full_key(ctx->dict, change->key); key = memcached_ascii_dict_get_full_key(ctx->dict, set->username,
change->key);
str_truncate(ctx->str, 0); str_truncate(ctx->str, 0);
switch (change->type) { switch (change->type) {
case DICT_CHANGE_TYPE_SET: case DICT_CHANGE_TYPE_SET:
state = MEMCACHED_INPUT_STATE_STORED; state = MEMCACHED_INPUT_STATE_STORED;
str_printfa(ctx->str, "set %s 0 0 %zu\r\n%s\r\n", str_printfa(ctx->str, "set %s 0 0 %zu\r\n%s\r\n",
key, strlen(change->value.str), change->value.str); key, strlen(change->value.str), change->value.str);
break; break;
case DICT_CHANGE_TYPE_UNSET: case DICT_CHANGE_TYPE_UNSET:
state = MEMCACHED_INPUT_STATE_DELETED; state = MEMCACHED_INPUT_STATE_DELETED;
skipping to change at line 601 skipping to change at line 605
} }
break; break;
} }
array_push_back(&ctx->dict->input_states, &state); array_push_back(&ctx->dict->input_states, &state);
o_stream_nsend(ctx->dict->conn.conn.output, o_stream_nsend(ctx->dict->conn.conn.output,
str_data(ctx->str), str_len(ctx->str)); str_data(ctx->str), str_len(ctx->str));
} }
static int static int
memcached_ascii_transaction_send(struct dict_memcached_ascii_commit_ctx *ctx, memcached_ascii_transaction_send(struct dict_memcached_ascii_commit_ctx *ctx,
const struct dict_op_settings_private *set,
const char **error_r) const char **error_r)
{ {
struct memcached_ascii_dict *dict = ctx->dict; struct memcached_ascii_dict *dict = ctx->dict;
struct memcached_ascii_dict_reply *reply; struct memcached_ascii_dict_reply *reply;
const struct dict_transaction_memory_change *changes; const struct dict_transaction_memory_change *changes;
unsigned int i, count, old_state_count; unsigned int i, count, old_state_count;
if (memcached_ascii_connect(dict, error_r) < 0) if (memcached_ascii_connect(dict, error_r) < 0)
return -1; return -1;
old_state_count = array_count(&dict->input_states); old_state_count = array_count(&dict->input_states);
changes = array_get(&ctx->memctx->changes, &count); changes = array_get(&ctx->memctx->changes, &count);
i_assert(count > 0); i_assert(count > 0);
o_stream_cork(dict->conn.conn.output); o_stream_cork(dict->conn.conn.output);
for (i = 0; i < count; i++) T_BEGIN { for (i = 0; i < count; i++) T_BEGIN {
memcached_send_change(ctx, &changes[i]); memcached_send_change(ctx, set, &changes[i]);
} T_END; } T_END;
o_stream_uncork(dict->conn.conn.output); o_stream_uncork(dict->conn.conn.output);
reply = array_append_space(&dict->replies); reply = array_append_space(&dict->replies);
reply->callback = ctx->callback; reply->callback = ctx->callback;
reply->context = ctx->context; reply->context = ctx->context;
reply->reply_count = array_count(&dict->input_states) - old_state_count; reply->reply_count = array_count(&dict->input_states) - old_state_count;
return 0; return 0;
} }
skipping to change at line 640 skipping to change at line 645
bool async, bool async,
dict_transaction_commit_callback_t *callback, dict_transaction_commit_callback_t *callback,
void *context) void *context)
{ {
struct dict_transaction_memory_context *ctx = struct dict_transaction_memory_context *ctx =
(struct dict_transaction_memory_context *)_ctx; (struct dict_transaction_memory_context *)_ctx;
struct memcached_ascii_dict *dict = struct memcached_ascii_dict *dict =
(struct memcached_ascii_dict *)_ctx->dict; (struct memcached_ascii_dict *)_ctx->dict;
struct dict_memcached_ascii_commit_ctx commit_ctx; struct dict_memcached_ascii_commit_ctx commit_ctx;
struct dict_commit_result result = { DICT_COMMIT_RET_OK, NULL }; struct dict_commit_result result = { DICT_COMMIT_RET_OK, NULL };
const struct dict_op_settings_private *set = &_ctx->set;
if (_ctx->changed) { if (_ctx->changed) {
i_zero(&commit_ctx); i_zero(&commit_ctx);
commit_ctx.dict = dict; commit_ctx.dict = dict;
commit_ctx.memctx = ctx; commit_ctx.memctx = ctx;
commit_ctx.callback = callback; commit_ctx.callback = callback;
commit_ctx.context = context; commit_ctx.context = context;
commit_ctx.str = str_new(default_pool, 128); commit_ctx.str = str_new(default_pool, 128);
result.ret = memcached_ascii_transaction_send(&commit_ctx, &resul t.error); result.ret = memcached_ascii_transaction_send(&commit_ctx, set, & result.error);
str_free(&commit_ctx.str); str_free(&commit_ctx.str);
if (async && result.ret == 0) { if (async && result.ret == 0) {
pool_unref(&ctx->pool); pool_unref(&ctx->pool);
return; return;
} }
if (result.ret == 0) { if (result.ret == 0) {
if (memcached_ascii_wait(dict, &result.error) < 0) if (memcached_ascii_wait(dict, &result.error) < 0)
result.ret = -1; result.ret = -1;
 End of changes. 13 change blocks. 
19 lines changed or deleted 25 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)