~brianaker/libmemcached/1164440

« back to all changes in this revision

Viewing changes to libmemcached/version.cc

  • Committer: Brian Aker
  • Date: 2011-10-05 21:43:41 UTC
  • mfrom: (929.1.285 libmemcached-build)
  • mto: This revision was merged to the branch mainline in revision 967.
  • Revision ID: brian@tangent.org-20111005214341-le14e1xyyyph9ymq
MergeĀ inĀ touch/etc

Show diffs side-by-side

added added

removed removed

Lines of Context:
46
46
 
47
47
memcached_return_t memcached_version(memcached_st *ptr)
48
48
{
 
49
  memcached_return_t rc;
 
50
  if (memcached_failed(rc= initialize_query(ptr)))
 
51
  {
 
52
    return rc;
 
53
  }
 
54
 
49
55
  if (ptr->flags.use_udp)
 
56
  {
50
57
    return MEMCACHED_NOT_SUPPORTED;
51
 
 
52
 
  memcached_return_t rc;
 
58
  }
53
59
 
54
60
  if (ptr->flags.binary_protocol)
 
61
  {
55
62
    rc= memcached_version_binary(ptr);
 
63
  }
56
64
  else
 
65
  {
57
66
    rc= memcached_version_textual(ptr);      
 
67
  }
58
68
 
59
69
  return rc;
60
70
}
61
71
 
62
72
static inline memcached_return_t memcached_version_textual(memcached_st *ptr)
63
73
{
64
 
  size_t send_length;
65
 
  memcached_return_t rc;
66
 
  char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
67
 
  char *response_ptr;
68
 
  const char *command= "version\r\n";
69
 
 
70
 
  send_length= sizeof("version\r\n") -1;
71
 
 
72
 
  rc= MEMCACHED_SUCCESS;
 
74
  memcached_return_t rc= MEMCACHED_SUCCESS;
73
75
  for (uint32_t x= 0; x < memcached_server_count(ptr); x++)
74
76
  {
75
 
    memcached_return_t rrc;
76
 
    memcached_server_write_instance_st instance=
77
 
      memcached_server_instance_fetch(ptr, x);
 
77
    memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, x);
78
78
 
79
79
    // Optimization, we only fetch version once.
80
80
    if (instance->major_version != UINT8_MAX)
 
81
    {
81
82
      continue;
 
83
    }
82
84
 
83
 
    rrc= memcached_do(instance, command, send_length, true);
84
 
    if (rrc != MEMCACHED_SUCCESS)
 
85
    memcached_return_t rrc= memcached_do(instance, memcached_literal_param("version\r\n"), true);
 
86
    if (memcached_failed(rrc))
85
87
    {
 
88
      (void)memcached_set_error(*instance, rrc, MEMCACHED_AT);
86
89
      instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
87
90
      rc= MEMCACHED_SOME_ERRORS;
88
91
      continue;
89
92
    }
90
93
 
 
94
    char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
91
95
    rrc= memcached_response(instance, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL);
92
 
    if (rrc != MEMCACHED_SUCCESS)
 
96
    if (memcached_failed(rrc))
93
97
    {
 
98
      memcached_set_error(*instance, rrc, MEMCACHED_AT);
94
99
      instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
95
100
      rc= MEMCACHED_SOME_ERRORS;
96
101
      continue;
97
102
    }
98
103
 
99
104
    /* Find the space, and then move one past it to copy version */
100
 
    response_ptr= index(buffer, ' ');
101
 
    response_ptr++;
102
 
 
103
 
    instance->major_version= (uint8_t)strtol(response_ptr, (char **)NULL, 10);
104
 
    if (errno == ERANGE)
105
 
    {
106
 
      instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
107
 
      rc= MEMCACHED_SOME_ERRORS;
108
 
      continue;
109
 
    }
110
 
 
111
 
    response_ptr= index(response_ptr, '.');
112
 
    response_ptr++;
113
 
 
114
 
    instance->minor_version= (uint8_t)strtol(response_ptr, (char **)NULL, 10);
115
 
    if (errno == ERANGE)
116
 
    {
117
 
      instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
118
 
      rc= MEMCACHED_SOME_ERRORS;
119
 
      continue;
120
 
    }
121
 
 
122
 
    response_ptr= index(response_ptr, '.');
123
 
    response_ptr++;
124
 
    instance->micro_version= (uint8_t)strtol(response_ptr, (char **)NULL, 10);
125
 
    if (errno == ERANGE)
126
 
    {
127
 
      instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
128
 
      rc= MEMCACHED_SOME_ERRORS;
129
 
      continue;
130
 
    }
 
105
    char *response_ptr= index(buffer, ' ');
 
106
    response_ptr++;
 
107
 
 
108
    long int version= strtol(response_ptr, (char **)NULL, 10);
 
109
    if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX or version == 0)
 
110
    {
 
111
      memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse major version"));
 
112
      instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
 
113
      rc= MEMCACHED_SOME_ERRORS;
 
114
      continue;
 
115
    }
 
116
    instance->major_version= uint8_t(version);
 
117
 
 
118
    response_ptr= index(response_ptr, '.');
 
119
    response_ptr++;
 
