-/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- *
- * Libmemcached library
- *
- * Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * * The names of its contributors may not be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
+/*
+ +--------------------------------------------------------------------+
+ | libmemcached - C/C++ Client Library for memcached |
+ +--------------------------------------------------------------------+
+ | Redistribution and use in source and binary forms, with or without |
+ | modification, are permitted under the terms of the BSD license. |
+ | You should have received a copy of the license in a bundled file |
+ | named LICENSE; in case you did not receive a copy you can review |
+ | the terms online at: https://opensource.org/licenses/BSD-3-Clause |
+ +--------------------------------------------------------------------+
+ | Copyright (c) 2006-2014 Brian Aker https://datadifferential.com/ |
+ | Copyright (c) 2020 Michael Wallner <mike@php.net> |
+ +--------------------------------------------------------------------+
+*/
#include "libmemcachedprotocol/common.h"
#include <string.h>
#include <errno.h>
-
-static void print_ascii_command(memcached_protocol_client_st *client)
-{
- if (client->is_verbose)
- {
- switch (client->ascii_command)
- {
+static void print_ascii_command(memcached_protocol_client_st *client) {
+ if (client->is_verbose) {
+ switch (client->ascii_command) {
case SET_CMD:
fprintf(stderr, "%s:%d SET_CMD\n", __FILE__, __LINE__);
break;
case UNKNOWN_CMD:
fprintf(stderr, "%s:%d UNKNOWN_CMD\n", __FILE__, __LINE__);
break;
-
}
}
}
* characters or invalid length)
* @todo add length!
*/
-static uint16_t parse_ascii_key(char **start)
-{
- uint16_t len= 0;
- char *c= *start;
+static uint16_t parse_ascii_key(char **start) {
+ uint16_t len = 0;
+ char *c = *start;
/* Strip leading whitespaces */
- while (isspace(*c))
- {
+ while (isspace(*c)) {
++c;
}
- *start= c;
+ *start = c;
- while (*c != '\0' && !isspace(*c) && !iscntrl(*c))
- {
+ while (*c != '\0' && !isspace(*c) && !iscntrl(*c)) {
++c;
++len;
}
-
- if (len == 0 || len > 240 || (*c != '\0' && *c != '\r' && iscntrl(*c)))
- {
+ if (len == 0 || len > 240 || (*c != '\0' && *c != '\r' && iscntrl(*c))) {
return 0;
}
* @param text the text to spool
* @return status of the spool operation
*/
-static protocol_binary_response_status ascii_raw_response_handler(memcached_protocol_client_st *client, const char *text)
-{
- if (client->is_verbose)
- {
+static protocol_binary_response_status
+ascii_raw_response_handler(memcached_protocol_client_st *client, const char *text) {
+ if (client->is_verbose) {
fprintf(stderr, "%s:%d %s\n", __FILE__, __LINE__, text);
}
- if (client->root->drain(client) == false)
- {
+ if (client->root->drain(client) == false) {
return PROTOCOL_BINARY_RESPONSE_EINTERNAL;
}
- assert(client->output != NULL);
+ assert(client->output);
#if 0
if (client->output == NULL)
{
* format of the command being sent
* @param client the client to send the message to
*/
-static void send_command_usage(memcached_protocol_client_st *client)
-{
- const char *errmsg[]= {
- [GET_CMD]= "CLIENT_ERROR: Syntax error: get <key>*\r\n",
- [GETS_CMD]= "CLIENT_ERROR: Syntax error: gets <key>*\r\n",
- [SET_CMD]= "CLIENT_ERROR: Syntax error: set <key> <flags> <exptime> <bytes> [noreply]\r\n",
- [ADD_CMD]= "CLIENT_ERROR: Syntax error: add <key> <flags> <exptime> <bytes> [noreply]\r\n",
- [REPLACE_CMD]= "CLIENT_ERROR: Syntax error: replace <key> <flags> <exptime> <bytes> [noreply]\r\n",
- [CAS_CMD]= "CLIENT_ERROR: Syntax error: cas <key> <flags> <exptime> <bytes> <casid> [noreply]\r\n",
- [APPEND_CMD]= "CLIENT_ERROR: Syntax error: append <key> <flags> <exptime> <bytes> [noreply]\r\n",
- [PREPEND_CMD]= "CLIENT_ERROR: Syntax error: prepend <key> <flags> <exptime> <bytes> [noreply]\r\n",
- [DELETE_CMD]= "CLIENT_ERROR: Syntax error: delete_object <key> [noreply]\r\n",
- [INCR_CMD]= "CLIENT_ERROR: Syntax error: incr <key> <value> [noreply]\r\n",
- [DECR_CMD]= "CLIENT_ERROR: Syntax error: decr <key> <value> [noreply]\r\n",
- [STATS_CMD]= "CLIENT_ERROR: Syntax error: stats [key]\r\n",
- [FLUSH_ALL_CMD]= "CLIENT_ERROR: Syntax error: flush_all [timeout] [noreply]\r\n",
- [VERSION_CMD]= "CLIENT_ERROR: Syntax error: version\r\n",
- [QUIT_CMD]="CLIENT_ERROR: Syntax error: quit\r\n",
-
- [VERBOSITY_CMD]= "CLIENT_ERROR: Syntax error: verbosity <num>\r\n",
- [UNKNOWN_CMD]= "CLIENT_ERROR: Unknown command\r\n",
+static void send_command_usage(memcached_protocol_client_st *client) {
+ const char *errmsg[] = {
+ [GET_CMD] = "CLIENT_ERROR: Syntax error: get <key>*\r\n",
+ [GETS_CMD] = "CLIENT_ERROR: Syntax error: gets <key>*\r\n",
+ [SET_CMD] = "CLIENT_ERROR: Syntax error: set <key> <flags> <exptime> <bytes> [noreply]\r\n",
+ [ADD_CMD] = "CLIENT_ERROR: Syntax error: add <key> <flags> <exptime> <bytes> [noreply]\r\n",
+ [REPLACE_CMD] =
+ "CLIENT_ERROR: Syntax error: replace <key> <flags> <exptime> <bytes> [noreply]\r\n",
+ [CAS_CMD] =
+ "CLIENT_ERROR: Syntax error: cas <key> <flags> <exptime> <bytes> <casid> [noreply]\r\n",
+ [APPEND_CMD] =
+ "CLIENT_ERROR: Syntax error: append <key> <flags> <exptime> <bytes> [noreply]\r\n",
+ [PREPEND_CMD] =
+ "CLIENT_ERROR: Syntax error: prepend <key> <flags> <exptime> <bytes> [noreply]\r\n",
+ [DELETE_CMD] = "CLIENT_ERROR: Syntax error: delete_object <key> [noreply]\r\n",
+ [INCR_CMD] = "CLIENT_ERROR: Syntax error: incr <key> <value> [noreply]\r\n",
+ [DECR_CMD] = "CLIENT_ERROR: Syntax error: decr <key> <value> [noreply]\r\n",
+ [STATS_CMD] = "CLIENT_ERROR: Syntax error: stats [key]\r\n",
+ [FLUSH_ALL_CMD] = "CLIENT_ERROR: Syntax error: flush_all [timeout] [noreply]\r\n",
+ [VERSION_CMD] = "CLIENT_ERROR: Syntax error: version\r\n",
+ [QUIT_CMD] = "CLIENT_ERROR: Syntax error: quit\r\n",
+
+ [VERBOSITY_CMD] = "CLIENT_ERROR: Syntax error: verbosity <num>\r\n",
+ [UNKNOWN_CMD] = "CLIENT_ERROR: Unknown command\r\n",
};
client->mute = false;
* @param text the length of the body
* @param textlen the length of the body
*/
-static protocol_binary_response_status ascii_version_response_handler(const void *cookie,
- const void *text,
- uint32_t textlen)
-{
- memcached_protocol_client_st *client= (memcached_protocol_client_st*)cookie;
+static protocol_binary_response_status
+ascii_version_response_handler(const void *cookie, const void *text, uint32_t textlen) {
+ memcached_protocol_client_st *client = (memcached_protocol_client_st *) cookie;
ascii_raw_response_handler(client, "VERSION ");
client->root->spool(client, text, textlen);
ascii_raw_response_handler(client, "\r\n");
* @param cas the CAS id for the item
*/
static protocol_binary_response_status
-ascii_get_response_handler(const void *cookie,
- const void *key,
- uint16_t keylen,
- const void *body,
- uint32_t bodylen,
- uint32_t flags,
- uint64_t cas)
-{
- memcached_protocol_client_st *client= (void*)cookie;
+ascii_get_response_handler(const void *cookie, const void *key, uint16_t keylen, const void *body,
+ uint32_t bodylen, uint32_t flags, uint64_t cas) {
+ memcached_protocol_client_st *client = (void *) cookie;
char buffer[300];
strcpy(buffer, "VALUE ");
- const char *source= key;
- char *dest= buffer + 6;
+ const char *source = key;
+ char *dest = buffer + 6;
- for (int x= 0; x < keylen; ++x)
- {
- if (*source != '\0' && !isspace(*source) && !iscntrl(*source))
- {
- *dest= *source;
- }
- else
- {
+ for (int x = 0; x < keylen; ++x) {
+ if (*source != '\0' && !isspace(*source) && !iscntrl(*source)) {
+ *dest = *source;
+ } else {
return PROTOCOL_BINARY_RESPONSE_EINVAL; /* key constraints in ascii */
}
++source;
}
- size_t used= (size_t)(dest - buffer);
+ size_t used = (size_t)(dest - buffer);
- if (client->ascii_command == GETS_CMD)
- {
- snprintf(dest, sizeof(buffer) - used, " %u %u %" PRIu64 "\r\n", flags,
- bodylen, cas);
- }
- else
- {
+ if (client->ascii_command == GETS_CMD) {
+ snprintf(dest, sizeof(buffer) - used, " %u %u %" PRIu64 "\r\n", flags, bodylen, cas);
+ } else {
snprintf(dest, sizeof(buffer) - used, " %u %u\r\n", flags, bodylen);
}
* @param bodylen the length of the body
*/
static protocol_binary_response_status ascii_stat_response_handler(const void *cookie,
- const void *key,
- uint16_t keylen,
+ const void *key, uint16_t keylen,
const void *body,
- uint32_t bodylen)
-{
-
- memcached_protocol_client_st *client= (void*)cookie;
+ uint32_t bodylen) {
+ memcached_protocol_client_st *client = (void *) cookie;
- if (key != NULL)
- {
+ if (key) {
ascii_raw_response_handler(client, "STAT ");
client->root->spool(client, key, keylen);
ascii_raw_response_handler(client, " ");
client->root->spool(client, body, bodylen);
ascii_raw_response_handler(client, "\r\n");
- }
- else
- {
+ } else {
ascii_raw_response_handler(client, "END\r\n");
}
* @param buffer the complete get(s) command
* @param end the last character in the command
*/
-static void ascii_process_gets(memcached_protocol_client_st *client,
- char *buffer, char *end)
-{
- char *key= buffer;
+static void ascii_process_gets(memcached_protocol_client_st *client, char *buffer, char *end) {
+ char *key = buffer;
/* Skip command */
key += (client->ascii_command == GETS_CMD) ? 5 : 4;
- int num_keys= 0;
- while (key < end)
- {
- uint16_t nkey= parse_ascii_key(&key);
- if (nkey == 0) /* Invalid key... stop processing this line */
- {
+ int num_keys = 0;
+ while (key < end) {
+ uint16_t nkey = parse_ascii_key(&key);
+ if (nkey == 0) /* Invalid key... stop processing this line */ {
break;
}
- (void)client->root->callback->interface.v1.get(client, key, nkey,
- ascii_get_response_handler);
+ (void) client->root->callback->interface.v1.get(client, key, nkey, ascii_get_response_handler);
key += nkey;
++num_keys;
}
- if (num_keys == 0)
- {
+ if (num_keys == 0) {
send_command_usage(client);
- }
- else
- {
+ } else {
client->root->spool(client, "END\r\n", 5);
}
}
* @size the number of elements in the vector
* @return the number of tokens in the vector
*/
-static int ascii_tokenize_command(char *str, char *end, char **vec, int size)
-{
- int elem= 0;
+static int ascii_tokenize_command(char *str, char *end, char **vec, int size) {
+ int elem = 0;
- while (str < end)
- {
+ while (str < end) {
/* Skip leading blanks */
- while (str < end && isspace(*str))
- {
+ while (str < end && isspace(*str)) {
++str;
}
- if (str == end)
- {
+ if (str == end) {
return elem;
}
- vec[elem++]= str;
+ vec[elem++] = str;
/* find the next non-blank field */
- while (str < end && !isspace(*str))
- {
+ while (str < end && !isspace(*str)) {
++str;
}
/* zero-terminate it for easier parsing later on */
- *str= '\0';
+ *str = '\0';
++str;
/* Is the vector full? */
- if (elem == size)
- {
+ if (elem == size) {
break;
}
}
* @param start pointer to the first character in the buffer to recover
* @param end pointer to the last character in the buffer to recover
*/
-static void recover_tokenize_command(char *start, char *end)
-{
- while (start < end)
- {
+static void recover_tokenize_command(char *start, char *end) {
+ while (start < end) {
if (*start == '\0')
- *start= ' ';
+ *start = ' ';
++start;
}
- *end= '\n';
+ *end = '\n';
}
/**
* Convert the textual command into a comcode
*/
-static enum ascii_cmd ascii_to_cmd(char *start, size_t length)
-{
+static enum ascii_cmd ascii_to_cmd(char *start, size_t length) {
struct {
const char *cmd;
size_t len;
enum ascii_cmd cc;
- } commands[]= {
- { .cmd= "get", .len= 3, .cc= GET_CMD },
- { .cmd= "gets", .len= 4, .cc= GETS_CMD },
- { .cmd= "set", .len= 3, .cc= SET_CMD },
- { .cmd= "add", .len= 3, .cc= ADD_CMD },
- { .cmd= "replace", .len= 7, .cc= REPLACE_CMD },
- { .cmd= "cas", .len= 3, .cc= CAS_CMD },
- { .cmd= "append", .len= 6, .cc= APPEND_CMD },
- { .cmd= "prepend", .len= 7, .cc= PREPEND_CMD },
- { .cmd= "delete_object", .len= 6, .cc= DELETE_CMD },
- { .cmd= "incr", .len= 4, .cc= INCR_CMD },
- { .cmd= "decr", .len= 4, .cc= DECR_CMD },
- { .cmd= "stats", .len= 5, .cc= STATS_CMD },
- { .cmd= "flush_all", .len= 9, .cc= FLUSH_ALL_CMD },
- { .cmd= "version", .len= 7, .cc= VERSION_CMD },
- { .cmd= "quit", .len= 4, .cc= QUIT_CMD },
- { .cmd= "verbosity", .len= 9, .cc= VERBOSITY_CMD },
- { .cmd= NULL, .len= 0, .cc= UNKNOWN_CMD }};
-
- int x= 0;
+ } commands[] = {{.cmd = "get", .len = 3, .cc = GET_CMD},
+ {.cmd = "gets", .len = 4, .cc = GETS_CMD},
+ {.cmd = "set", .len = 3, .cc = SET_CMD},
+ {.cmd = "add", .len = 3, .cc = ADD_CMD},
+ {.cmd = "replace", .len = 7, .cc = REPLACE_CMD},
+ {.cmd = "cas", .len = 3, .cc = CAS_CMD},
+ {.cmd = "append", .len = 6, .cc = APPEND_CMD},
+ {.cmd = "prepend", .len = 7, .cc = PREPEND_CMD},
+ {.cmd = "delete_object", .len = 6, .cc = DELETE_CMD},
+ {.cmd = "incr", .len = 4, .cc = INCR_CMD},
+ {.cmd = "decr", .len = 4, .cc = DECR_CMD},
+ {.cmd = "stats", .len = 5, .cc = STATS_CMD},
+ {.cmd = "flush_all", .len = 9, .cc = FLUSH_ALL_CMD},
+ {.cmd = "version", .len = 7, .cc = VERSION_CMD},
+ {.cmd = "quit", .len = 4, .cc = QUIT_CMD},
+ {.cmd = "verbosity", .len = 9, .cc = VERBOSITY_CMD},
+ {.cmd = NULL, .len = 0, .cc = UNKNOWN_CMD}};
+
+ int x = 0;
while (commands[x].len > 0) {
- if (length >= commands[x].len)
- {
- if (strncmp(start, commands[x].cmd, commands[x].len) == 0)
- {
+ if (length >= commands[x].len) {
+ if (strncmp(start, commands[x].cmd, commands[x].len) == 0) {
/* Potential hit */
- if (length == commands[x].len || isspace(*(start + commands[x].len)))
- {
+ if (length == commands[x].len || isspace(*(start + commands[x].len))) {
return commands[x].cc;
}
}
* @param tokens the command as a vector
* @param ntokens the number of items in the vector
*/
-static void process_delete(memcached_protocol_client_st *client,
- char **tokens, int ntokens)
-{
- char *key= tokens[1];
+static void process_delete(memcached_protocol_client_st *client, char **tokens, int ntokens) {
+ char *key = tokens[1];
uint16_t nkey;
- if (ntokens != 2 || (nkey= parse_ascii_key(&key)) == 0)
- {
+ if (ntokens != 2 || (nkey = parse_ascii_key(&key)) == 0) {
send_command_usage(client);
return;
}
- if (client->root->callback->interface.v1.delete_object == NULL)
- {
+ if (client->root->callback->interface.v1.delete_object == NULL) {
ascii_raw_response_handler(client, "SERVER_ERROR: callback not implemented\r\n");
return;
}
- protocol_binary_response_status rval= client->root->callback->interface.v1.delete_object(client, key, nkey, 0);
+ protocol_binary_response_status rval =
+ client->root->callback->interface.v1.delete_object(client, key, nkey, 0);
- if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS)
- {
+ if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
ascii_raw_response_handler(client, "DELETED\r\n");
- }
- else if (rval == PROTOCOL_BINARY_RESPONSE_KEY_ENOENT)
- {
+ } else if (rval == PROTOCOL_BINARY_RESPONSE_KEY_ENOENT) {
ascii_raw_response_handler(client, "NOT_FOUND\r\n");
- }
- else
- {
+ } else {
char msg[80];
- snprintf(msg, sizeof(msg), "SERVER_ERROR: delete_object failed %u\r\n",(uint32_t)rval);
+ snprintf(msg, sizeof(msg), "SERVER_ERROR: delete_object failed %u\r\n", (uint32_t) rval);
ascii_raw_response_handler(client, msg);
}
}
-static void process_arithmetic(memcached_protocol_client_st *client,
- char **tokens, int ntokens)
-{
- char *key= tokens[1];
+static void process_arithmetic(memcached_protocol_client_st *client, char **tokens, int ntokens) {
+ char *key = tokens[1];
uint16_t nkey;
- if (ntokens != 3 || (nkey= parse_ascii_key(&key)) == 0)
- {
+ if (ntokens != 3 || (nkey = parse_ascii_key(&key)) == 0) {
send_command_usage(client);
return;
}
uint64_t cas;
uint64_t result;
- errno= 0;
- uint64_t delta= strtoull(tokens[2], NULL, 10);
- if (errno != 0)
- {
+ errno = 0;
+ uint64_t delta = strtoull(tokens[2], NULL, 10);
+ if (errno) {
return; // Error
}
protocol_binary_response_status rval;
- if (client->ascii_command == INCR_CMD)
- {
- if (client->root->callback->interface.v1.increment == NULL)
- {
+ if (client->ascii_command == INCR_CMD) {
+ if (client->root->callback->interface.v1.increment == NULL) {
ascii_raw_response_handler(client, "SERVER_ERROR: callback not implemented\r\n");
return;
}
- rval= client->root->callback->interface.v1.increment(client,
- key, nkey,
- delta, 0,
- 0,
- &result,
- &cas);
- }
- else
- {
- if (client->root->callback->interface.v1.decrement == NULL)
- {
+ rval = client->root->callback->interface.v1.increment(client, key, nkey, delta, 0, 0, &result,
+ &cas);
+ } else {
+ if (client->root->callback->interface.v1.decrement == NULL) {
ascii_raw_response_handler(client, "SERVER_ERROR: callback not implemented\r\n");
return;
}
- rval= client->root->callback->interface.v1.decrement(client,
- key, nkey,
- delta, 0,
- 0,
- &result,
- &cas);
+ rval = client->root->callback->interface.v1.decrement(client, key, nkey, delta, 0, 0, &result,
+ &cas);
}
- if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS)
- {
+ if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
char buffer[80];
- snprintf(buffer, sizeof(buffer), "%"PRIu64"\r\n", result);
+ snprintf(buffer, sizeof(buffer), "%" PRIu64 "\r\n", result);
ascii_raw_response_handler(client, buffer);
- }
- else
- {
+ } else {
ascii_raw_response_handler(client, "NOT_FOUND\r\n");
}
}
* @param key pointer to the first character after "stats"
* @param end pointer to the "\n"
*/
-static void process_stats(memcached_protocol_client_st *client,
- char *key, char *end)
-{
- if (client->root->callback->interface.v1.stat == NULL)
- {
+static void process_stats(memcached_protocol_client_st *client, char *key, char *end) {
+ if (client->root->callback->interface.v1.stat == NULL) {
ascii_raw_response_handler(client, "SERVER_ERROR: callback not implemented\r\n");
return;
}
- while (isspace(*key))
- {
+ while (isspace(*key)) {
key++;
}
- uint16_t nkey= (uint16_t)(end - key);
- (void)client->root->callback->interface.v1.stat(client, key, nkey,
- ascii_stat_response_handler);
+ uint16_t nkey = (uint16_t)(end - key);
+ (void) client->root->callback->interface.v1.stat(client, key, nkey, ascii_stat_response_handler);
}
-static void process_version(memcached_protocol_client_st *client,
- char **tokens, int ntokens)
-{
- (void)tokens;
- if (ntokens != 1)
- {
+static void process_version(memcached_protocol_client_st *client, char **tokens, int ntokens) {
+ (void) tokens;
+ if (ntokens != 1) {
send_command_usage(client);
return;
}
- if (client->root->callback->interface.v1.version == NULL)
- {
+ if (client->root->callback->interface.v1.version == NULL) {
ascii_raw_response_handler(client, "SERVER_ERROR: callback not implemented\r\n");
return;
}
- client->root->callback->interface.v1.version(client,
- ascii_version_response_handler);
+ client->root->callback->interface.v1.version(client, ascii_version_response_handler);
}
-static void process_flush(memcached_protocol_client_st *client,
- char **tokens, int ntokens)
-{
- if (ntokens > 2)
- {
+static void process_flush(memcached_protocol_client_st *client, char **tokens, int ntokens) {
+ if (ntokens > 2) {
send_command_usage(client);
return;
}
- if (client->root->callback->interface.v1.flush_object == NULL)
- {
+ if (client->root->callback->interface.v1.flush_object == NULL) {
ascii_raw_response_handler(client, "SERVER_ERROR: callback not implemented\r\n");
return;
}
- uint32_t timeout= 0;
- if (ntokens == 2)
- {
- errno= 0;
- timeout= (uint32_t)strtoul(tokens[1], NULL, 10);
- if (errno != 0)
- {
+ uint32_t timeout = 0;
+ if (ntokens == 2) {
+ errno = 0;
+ timeout = (uint32_t) strtoul(tokens[1], NULL, 10);
+ if (errno) {
return; // Error
}
}
protocol_binary_response_status rval;
- rval= client->root->callback->interface.v1.flush_object(client, timeout);
+ rval = client->root->callback->interface.v1.flush_object(client, timeout);
if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS)
ascii_raw_response_handler(client, "OK\r\n");
else
* 0 storage command completed, continue processing
* 1 We need more data, so just go ahead and wait for more!
*/
-static inline int process_storage_command(memcached_protocol_client_st *client,
- char **tokens, int ntokens, char *start,
- char **end, ssize_t length)
-{
- (void)ntokens; /* already checked */
- char *key= tokens[1];
- uint16_t nkey= parse_ascii_key(&key);
- if (nkey == 0)
- {
+static inline int process_storage_command(memcached_protocol_client_st *client, char **tokens,
+ int ntokens, char *start, char **end, ssize_t length) {
+ (void) ntokens; /* already checked */
+ char *key = tokens[1];
+ uint16_t nkey = parse_ascii_key(&key);
+ if (nkey == 0) {
/* return error */
ascii_raw_response_handler(client, "CLIENT_ERROR: bad key\r\n");
return -1;
}
- errno= 0;
- uint32_t flags= (uint32_t)strtoul(tokens[2], NULL, 10);
- if (errno != 0)
- {
+ errno = 0;
+ uint32_t flags = (uint32_t) strtoul(tokens[2], NULL, 10);
+ if (errno) {
/* return error */
ascii_raw_response_handler(client, "CLIENT_ERROR: bad key\r\n");
return -1;
}
- uint32_t timeout= (uint32_t)strtoul(tokens[3], NULL, 10);
- if (errno != 0)
- {
+ uint32_t timeout = (uint32_t) strtoul(tokens[3], NULL, 10);
+ if (errno) {
/* return error */
ascii_raw_response_handler(client, "CLIENT_ERROR: bad key\r\n");
return -1;
}
- unsigned long nbytes= strtoul(tokens[4], NULL, 10);
- if (errno != 0)
- {
+ unsigned long nbytes = strtoul(tokens[4], NULL, 10);
+ if (errno) {
/* return error */
ascii_raw_response_handler(client, "CLIENT_ERROR: bad key\r\n");
return -1;
}
/* Do we have all data? */
- unsigned long need= nbytes + (unsigned long)((*end - start) + 1) + 2; /* \n\r\n */
- if ((ssize_t)need > length)
- {
+ unsigned long need = nbytes + (unsigned long) ((*end - start) + 1) + 2; /* \n\r\n */
+ if ((ssize_t) need > length) {
/* Keep on reading */
recover_tokenize_command(start, *end);
return 1;
}
- void *data= (*end) + 1;
- uint64_t cas= 0;
+ void *data = (*end) + 1;
+ uint64_t cas = 0;
uint64_t result_cas;
protocol_binary_response_status rval;
- switch (client->ascii_command)
- {
+ switch (client->ascii_command) {
case SET_CMD:
- rval= client->root->callback->interface.v1.set(client, key,
- (uint16_t)nkey,
- data,
- (uint32_t)nbytes,
- flags,
- timeout, cas,
- &result_cas);
+ rval = client->root->callback->interface.v1.set(
+ client, key, (uint16_t) nkey, data, (uint32_t) nbytes, flags, timeout, cas, &result_cas);
break;
case ADD_CMD:
- rval= client->root->callback->interface.v1.add(client, key,
- (uint16_t)nkey,
- data,
- (uint32_t)nbytes,
- flags,
- timeout, &result_cas);
+ rval = client->root->callback->interface.v1.add(client, key, (uint16_t) nkey, data,
+ (uint32_t) nbytes, flags, timeout, &result_cas);
break;
case CAS_CMD:
- errno= 0;
- cas= strtoull(tokens[5], NULL, 10);
- if (errno != 0)
- {
+ errno = 0;
+ cas = strtoull(tokens[5], NULL, 10);
+ if (errno) {
/* return error */
ascii_raw_response_handler(client, "CLIENT_ERROR: bad key\r\n");
return -1;
}
/* FALLTHROUGH */
case REPLACE_CMD:
- rval= client->root->callback->interface.v1.replace(client, key,
- (uint16_t)nkey,
- data,
- (uint32_t)nbytes,
- flags,
- timeout, cas,
- &result_cas);
+ rval = client->root->callback->interface.v1.replace(
+ client, key, (uint16_t) nkey, data, (uint32_t) nbytes, flags, timeout, cas, &result_cas);
break;
case APPEND_CMD:
- rval= client->root->callback->interface.v1.append(client, key,
- (uint16_t)nkey,
- data,
- (uint32_t)nbytes,
- cas,
- &result_cas);
+ rval = client->root->callback->interface.v1.append(client, key, (uint16_t) nkey, data,
+ (uint32_t) nbytes, cas, &result_cas);
break;
case PREPEND_CMD:
- rval= client->root->callback->interface.v1.prepend(client, key,
- (uint16_t)nkey,
- data,
- (uint32_t)nbytes,
- cas,
- &result_cas);
+ rval = client->root->callback->interface.v1.prepend(client, key, (uint16_t) nkey, data,
+ (uint32_t) nbytes, cas, &result_cas);
break;
/* gcc complains if I don't put all of the enums in here.. */
abort(); /* impossible */
}
- if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS)
- {
+ if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
ascii_raw_response_handler(client, "STORED\r\n");
- }
- else
- {
- if (client->ascii_command == CAS_CMD)
- {
- if (rval == PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS)
- {
+ } else {
+ if (client->ascii_command == CAS_CMD) {
+ if (rval == PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS) {
ascii_raw_response_handler(client, "EXISTS\r\n");
- }
- else if (rval == PROTOCOL_BINARY_RESPONSE_KEY_ENOENT)
- {
+ } else if (rval == PROTOCOL_BINARY_RESPONSE_KEY_ENOENT) {
ascii_raw_response_handler(client, "NOT_FOUND\r\n");
- }
- else
- {
+ } else {
ascii_raw_response_handler(client, "NOT_STORED\r\n");
}
- }
- else
- {
+ } else {
ascii_raw_response_handler(client, "NOT_STORED\r\n");
}
}
return 0;
}
-static int process_cas_command(memcached_protocol_client_st *client,
- char **tokens, int ntokens, char *start,
- char **end, ssize_t length)
-{
- if (ntokens != 6)
- {
+static int process_cas_command(memcached_protocol_client_st *client, char **tokens, int ntokens,
+ char *start, char **end, ssize_t length) {
+ if (ntokens != 6) {
send_command_usage(client);
return false;
}
- if (client->root->callback->interface.v1.replace == NULL)
- {
+ if (client->root->callback->interface.v1.replace == NULL) {
ascii_raw_response_handler(client, "SERVER_ERROR: callback not implemented\r\n");
return false;
}
return process_storage_command(client, tokens, ntokens, start, end, length);
}
-static int process_set_command(memcached_protocol_client_st *client,
- char **tokens, int ntokens, char *start,
- char **end, ssize_t length)
-{
- if (ntokens != 5)
- {
+static int process_set_command(memcached_protocol_client_st *client, char **tokens, int ntokens,
+ char *start, char **end, ssize_t length) {
+ if (ntokens != 5) {
send_command_usage(client);
return false;
}
- if (client->root->callback->interface.v1.set == NULL)
- {
+ if (client->root->callback->interface.v1.set == NULL) {
ascii_raw_response_handler(client, "SERVER_ERROR: callback not implemented\r\n");
return false;
}
return process_storage_command(client, tokens, ntokens, start, end, length);
}
-static int process_add_command(memcached_protocol_client_st *client,
- char **tokens, int ntokens, char *start,
- char **end, ssize_t length)
-{
- if (ntokens != 5)
- {
+static int process_add_command(memcached_protocol_client_st *client, char **tokens, int ntokens,
+ char *start, char **end, ssize_t length) {
+ if (ntokens != 5) {
send_command_usage(client);
return false;
}
- if (client->root->callback->interface.v1.add == NULL)
- {
+ if (client->root->callback->interface.v1.add == NULL) {
ascii_raw_response_handler(client, "SERVER_ERROR: callback not implemented\r\n");
return false;
}
return process_storage_command(client, tokens, ntokens, start, end, length);
}
-static int process_replace_command(memcached_protocol_client_st *client,
- char **tokens, int ntokens, char *start,
- char **end, ssize_t length)
-{
- if (ntokens != 5)
- {
+static int process_replace_command(memcached_protocol_client_st *client, char **tokens, int ntokens,
+ char *start, char **end, ssize_t length) {
+ if (ntokens != 5) {
send_command_usage(client);
return false;
}
- if (client->root->callback->interface.v1.replace == NULL)
- {
+ if (client->root->callback->interface.v1.replace == NULL) {
ascii_raw_response_handler(client, "SERVER_ERROR: callback not implemented\r\n");
return false;
}
return process_storage_command(client, tokens, ntokens, start, end, length);
}
-static int process_append_command(memcached_protocol_client_st *client,
- char **tokens, int ntokens, char *start,
- char **end, ssize_t length)
-{
- if (ntokens != 5)
- {
+static int process_append_command(memcached_protocol_client_st *client, char **tokens, int ntokens,
+ char *start, char **end, ssize_t length) {
+ if (ntokens != 5) {
send_command_usage(client);
return false;
}
- if (client->root->callback->interface.v1.append == NULL)
- {
+ if (client->root->callback->interface.v1.append == NULL) {
ascii_raw_response_handler(client, "SERVER_ERROR: callback not implemented\r\n");
return false;
}
return process_storage_command(client, tokens, ntokens, start, end, length);
}
-static int process_prepend_command(memcached_protocol_client_st *client,
- char **tokens, int ntokens, char *start,
- char **end, ssize_t length)
-{
- if (ntokens != 5)
- {
+static int process_prepend_command(memcached_protocol_client_st *client, char **tokens, int ntokens,
+ char *start, char **end, ssize_t length) {
+ if (ntokens != 5) {
send_command_usage(client);
return false;
}
- if (client->root->callback->interface.v1.prepend == NULL)
- {
+ if (client->root->callback->interface.v1.prepend == NULL) {
ascii_raw_response_handler(client, "SERVER_ERROR: callback not implemented\r\n");
return false;
}
* a optimal ascii support, I just convert the ASCII commands to the binary
* protocol and calls back into the command handlers for the binary protocol ;)
*/
-memcached_protocol_event_t memcached_ascii_protocol_process_data(memcached_protocol_client_st *client, ssize_t *length, void **endptr)
-{
- char *ptr= (char*)client->root->input_buffer;
- *endptr= ptr;
+memcached_protocol_event_t
+memcached_ascii_protocol_process_data(memcached_protocol_client_st *client, ssize_t *length,
+ void **endptr) {
+ char *ptr = (char *) client->root->input_buffer;
+ *endptr = ptr;
do {
/* Do we have \n (indicating the command preamble)*/
- char *end= memchr(ptr, '\n', (size_t)*length);
- if (end == NULL)
- {
- *endptr= ptr;
+ char *end = memchr(ptr, '\n', (size_t) *length);
+ if (end == NULL) {
+ *endptr = ptr;
return MEMCACHED_PROTOCOL_READ_EVENT;
}
- client->ascii_command= ascii_to_cmd(ptr, (size_t)(*length));
+ client->ascii_command = ascii_to_cmd(ptr, (size_t)(*length));
/* we got all data available, execute the callback! */
- if (client->root->callback->pre_execute != NULL)
- {
+ if (client->root->callback->pre_execute) {
client->root->callback->pre_execute(client, NULL);
}
-
/* A multiget lists all of the keys, and I don't want to have an
* avector of let's say 512 pointers to tokenize all of them, so let's
* just handle them immediately
*/
- if (client->ascii_command == GET_CMD ||
- client->ascii_command == GETS_CMD)
- {
- if (client->root->callback->interface.v1.get != NULL)
- {
+ if (client->ascii_command == GET_CMD || client->ascii_command == GETS_CMD) {
+ if (client->root->callback->interface.v1.get) {
ascii_process_gets(client, ptr, end);
- }
- else
- {
+ } else {
ascii_raw_response_handler(client, "SERVER_ERROR: Command not implemented\n");
}
- }
- else
- {
+ } else {
/* None of the defined commands takes 10 parameters, so lets just use
* that as a maximum limit.
- */
+ */
char *tokens[10];
- int ntokens= ascii_tokenize_command(ptr, end, tokens, 10);
+ int ntokens = ascii_tokenize_command(ptr, end, tokens, 10);
- if (ntokens < 10)
- {
- client->mute= strcmp(tokens[ntokens - 1], "noreply") == 0;
- if (client->mute)
- {
+ if (ntokens < 10) {
+ client->mute = strcmp(tokens[ntokens - 1], "noreply") == 0;
+ if (client->mute) {
--ntokens; /* processed noreply token*/
}
}
- int error= 0;
+ int error = 0;
print_ascii_command(client);
- switch (client->ascii_command)
- {
+ switch (client->ascii_command) {
case SET_CMD:
- error= process_set_command(client, tokens, ntokens, ptr, &end, *length);
+ error = process_set_command(client, tokens, ntokens, ptr, &end, *length);
break;
case ADD_CMD:
- error= process_add_command(client, tokens, ntokens, ptr, &end, *length);
+ error = process_add_command(client, tokens, ntokens, ptr, &end, *length);
break;
case REPLACE_CMD:
- error= process_replace_command(client, tokens, ntokens, ptr, &end, *length);
+ error = process_replace_command(client, tokens, ntokens, ptr, &end, *length);
break;
case CAS_CMD:
- error= process_cas_command(client, tokens, ntokens, ptr, &end, *length);
+ error = process_cas_command(client, tokens, ntokens, ptr, &end, *length);
break;
case APPEND_CMD:
- error= process_append_command(client, tokens, ntokens, ptr, &end, *length);
+ error = process_append_command(client, tokens, ntokens, ptr, &end, *length);
break;
case PREPEND_CMD:
- error= process_prepend_command(client, tokens, ntokens, ptr, &end, *length);
+ error = process_prepend_command(client, tokens, ntokens, ptr, &end, *length);
break;
case DELETE_CMD:
break;
case STATS_CMD:
- if (client->mute)
- {
+ if (client->mute) {
send_command_usage(client);
- }
- else
- {
+ } else {
recover_tokenize_command(ptr, end);
process_stats(client, ptr + 6, end);
}
break;
case VERSION_CMD:
- if (client->mute)
- {
+ if (client->mute) {
send_command_usage(client);
- }
- else
- {
+ } else {
process_version(client, tokens, ntokens);
}
break;
case QUIT_CMD:
- if (ntokens != 1 || client->mute)
- {
+ if (ntokens != 1 || client->mute) {
send_command_usage(client);
- }
- else
- {
- if (client->root->callback->interface.v1.quit != NULL)
- {
+ } else {
+ if (client->root->callback->interface.v1.quit) {
client->root->callback->interface.v1.quit(client);
}
break;
case VERBOSITY_CMD:
- if (ntokens != 2)
- {
+ if (ntokens != 2) {
send_command_usage(client);
- }
- else
- {
+ } else {
ascii_raw_response_handler(client, "OK\r\n");
}
break;
abort();
}
- if (error == -1)
- {
+ if (error == -1) {
return MEMCACHED_PROTOCOL_ERROR_EVENT;
- }
- else if (error == 1)
- {
+ } else if (error == 1) {
return MEMCACHED_PROTOCOL_READ_EVENT;
}
}
- if (client->root->callback->post_execute != NULL)
- {
+ if (client->root->callback->post_execute) {
client->root->callback->post_execute(client, NULL);
}
/* Move past \n */
++end;
*length -= end - ptr;
- ptr= end;
+ ptr = end;
} while (*length > 0);
- *endptr= ptr;
+ *endptr = ptr;
return MEMCACHED_PROTOCOL_READ_EVENT;
}