00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00016 #include "common.h"
00017
00018
00019
00020
00021
00022 static drizzle_command_drizzle_t _command_drizzle_map[]=
00023 {
00024 DRIZZLE_COMMAND_DRIZZLE_SLEEP,
00025 DRIZZLE_COMMAND_DRIZZLE_QUIT,
00026 DRIZZLE_COMMAND_DRIZZLE_INIT_DB,
00027 DRIZZLE_COMMAND_DRIZZLE_QUERY,
00028 DRIZZLE_COMMAND_DRIZZLE_END,
00029 DRIZZLE_COMMAND_DRIZZLE_END,
00030 DRIZZLE_COMMAND_DRIZZLE_END,
00031 DRIZZLE_COMMAND_DRIZZLE_END,
00032 DRIZZLE_COMMAND_DRIZZLE_SHUTDOWN,
00033 DRIZZLE_COMMAND_DRIZZLE_END,
00034 DRIZZLE_COMMAND_DRIZZLE_END,
00035 DRIZZLE_COMMAND_DRIZZLE_CONNECT,
00036 DRIZZLE_COMMAND_DRIZZLE_END,
00037 DRIZZLE_COMMAND_DRIZZLE_END,
00038 DRIZZLE_COMMAND_DRIZZLE_PING,
00039 DRIZZLE_COMMAND_DRIZZLE_END,
00040 DRIZZLE_COMMAND_DRIZZLE_END,
00041 DRIZZLE_COMMAND_DRIZZLE_END,
00042 DRIZZLE_COMMAND_DRIZZLE_END,
00043 DRIZZLE_COMMAND_DRIZZLE_END,
00044 DRIZZLE_COMMAND_DRIZZLE_END,
00045 DRIZZLE_COMMAND_DRIZZLE_END,
00046 DRIZZLE_COMMAND_DRIZZLE_END,
00047 DRIZZLE_COMMAND_DRIZZLE_END,
00048 DRIZZLE_COMMAND_DRIZZLE_END,
00049 DRIZZLE_COMMAND_DRIZZLE_END,
00050 DRIZZLE_COMMAND_DRIZZLE_END,
00051 DRIZZLE_COMMAND_DRIZZLE_END,
00052 DRIZZLE_COMMAND_DRIZZLE_END,
00053 DRIZZLE_COMMAND_DRIZZLE_END,
00054 DRIZZLE_COMMAND_DRIZZLE_END
00055 };
00056
00057
00058
00059
00060
00061 drizzle_result_st *drizzle_quit(drizzle_con_st *con, drizzle_result_st *result,
00062 drizzle_return_t *ret_ptr)
00063 {
00064 return drizzle_command_write(con, result, DRIZZLE_COMMAND_QUIT, NULL, 0, 0,
00065 ret_ptr);
00066 }
00067
00068 drizzle_result_st *drizzle_select_db(drizzle_con_st *con,
00069 drizzle_result_st *result, const char *db,
00070 drizzle_return_t *ret_ptr)
00071 {
00072 drizzle_con_set_db(con, db);
00073 return drizzle_command_write(con, result, DRIZZLE_COMMAND_INIT_DB,
00074 (uint8_t *)db, strlen(db), strlen(db), ret_ptr);
00075 }
00076
00077 drizzle_result_st *drizzle_refresh(drizzle_con_st *con,
00078 drizzle_result_st *result,
00079 drizzle_refresh_options_t options,
00080 drizzle_return_t *ret_ptr)
00081 {
00082 return drizzle_command_write(con, result, DRIZZLE_COMMAND_REFRESH,
00083 (uint8_t *)&options, 1, 1, ret_ptr);
00084 }
00085
00086 drizzle_result_st *drizzle_shutdown(drizzle_con_st *con,
00087 drizzle_result_st *result,
00088 drizzle_shutdown_level_t level,
00089 drizzle_return_t *ret_ptr)
00090 {
00091 if (con->options & DRIZZLE_CON_MYSQL)
00092 {
00093 return drizzle_command_write(con, result, DRIZZLE_COMMAND_SHUTDOWN,
00094 (uint8_t *)&level, 1, 1, ret_ptr);
00095 }
00096
00097 return drizzle_command_write(con, result, DRIZZLE_COMMAND_SHUTDOWN, NULL, 0,
00098 0, ret_ptr);
00099 }
00100
00101 drizzle_result_st *drizzle_stat(drizzle_con_st *con, drizzle_result_st *result,
00102 drizzle_return_t *ret_ptr)
00103 {
00104 return drizzle_command_write(con, result, DRIZZLE_COMMAND_STATISTICS, NULL, 0,
00105 0, ret_ptr);
00106 }
00107
00108 drizzle_result_st *drizzle_debug_info(drizzle_con_st *con,
00109 drizzle_result_st *result,
00110 drizzle_return_t *ret_ptr)
00111 {
00112 return drizzle_command_write(con, result, DRIZZLE_COMMAND_DEBUG, NULL, 0, 0,
00113 ret_ptr);
00114 }
00115
00116 drizzle_result_st *drizzle_ping(drizzle_con_st *con, drizzle_result_st *result,
00117 drizzle_return_t *ret_ptr)
00118 {
00119 return drizzle_command_write(con, result, DRIZZLE_COMMAND_PING, NULL, 0, 0,
00120 ret_ptr);
00121 }
00122
00123 drizzle_result_st *drizzle_change_user(drizzle_con_st *con,
00124 drizzle_result_st *result,
00125 const char *user, const char *password,
00126 const char *db,
00127 drizzle_return_t *ret_ptr)
00128 {
00129 drizzle_con_set_auth(con, user, password);
00130 drizzle_con_set_db(con, db);
00131 return drizzle_command_write(con, result, DRIZZLE_COMMAND_CHANGE_USER, NULL,
00132 0, 0, ret_ptr);
00133 }
00134
00135 drizzle_result_st *drizzle_command_write(drizzle_con_st *con,
00136 drizzle_result_st *result,
00137 drizzle_command_t command,
00138 const uint8_t *data, size_t size,
00139 size_t total,
00140 drizzle_return_t *ret_ptr)
00141 {
00142 if (!(con->options & DRIZZLE_CON_READY))
00143 {
00144 if (con->options & DRIZZLE_CON_RAW_PACKET)
00145 {
00146 DRIZZLE_ERROR_SET(con->drizzle, "drizzle_command_write",
00147 "connection not ready")
00148 *ret_ptr= DRIZZLE_RETURN_NOT_READY;
00149 return result;
00150 }
00151
00152 *ret_ptr= drizzle_con_connect(con);
00153 if (*ret_ptr != DRIZZLE_RETURN_OK)
00154 return result;
00155 }
00156
00157 if (DRIZZLE_STATE_NONE(con))
00158 {
00159 if (con->options & (DRIZZLE_CON_RAW_PACKET | DRIZZLE_CON_NO_RESULT_READ))
00160 con->result= NULL;
00161 else
00162 {
00163 con->result= drizzle_result_create(con, result);
00164 if (con->result == NULL)
00165 {
00166 *ret_ptr= DRIZZLE_RETURN_MEMORY;
00167 return NULL;
00168 }
00169 }
00170
00171 con->command= command;
00172 con->command_data= (uint8_t *)data;
00173 con->command_size= size;
00174 con->command_offset= 0;
00175 con->command_total= total;
00176
00177 DRIZZLE_STATE_PUSH(con, drizzle_state_command_write)
00178 }
00179 else if (con->command_data == NULL)
00180 {
00181 con->command_data= (uint8_t *)data;
00182 con->command_size= size;
00183 }
00184
00185 *ret_ptr= drizzle_state_loop(con);
00186 if (*ret_ptr == DRIZZLE_RETURN_PAUSE)
00187 *ret_ptr= DRIZZLE_RETURN_OK;
00188 else if (*ret_ptr != DRIZZLE_RETURN_OK &&
00189 *ret_ptr != DRIZZLE_RETURN_IO_WAIT &&
00190 *ret_ptr != DRIZZLE_RETURN_ERROR_CODE)
00191 {
00192 drizzle_result_free(con->result);
00193 con->result= result;
00194 }
00195
00196 return con->result;
00197 }
00198
00199
00200
00201
00202
00203 uint8_t *drizzle_command_read(drizzle_con_st *con, drizzle_command_t *command,
00204 size_t *offset, size_t *size, size_t *total,
00205 drizzle_return_t *ret_ptr)
00206 {
00207 if (DRIZZLE_STATE_NONE(con))
00208 {
00209 con->packet_number= 0;
00210 con->command_offset= 0;
00211 con->command_total= 0;
00212
00213 DRIZZLE_STATE_PUSH(con, drizzle_state_command_read)
00214 DRIZZLE_STATE_PUSH(con, drizzle_state_packet_read)
00215 }
00216
00217 *offset= con->command_offset;
00218
00219 *ret_ptr= drizzle_state_loop(con);
00220 if (*ret_ptr == DRIZZLE_RETURN_PAUSE)
00221 *ret_ptr= DRIZZLE_RETURN_OK;
00222
00223 *command= con->command;
00224 *size= con->command_size;
00225 *total= con->command_total;
00226
00227 return con->command_data;
00228 }
00229
00230 uint8_t *drizzle_command_buffer(drizzle_con_st *con, drizzle_command_t *command,
00231 size_t *total, drizzle_return_t *ret_ptr)
00232 {
00233 uint8_t *command_data;
00234 size_t offset= 0;
00235 size_t size= 0;
00236
00237 command_data= drizzle_command_read(con, command, &offset, &size, total,
00238 ret_ptr);
00239 if (*ret_ptr != DRIZZLE_RETURN_OK)
00240 return NULL;
00241
00242 if (command_data == NULL)
00243 {
00244 *total= 0;
00245 return NULL;
00246 }
00247
00248 if (con->command_buffer == NULL)
00249 {
00250 con->command_buffer= malloc((*total) + 1);
00251 if (con->command_buffer == NULL)
00252 {
00253 DRIZZLE_ERROR_SET(con->drizzle, "drizzle_command_buffer", "malloc");
00254 *ret_ptr= DRIZZLE_RETURN_MEMORY;
00255 return NULL;
00256 }
00257 }
00258
00259 memcpy(con->command_buffer + offset, command_data, size);
00260
00261 while ((offset + size) != (*total))
00262 {
00263 command_data= drizzle_command_read(con, command, &offset, &size, total,
00264 ret_ptr);
00265 if (*ret_ptr != DRIZZLE_RETURN_OK)
00266 return NULL;
00267
00268 memcpy(con->command_buffer + offset, command_data, size);
00269 }
00270
00271 command_data= con->command_buffer;
00272 con->command_buffer= NULL;
00273 command_data[*total]= 0;
00274
00275 return command_data;
00276 }
00277
00278
00279
00280
00281
00282 drizzle_return_t drizzle_state_command_read(drizzle_con_st *con)
00283 {
00284 PDEBUG("drizzle_state_command_read", "%5zu %5zu", con->buffer_size,
00285 con->packet_size)
00286
00287 if (con->buffer_size == 0)
00288 {
00289 DRIZZLE_STATE_PUSH(con, drizzle_state_read)
00290 return DRIZZLE_RETURN_OK;
00291 }
00292
00293 if (con->command_total == 0)
00294 {
00295 con->command= (drizzle_command_t)(con->buffer_ptr[0]);
00296 con->buffer_ptr++;
00297 con->buffer_size--;
00298
00299 con->command_total= (con->packet_size - 1);
00300 }
00301
00302 if (con->buffer_size < (con->command_total - con->command_offset))
00303 {
00304 con->command_size= con->buffer_size;
00305 con->command_offset+= con->command_size;
00306 }
00307 else
00308 {
00309 con->command_size= (con->command_total - con->command_offset);
00310 con->command_offset= con->command_total;
00311 }
00312
00313 con->command_data= con->buffer_ptr;
00314 con->buffer_ptr+= con->command_size;
00315 con->buffer_size-= con->command_size;
00316
00317 if (con->command_offset == con->command_total)
00318 DRIZZLE_STATE_POP(con)
00319 else
00320 return DRIZZLE_RETURN_PAUSE;
00321
00322 return DRIZZLE_RETURN_OK;
00323 }
00324
00325 drizzle_return_t drizzle_state_command_write(drizzle_con_st *con)
00326 {
00327 uint8_t *start;
00328 uint8_t *ptr;
00329 size_t free_size;
00330 drizzle_return_t ret;
00331
00332 if (con->command_data == NULL && con->command_total != 0 &&
00333 con->command != DRIZZLE_COMMAND_CHANGE_USER)
00334 {
00335 return DRIZZLE_RETURN_PAUSE;
00336 }
00337
00338 if (con->buffer_size == 0)
00339 {
00340 con->buffer_ptr= con->buffer;
00341 start= con->buffer;
00342 }
00343 else
00344 start= con->buffer_ptr + con->buffer_size;
00345
00346 if (con->command_offset == 0)
00347 {
00348
00349
00350
00351 con->packet_size= 1
00352 + strlen(con->user) + 1
00353 + 1
00354 + DRIZZLE_MAX_SCRAMBLE_SIZE
00355 + strlen(con->db) + 1;
00356
00357
00358 free_size= (size_t)DRIZZLE_MAX_BUFFER_SIZE - (size_t)(start - con->buffer);
00359 if (free_size < con->packet_size)
00360 {
00361 DRIZZLE_STATE_PUSH(con, drizzle_state_write)
00362 return DRIZZLE_RETURN_OK;
00363 }
00364
00365
00366 con->packet_number= 1;
00367 ptr= start;
00368 ptr[3]= 0;
00369 if (con->options & DRIZZLE_CON_MYSQL)
00370 ptr[4]= (uint8_t)(con->command);
00371 else
00372 ptr[4]= (uint8_t)(_command_drizzle_map[con->command]);
00373 ptr+= 5;
00374
00375 if (con->command == DRIZZLE_COMMAND_CHANGE_USER)
00376 {
00377 ptr= drizzle_pack_auth(con, ptr, &ret);
00378 if (ret != DRIZZLE_RETURN_OK)
00379 return ret;
00380
00381 con->buffer_size+= (4 + con->packet_size);
00382 }
00383 else if (con->command_total == 0)
00384 {
00385 con->packet_size= 1;
00386 con->buffer_size+= 5;
00387 }
00388 else
00389 {
00390 con->packet_size= 1 + con->command_total;
00391 free_size-= 5;
00392
00393
00394 if (con->command_size <= free_size)
00395 {
00396 memcpy(ptr, con->command_data, con->command_size);
00397 con->command_offset= con->command_size;
00398 con->command_data= NULL;
00399 con->buffer_size+= 5 + con->command_size;
00400 }
00401 else
00402 {
00403 memcpy(ptr, con->command_data, free_size);
00404 con->command_offset= free_size;
00405 con->command_data+= free_size;
00406 con->command_size-= free_size;
00407 con->buffer_size+= 5 + free_size;
00408 }
00409 }
00410
00411
00412 DRIZZLE_SET_BYTE3(start, con->packet_size)
00413 }
00414 else
00415 {
00416
00417 con->buffer_ptr= (uint8_t *)con->command_data;
00418 con->buffer_size= con->command_size;
00419 con->command_offset+= con->command_size;
00420 con->command_data= NULL;
00421 }
00422
00423 if (con->command_offset == con->command_total)
00424 {
00425 DRIZZLE_STATE_POP(con)
00426
00427 if (!(con->options & (DRIZZLE_CON_RAW_PACKET |
00428 DRIZZLE_CON_NO_RESULT_READ)) &&
00429 con->command != DRIZZLE_COMMAND_FIELD_LIST)
00430 {
00431 DRIZZLE_STATE_PUSH(con, drizzle_state_result_read)
00432 DRIZZLE_STATE_PUSH(con, drizzle_state_packet_read)
00433 }
00434 }
00435
00436 DRIZZLE_STATE_PUSH(con, drizzle_state_write)
00437
00438 return DRIZZLE_RETURN_OK;
00439 }