memcached_return_t memcached_version(memcached_st *ptr)
{
+ memcached_return_t rc;
+ if (memcached_failed(rc= initialize_query(ptr)))
+ {
+ return rc;
+ }
+
if (ptr->flags.use_udp)
+ {
return MEMCACHED_NOT_SUPPORTED;
-
- memcached_return_t rc;
+ }
if (ptr->flags.binary_protocol)
+ {
rc= memcached_version_binary(ptr);
+ }
else
+ {
rc= memcached_version_textual(ptr);
+ }
return rc;
}
static inline memcached_return_t memcached_version_textual(memcached_st *ptr)
{
- size_t send_length;
- memcached_return_t rc;
- char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
- char *response_ptr;
- const char *command= "version\r\n";
-
- send_length= sizeof("version\r\n") -1;
-
- rc= MEMCACHED_SUCCESS;
+ memcached_return_t rc= MEMCACHED_SUCCESS;
for (uint32_t x= 0; x < memcached_server_count(ptr); x++)
{
- memcached_return_t rrc;
- memcached_server_write_instance_st instance=
- memcached_server_instance_fetch(ptr, x);
+ memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, x);
// Optimization, we only fetch version once.
if (instance->major_version != UINT8_MAX)
+ {
continue;
+ }
- rrc= memcached_do(instance, command, send_length, true);
- if (rrc != MEMCACHED_SUCCESS)
+ memcached_return_t rrc= memcached_do(instance, memcached_literal_param("version\r\n"), true);
+ if (memcached_failed(rrc))
{
+ (void)memcached_set_error(*instance, rrc, MEMCACHED_AT);
instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
rc= MEMCACHED_SOME_ERRORS;
continue;
}
+ char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
rrc= memcached_response(instance, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL);
- if (rrc != MEMCACHED_SUCCESS)
+ if (memcached_failed(rrc))
{
+ memcached_set_error(*instance, rrc, MEMCACHED_AT);
instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
rc= MEMCACHED_SOME_ERRORS;
continue;
}
/* Find the space, and then move one past it to copy version */
- response_ptr= index(buffer, ' ');
+ char *response_ptr= index(buffer, ' ');
response_ptr++;
- instance->major_version= (uint8_t)strtol(response_ptr, (char **)NULL, 10);
- if (errno == ERANGE)
+ long int version= strtol(response_ptr, (char **)NULL, 10);
+ if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX or version == 0)
{
+ memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse major version"));
instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
rc= MEMCACHED_SOME_ERRORS;
continue;
}
+ instance->major_version= uint8_t(version);
response_ptr= index(response_ptr, '.');
response_ptr++;
- instance->minor_version= (uint8_t)strtol(response_ptr, (char **)NULL, 10);
- if (errno == ERANGE)
+ version= strtol(response_ptr, (char **)NULL, 10);
+ if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX)
{
+ memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse minor version"));
instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
rc= MEMCACHED_SOME_ERRORS;
continue;
}
+ instance->minor_version= uint8_t(version);
response_ptr= index(response_ptr, '.');
response_ptr++;
- instance->micro_version= (uint8_t)strtol(response_ptr, (char **)NULL, 10);
- if (errno == ERANGE)
+
+ version= strtol(response_ptr, (char **)NULL, 10);
+ if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX)
{
+ memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version"));
instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
rc= MEMCACHED_SOME_ERRORS;
continue;
}
+ instance->micro_version= uint8_t(version);
}
return rc;
static inline memcached_return_t memcached_version_binary(memcached_st *ptr)
{
- memcached_return_t rc;
protocol_binary_request_version request= {};
request.message.header.request.magic= PROTOCOL_BINARY_REQ;
request.message.header.request.opcode= PROTOCOL_BINARY_CMD_VERSION;
request.message.header.request.datatype= PROTOCOL_BINARY_RAW_BYTES;
- rc= MEMCACHED_SUCCESS;
+ memcached_return_t rc= MEMCACHED_SUCCESS;
for (uint32_t x= 0; x < memcached_server_count(ptr); x++)
{
- memcached_return_t rrc;
-
- memcached_server_write_instance_st instance=
- memcached_server_instance_fetch(ptr, x);
+ memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, x);
if (instance->major_version != UINT8_MAX)
+ {
continue;
+ }
- rrc= memcached_do(instance, request.bytes, sizeof(request.bytes), true);
- if (rrc != MEMCACHED_SUCCESS)
+ memcached_return_t rrc= memcached_do(instance, request.bytes, sizeof(request.bytes), true);
+ if (memcached_failed(rrc))
{
memcached_io_reset(instance);
rc= MEMCACHED_SOME_ERRORS;
memcached_server_instance_fetch(ptr, x);
if (instance->major_version != UINT8_MAX)
+ {
continue;
+ }
if (memcached_server_response_count(instance) > 0)
{
- memcached_return_t rrc;
char buffer[32];
char *p;
- rrc= memcached_response(instance, buffer, sizeof(buffer), NULL);
- if (rrc != MEMCACHED_SUCCESS)
+ memcached_return_t rrc= memcached_response(instance, buffer, sizeof(buffer), NULL);
+ if (memcached_failed(rrc))
{
memcached_io_reset(instance);
rc= MEMCACHED_SOME_ERRORS;
continue;
}
- instance->major_version= (uint8_t)strtol(buffer, &p, 10);
- if (errno == ERANGE)
+ long int version= strtol(buffer, &p, 10);
+ if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX or version == 0)
{
+ memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse major version"));
instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
rc= MEMCACHED_SOME_ERRORS;
continue;
}
+ instance->major_version= uint8_t(version);
- instance->minor_version= (uint8_t)strtol(p + 1, &p, 10);
- if (errno == ERANGE)
+ version= strtol(p +1, &p, 10);
+ if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX)
{
+ memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version"));
instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
rc= MEMCACHED_SOME_ERRORS;
continue;
}
+ instance->minor_version= uint8_t(version);
- instance->micro_version= (uint8_t)strtol(p + 1, NULL, 10);
+ version= strtol(p + 1, NULL, 10);
if (errno == ERANGE)
{
+ memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version"));
instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
rc= MEMCACHED_SOME_ERRORS;
continue;
}
-
+ instance->micro_version= uint8_t(version);
}
}