Fix for non-Linux platforms.
[awesomized/libmemcached] / libmemcached / 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_t memcached_version_binary(memcached_st *ptr);
9 static inline memcached_return_t memcached_version_textual(memcached_st *ptr);
10
11 memcached_return_t memcached_version(memcached_st *ptr)
12 {
13 if (ptr->flags.use_udp)
14 return MEMCACHED_NOT_SUPPORTED;
15
16 if (ptr->flags.binary_protocol)
17 return memcached_version_binary(ptr);
18 else
19 return memcached_version_textual(ptr);
20 }
21
22 static inline memcached_return_t memcached_version_textual(memcached_st *ptr)
23 {
24 size_t send_length;
25 memcached_return_t rc;
26 char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
27 char *response_ptr;
28 const char *command= "version\r\n";
29
30 send_length= strlen(command);
31
32 rc= MEMCACHED_SUCCESS;
33 for (uint32_t x= 0; x < memcached_server_count(ptr); x++)
34 {
35 memcached_return_t rrc;
36 memcached_server_instance_st *instance=
37 memcached_server_instance_fetch(ptr, x);
38
39 rrc= memcached_do(instance, command, send_length, true);
40 if (rrc != MEMCACHED_SUCCESS)
41 {
42 rc= MEMCACHED_SOME_ERRORS;
43 continue;
44 }
45
46 rrc= memcached_response(instance, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL);
47 if (rrc != MEMCACHED_SUCCESS)
48 {
49 rc= MEMCACHED_SOME_ERRORS;
50 continue;
51 }
52
53 /* Find the space, and then move one past it to copy version */
54 response_ptr= index(buffer, ' ');
55 response_ptr++;
56
57 instance->major_version= (uint8_t)strtol(response_ptr, (char **)NULL, 10);
58 response_ptr= index(response_ptr, '.');
59 response_ptr++;
60 instance->minor_version= (uint8_t)strtol(response_ptr, (char **)NULL, 10);
61 response_ptr= index(response_ptr, '.');
62 response_ptr++;
63 instance->micro_version= (uint8_t)strtol(response_ptr, (char **)NULL, 10);
64 }
65
66 return rc;
67 }
68
69 static inline memcached_return_t memcached_version_binary(memcached_st *ptr)
70 {
71 memcached_return_t rc;
72 unsigned int x;
73 protocol_binary_request_version request= { .bytes= {0}};
74 request.message.header.request.magic= PROTOCOL_BINARY_REQ;
75 request.message.header.request.opcode= PROTOCOL_BINARY_CMD_VERSION;
76 request.message.header.request.datatype= PROTOCOL_BINARY_RAW_BYTES;
77
78 rc= MEMCACHED_SUCCESS;
79 for (x= 0; x < memcached_server_count(ptr); x++)
80 {
81 memcached_return_t rrc;
82
83 memcached_server_instance_st *instance=
84 memcached_server_instance_fetch(ptr, x);
85
86 rrc= memcached_do(instance, request.bytes, sizeof(request.bytes), true);
87 if (rrc != MEMCACHED_SUCCESS)
88 {
89 memcached_io_reset(instance);
90 rc= MEMCACHED_SOME_ERRORS;
91 continue;
92 }
93 }
94
95 for (x= 0; x < memcached_server_count(ptr); x++)
96 {
97 memcached_server_instance_st *instance=
98 memcached_server_instance_fetch(ptr, x);
99
100 if (memcached_server_response_count(instance) > 0)
101 {
102 memcached_return_t rrc;
103 char buffer[32];
104 char *p;
105
106 rrc= memcached_response(instance, buffer, sizeof(buffer), NULL);
107 if (rrc != MEMCACHED_SUCCESS)
108 {
109 memcached_io_reset(instance);
110 rc= MEMCACHED_SOME_ERRORS;
111 continue;
112 }
113
114 instance->major_version= (uint8_t)strtol(buffer, &p, 10);
115 instance->minor_version= (uint8_t)strtol(p + 1, &p, 10);
116 instance->micro_version= (uint8_t)strtol(p + 1, NULL, 10);
117 }
118 }
119
120 return rc;
121 }