/* Copyright (c) 2008-2018 Dovecot authors, see the included COPYING memcached_ascii */
#include "lib.h"
#include "array.h"
#include "str.h"
#include "istream.h"
#include "ostream.h"
#include "connection.h"
#include "dict-transaction-memory.h"
#include "dict-private.h"
enum memcached_ascii_input_state {
/* GET: expecting VALUE or END */
/* SET: expecting STORED / NOT_STORED */
/* DELETE: expecting DELETED */
/* (INCR+ADD)/DECR: expecting number / NOT_FOUND / STORED / NOT_STORED */
};
struct memcached_ascii_connection {
unsigned int reply_bytes_left;
bool value_received;
bool value_waiting_end;
};
struct memcached_ascii_dict_reply {
unsigned int reply_count;
void *context;
};
struct dict_memcached_ascii_commit_ctx {
void *context;
};
struct memcached_ascii_dict {
unsigned int timeout_msecs;
};
static void
const struct memcached_ascii_dict_reply *reply,
const struct dict_commit_result *result)
{
/* Don't let callback see that we've created our
internal ioloop in case it wants to add some ios
or timeouts. */
}
}
}
static void
const char *reason)
{
};
conn->reply_bytes_left = 0;
}
{
(struct memcached_ascii_connection *)_conn;
}
{
const unsigned char *data;
if (conn->reply_bytes_left > 0)
return FALSE;
/* finished. drop the trailing CRLF */
return TRUE;
}
const char **error_r)
{
const char *line, *p;
unsigned int count;
long long num;
if (conn->reply_bytes_left > 0) {
/* continue reading bulk reply */
if (!memcached_ascii_input_value(conn))
return 0;
} else if (conn->value_waiting_end) {
} else {
}
return 0;
if (count == 0) {
"memcached_ascii: Unexpected input (expected nothing): %s", line);
return -1;
}
switch (states[0]) {
/* VALUE <key> <flags> <bytes>
END */
break;
return 1;
break;
break;
return 1;
break;
return 1;
break;
return 1;
}
"memcached_ascii: Unexpected input (state=%d): %s",
return -1;
}
const char **error_r)
{
};
unsigned int count;
int ret;
return ret;
/* finished a reply */
if (--replies[0].reply_count == 0) {
}
return 1;
}
{
(struct memcached_ascii_connection *)_conn;
const char *error;
int ret;
case 0:
return;
case -1:
return;
default:
break;
}
if (ret < 0)
}
const char **error_r)
{
*error_r = "memcached_ascii: Communication failure";
return -1;
}
return 0;
}
{
"memcached_ascii: Request timed out in %u.%03u secs",
}
const char **error_r)
{
int ret = 0;
if (ret < 0)
break;
}
if (ret != 0)
break;
}
return ret < 0 ? -1 : 0;
}
const char **error_r)
{
int ret;
/* waiting for connection to finish */
if (ret < 0)
return -1;
}
return -1;
return 0;
}
static void
{
if (!success) {
i_error("memcached_ascii: connect(%s, %u) failed: %m",
}
}
};
};
{
const char *p;
for (p = username; *p != '\0'; p++) {
switch (*p) {
case DICT_USERNAME_SEPARATOR:
break;
case '\\':
break;
default:
str_append_c(str, *p);
}
}
}
static int
const struct dict_settings *set,
{
const char *const *args;
int ret = 0;
if (memcached_ascii_connections == NULL) {
}
i_unreached();
*args+5);
ret = -1;
}
*args+5);
ret = -1;
}
ret = -1;
}
} else {
*args);
ret = -1;
}
}
if (ret < 0) {
return -1;
}
else {
/* escape the username */
}
return 0;
}
{
(struct memcached_ascii_dict *)_dict;
const char *error;
}
}
const char **error_r)
{
return 0;
"memcached_ascii: Couldn't connect to %s:%u",
return -1;
}
}
}
static const char *
const char *key)
{
} else {
i_unreached();
}
return key;
}
static int
{
return -1;
return -1;
}
static struct dict_transaction_context *
{
}
static void
const struct dict_transaction_memory_change *change)
{
case DICT_CHANGE_TYPE_SET:
break;
case DICT_CHANGE_TYPE_UNSET:
break;
case DICT_CHANGE_TYPE_INC:
/* same kludge as with append */
} else {
}
break;
}
}
static int
const char **error_r)
{
return -1;
} T_END;
return 0;
}
static void
bool async,
void *context)
{
(struct dict_transaction_memory_context *)_ctx;
i_zero(&commit_ctx);
return;
}
}
}
}
.name = "memcached_ascii",
{
}
};