version_textual no longer attempts to parse invalid response
[awesomized/libmemcached] / libmemcached / memcached_version.c
1 #include "common.h"
2
3 const char * memcached_lib_version(void)
4 {
5 return LIBMEMCACHED_VERSION_STRING;
6 }
7
8 static inline memcached_return memcached_version_binary(memcached_st *ptr);
9 static inline memcached_return memcached_version_textual(memcached_st *ptr);
10
11 memcached_return memcached_version(memcached_st *ptr)
12 {
13 if (ptr->flags & MEM_BINARY_PROTOCOL)
14 return memcached_version_binary(ptr);
15 else
16 return memcached_version_textual(ptr);
17 }
18
19 static inline memcached_return memcached_version_textual(memcached_st *ptr)
20 {
21 unsigned int x;
22 size_t send_length;
23 memcached_return rc;
24 char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
25 char *response_ptr;
26 char *command= "version\r\n";
27
28 send_length= strlen(command);
29
30 rc= MEMCACHED_SUCCESS;
31 for (x= 0; x < ptr->number_of_hosts; x++)
32 {
33 memcached_return rrc;
34
35 rrc= memcached_do(&ptr->hosts[x], command, send_length, 1);
36 if (rrc != MEMCACHED_SUCCESS)
37 {
38 rc= MEMCACHED_SOME_ERRORS;
39 continue;
40 }
41
42 rrc= memcached_response(&ptr->hosts[x], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL);
43 if (rrc != MEMCACHED_SUCCESS)
44 {
45 rc= MEMCACHED_SOME_ERRORS;
46 continue;
47 }
48
49 /* Find the space, and then move one past it to copy version */
50 response_ptr= index(buffer, ' ');
51 response_ptr++;
52
53 ptr->hosts[x].major_version= (uint8_t)strtol(response_ptr, (char **)NULL, 10);
54 response_ptr= index(response_ptr, '.');
55 response_ptr++;
56 ptr->hosts[x].minor_version= (uint8_t)strtol(response_ptr, (char **)NULL, 10);
57 response_ptr= index(response_ptr, '.');
58 response_ptr++;
59 ptr->hosts[x].micro_version= (uint8_t)strtol(response_ptr, (char **)NULL, 10);
60 }
61
62 return rc;
63 }
64
65 static inline memcached_return memcached_version_binary(memcached_st *ptr)
66 {
67 memcached_return rc;
68 unsigned int x;
69 protocol_binary_request_version request= { .bytes= {0}};
70 request.message.header.request.magic= PROTOCOL_BINARY_REQ;
71 request.message.header.request.opcode= PROTOCOL_BINARY_CMD_VERSION;
72 request.message.header.request.datatype= PROTOCOL_BINARY_RAW_BYTES;
73
74 rc= MEMCACHED_SUCCESS;
75 for (x= 0; x < ptr->number_of_hosts; x++)
76 {
77 memcached_return rrc;
78
79 rrc= memcached_do(&ptr->hosts[x], request.bytes, sizeof(request.bytes), 1);
80 if (rrc != MEMCACHED_SUCCESS)
81 {
82 memcached_io_reset(&ptr->hosts[x]);
83 rc= MEMCACHED_SOME_ERRORS;
84 continue;
85 }
86 }
87
88 for (x= 0; x < ptr->number_of_hosts; x++)
89 if (memcached_server_response_count(&ptr->hosts[x]) > 0)
90 {
91 memcached_return rrc;
92 char buffer[32];
93 char *p;
94
95 rrc= memcached_response(&ptr->hosts[x], buffer, sizeof(buffer), NULL);
96 if (rrc != MEMCACHED_SUCCESS)
97 {
98 memcached_io_reset(&ptr->hosts[x]);
99 rc= MEMCACHED_SOME_ERRORS;
100 }
101
102 ptr->hosts[x].major_version= (uint8_t)strtol(buffer, &p, 10);
103 ptr->hosts[x].minor_version= (uint8_t)strtol(p + 1, &p, 10);
104 ptr->hosts[x].micro_version= (uint8_t)strtol(p + 1, NULL, 10);
105 }
106
107 return rc;
108 }