120
 
 
121
    version= strtol(response_ptr, (char **)NULL, 10);
 
122
    if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX)
 
123
    {
 
124
      memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse minor version"));
 
125
      instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
 
126
      rc= MEMCACHED_SOME_ERRORS;
 
127
      continue;
 
128
    }
 
129
    instance->minor_version= uint8_t(version);
 
130
 
 
131
    response_ptr= index(response_ptr, '.');
 
132
    response_ptr++;
 
133
 
 
134
    version= strtol(response_ptr, (char **)NULL, 10);
 
135
    if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX)
 
136
    {
 
137
      memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version"));
 
138
      instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
 
139
      rc= MEMCACHED_SOME_ERRORS;
 
140
      continue;
 
141
    }
 
142
    instance->micro_version= uint8_t(version);
131
143
  }
132
144
 
133
145
  return rc;
135
147
 
136
148
static inline memcached_return_t memcached_version_binary(memcached_st *ptr)
137
149
{
138
 
  memcached_return_t rc;
139
150
  protocol_binary_request_version request= {};
140
151
  request.message.header.request.magic= PROTOCOL_BINARY_REQ;
141
152
  request.message.header.request.opcode= PROTOCOL_BINARY_CMD_VERSION;
142
153
  request.message.header.request.datatype= PROTOCOL_BINARY_RAW_BYTES;
143
154
 
144
 
  rc= MEMCACHED_SUCCESS;
 
155
  memcached_return_t rc= MEMCACHED_SUCCESS;
145
156
  for (uint32_t x= 0; x < memcached_server_count(ptr); x++) 
146
157
  {
147
 
    memcached_return_t rrc;
148
 
 
149
 
    memcached_server_write_instance_st instance=
150
 
      memcached_server_instance_fetch(ptr, x);
 
158
    memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, x);
151
159
 
152
160
    if (instance->major_version != UINT8_MAX)
 
161
    {
153
162
      continue;
 
163
    }
154
164
 
155
 
    rrc= memcached_do(instance, request.bytes, sizeof(request.bytes), true);
156
 
    if (rrc != MEMCACHED_SUCCESS) 
 
165
    memcached_return_t rrc= memcached_do(instance, request.bytes, sizeof(request.bytes), true);
 
166
    if (memcached_failed(rrc))
157
167
    {
158
168
      memcached_io_reset(instance);
159
169
      rc= MEMCACHED_SOME_ERRORS;
167
177
      memcached_server_instance_fetch(ptr, x);
168
178
 
169
179
    if (instance->major_version != UINT8_MAX)
 
180
    {
170
181
      continue;
 
182
    }
171
183
 
172
184
    if (memcached_server_response_count(instance) > 0) 
173
185
    {
174
 
      memcached_return_t rrc;
175
186
      char buffer[32];
176
187
      char *p;
177
188
 
178
 
      rrc= memcached_response(instance, buffer, sizeof(buffer), NULL);
179
 
      if (rrc != MEMCACHED_SUCCESS) 
 
189
      memcached_return_t rrc= memcached_response(instance, buffer, sizeof(buffer), NULL);
 
190
      if (memcached_failed(rrc))
180
191
      {
181
192
        memcached_io_reset(instance);
182
193
        rc= MEMCACHED_SOME_ERRORS;
183
194
        continue;
184
195
      }
185
196
 
186
 
      instance->major_version= (uint8_t)strtol(buffer, &p, 10);
187
 
      if (errno == ERANGE)
188
 
      {
189
 
        instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
190
 
        rc= MEMCACHED_SOME_ERRORS;
191
 
        continue;
192
 
      }
193
 
 
194
 
      instance->minor_version= (uint8_t)strtol(p + 1, &p, 10);
195
 
      if (errno == ERANGE)
196
 
      {
197
 
        instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
198
 
        rc= MEMCACHED_SOME_ERRORS;
199
 
        continue;
200
 
      }
201
 
 
202
 
      instance->micro_version= (uint8_t)strtol(p + 1, NULL, 10);
203
 
      if (errno == ERANGE)
204
 
      {
205
 
        instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
206
 
        rc= MEMCACHED_SOME_ERRORS;
207
 
        continue;
208
 
      }
209
 
 
 
197
      long int version= strtol(buffer, &p, 10);
 
198
      if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX or version == 0)
 
199
      {
 
200
        memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse major version"));
 
201
        instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
 
202
        rc= MEMCACHED_SOME_ERRORS;
 
203
        continue;
 
204
      }
 
205
      instance->major_version= uint8_t(version);
 
206
 
 
207
      version= strtol(p +1, &p, 10);
 
208
      if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX)
 
209
      {
 
210
        memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version"));
 
211
        instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
 
212
        rc= MEMCACHED_SOME_ERRORS;
 
213
        continue;
 
214
      }
 
215
      instance->minor_version= uint8_t(version);
 
216
 
 
217
      version= strtol(p + 1, NULL, 10);
 
218
      if (errno == ERANGE)
 
219
      {
 
220
        memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version"));
 
221
        instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
 
222
        rc= MEMCACHED_SOME_ERRORS;
 
223
        continue;
 
224
      }
 
225
      instance->micro_version= uint8_t(version);
210
226
    }
211
227
  }
212
228