~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzle-2.0/libdrizzle/command.cc

  • Committer: Lee Bieber
  • Date: 2011-03-23 18:58:39 UTC
  • mfrom: (2246.1.3 build)
  • Revision ID: kalebral@gmail.com-20110323185839-u96hq6u213nexixv
Merge Patrick - Updated dbqp's ld_lib_paths to find the new libdrizzle locations
Merge Monty - Splits out libdrizzle-1.0 and libdrizzle-2.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Drizzle Client & Protocol Library
 
3
 *
 
4
 * Copyright (C) 2008 Eric Day (eday@oddments.org)
 
5
 * All rights reserved.
 
6
 *
 
7
 * Redistribution and use in source and binary forms, with or without
 
8
 * modification, are permitted provided that the following conditions are
 
9
 * met:
 
10
 *
 
11
 *     * Redistributions of source code must retain the above copyright
 
12
 * notice, this list of conditions and the following disclaimer.
 
13
 *
 
14
 *     * Redistributions in binary form must reproduce the above
 
15
 * copyright notice, this list of conditions and the following disclaimer
 
16
 * in the documentation and/or other materials provided with the
 
17
 * distribution.
 
18
 *
 
19
 *     * The names of its contributors may not be used to endorse or
 
20
 * promote products derived from this software without specific prior
 
21
 * written permission.
 
22
 *
 
23
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
24
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
25
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
26
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 
27
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
28
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
29
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
30
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
31
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
32
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
33
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
34
 *
 
35
 */
 
36
 
 
37
 
 
38
/**
 
39
 * @file
 
40
 * @brief Command definitions
 
41
 */
 
42
 
 
43
#include "common.h"
 
44
 
 
45
/*
 
46
 * Private variables.
 
47
 */
 
48
 
 
49
static drizzle_command_drizzle_t _command_drizzle_map[]=
 
50
{
 
51
 DRIZZLE_COMMAND_DRIZZLE_END,
 
52
 DRIZZLE_COMMAND_DRIZZLE_QUIT,
 
53
 DRIZZLE_COMMAND_DRIZZLE_INIT_DB,
 
54
 DRIZZLE_COMMAND_DRIZZLE_QUERY,
 
55
 DRIZZLE_COMMAND_DRIZZLE_END,
 
56
 DRIZZLE_COMMAND_DRIZZLE_END,
 
57
 DRIZZLE_COMMAND_DRIZZLE_END,
 
58
 DRIZZLE_COMMAND_DRIZZLE_END,
 
59
 DRIZZLE_COMMAND_DRIZZLE_SHUTDOWN,
 
60
 DRIZZLE_COMMAND_DRIZZLE_END, // STATISTICS
 
61
 DRIZZLE_COMMAND_DRIZZLE_END, // PROCESS_INFO
 
62
 DRIZZLE_COMMAND_DRIZZLE_END, // CONNECT
 
63
 DRIZZLE_COMMAND_DRIZZLE_KILL,// PROCESS_KILL
 
64
 DRIZZLE_COMMAND_DRIZZLE_END,
 
65
 DRIZZLE_COMMAND_DRIZZLE_PING,
 
66
 DRIZZLE_COMMAND_DRIZZLE_END,
 
67
 DRIZZLE_COMMAND_DRIZZLE_END,
 
68
 DRIZZLE_COMMAND_DRIZZLE_END,
 
69
 DRIZZLE_COMMAND_DRIZZLE_END,
 
70
 DRIZZLE_COMMAND_DRIZZLE_END,
 
71
 DRIZZLE_COMMAND_DRIZZLE_END,
 
72
 DRIZZLE_COMMAND_DRIZZLE_END,
 
73
 DRIZZLE_COMMAND_DRIZZLE_END,
 
74
 DRIZZLE_COMMAND_DRIZZLE_END,
 
75
 DRIZZLE_COMMAND_DRIZZLE_END,
 
76
 DRIZZLE_COMMAND_DRIZZLE_END,
 
77
 DRIZZLE_COMMAND_DRIZZLE_END,
 
78
 DRIZZLE_COMMAND_DRIZZLE_END,
 
79
 DRIZZLE_COMMAND_DRIZZLE_END,
 
80
 DRIZZLE_COMMAND_DRIZZLE_END,
 
81
 DRIZZLE_COMMAND_DRIZZLE_END
 
82
};
 
83
 
 
84
/*
 
85
 * State Definitions
 
86
 */
 
87
 
 
88
drizzle_return_t drizzle_state_command_read(drizzle_con_st *con)
 
89
{
 
90
  drizzle_log_debug(con->drizzle, "drizzle_state_command_read");
 
91
 
 
92
  if (con->buffer_size == 0)
 
93
  {
 
94
    drizzle_state_push(con, drizzle_state_read);
 
95
    return DRIZZLE_RETURN_OK;
 
96
  }
 
97
 
 
98
  if (con->command_total == 0)
 
99
  {
 
100
    con->command= (drizzle_command_t)(con->buffer_ptr[0]);
 
101
    con->buffer_ptr++;
 
102
    con->buffer_size--;
 
103
 
 
104
    con->command_total= (con->packet_size - 1);
 
105
  }
 
106
 
 
107
  if (con->buffer_size < (con->command_total - con->command_offset))
 
108
  {
 
109
    con->command_size= con->buffer_size;
 
110
    con->command_offset+= con->command_size;
 
111
  }
 
112
  else
 
113
  {
 
114
    con->command_size= (con->command_total - con->command_offset);
 
115
    con->command_offset= con->command_total;
 
116
  }
 
117
 
 
118
  con->command_data= con->buffer_ptr;
 
119
  con->buffer_ptr+= con->command_size;
 
120
  con->buffer_size-= con->command_size;
 
121
 
 
122
  if (con->command_offset == con->command_total)
 
123
    drizzle_state_pop(con);
 
124
  else
 
125
    return DRIZZLE_RETURN_PAUSE;
 
126
 
 
127
  return DRIZZLE_RETURN_OK;
 
128
}
 
129
 
 
130
drizzle_return_t drizzle_state_command_write(drizzle_con_st *con)
 
131
{
 
132
  uint8_t *start;
 
133
  uint8_t *ptr;
 
134
  size_t free_size;
 
135
  drizzle_return_t ret;
 
136
 
 
137
  drizzle_log_debug(con->drizzle, "drizzle_state_command_write");
 
138
 
 
139
  if (con->command_data == NULL && con->command_total != 0 &&
 
140
      con->command != DRIZZLE_COMMAND_CHANGE_USER)
 
141
  {
 
142
    return DRIZZLE_RETURN_PAUSE;
 
143
  }
 
144
 
 
145
  if (con->buffer_size == 0)
 
146
  {
 
147
    con->buffer_ptr= con->buffer;
 
148
    start= con->buffer;
 
149
  }
 
150
  else
 
151
    start= con->buffer_ptr + con->buffer_size;
 
152
 
 
153
  if (con->command_offset == 0)
 
154
  {
 
155
    /* Make sure we can fit the largest non-streaming packet, currently a
 
156
       DRIZZLE_COMMAND_CHANGE_USER command. */
 
157
 
 
158
    con->packet_size= 1  /* Command */
 
159
                    + strlen(con->user) + 1
 
160
                    + 1  /* Scramble size */
 
161
                    + DRIZZLE_MAX_SCRAMBLE_SIZE
 
162
                    + strlen(con->db) + 1;
 
163
 
 
164
    /* Flush buffer if there is not enough room. */
 
165
    free_size= (size_t)DRIZZLE_MAX_BUFFER_SIZE - (size_t)(start - con->buffer);
 
166
    if (free_size < con->packet_size)
 
167
    {
 
168
      drizzle_state_push(con, drizzle_state_write);
 
169
      return DRIZZLE_RETURN_OK;
 
170
    }
 
171
 
 
172
    /* Store packet size at the end since it may change. */
 
173
    con->packet_number= 1;
 
174
    ptr= start;
 
175
    ptr[3]= 0;
 
176
    if (con->options & DRIZZLE_CON_MYSQL)
 
177
      ptr[4]= (uint8_t)(con->command);
 
178
    else
 
179
      ptr[4]= (uint8_t)(_command_drizzle_map[con->command]);
 
180
    ptr+= 5;
 
181
 
 
182
    if (con->command == DRIZZLE_COMMAND_CHANGE_USER)
 
183
    {
 
184
      ptr= drizzle_pack_auth(con, ptr, &ret);
 
185
      if (ret != DRIZZLE_RETURN_OK)
 
186
        return ret;
 
187
 
 
188
      con->buffer_size+= (4 + con->packet_size);
 
189
    }
 
190
    else if (con->command_total == 0)
 
191
    {
 
192
      con->packet_size= 1;
 
193
      con->buffer_size+= 5;
 
194
    }
 
195
    else
 
196
    {
 
197
      con->packet_size= 1 + con->command_total;
 
198
      free_size-= 5;
 
199
 
 
200
      /* Copy as much of the data in as we can into the write buffer. */
 
201
      if (con->command_size <= free_size)
 
202
      {
 
203
        memcpy(ptr, con->command_data, con->command_size);
 
204
        con->command_offset= con->command_size;
 
205
        con->command_data= NULL;
 
206
        con->buffer_size+= 5 + con->command_size;
 
207
      }
 
208
      else
 
209
      {
 
210
        memcpy(ptr, con->command_data, free_size);
 
211
        con->command_offset= free_size;
 
212
        con->command_data+= free_size;
 
213
        con->command_size-= free_size;
 
214
        con->buffer_size+= 5 + free_size;
 
215
      }
 
216
    }
 
217
 
 
218
    /* Store packet size now. */
 
219
    drizzle_set_byte3(start, con->packet_size);
 
220
  }
 
221
  else
 
222
  {
 
223
    /* Write directly from the caller buffer for the rest. */
 
224
    con->buffer_ptr= con->command_data;
 
225
    con->buffer_size= con->command_size;
 
226
    con->command_offset+= con->command_size;
 
227
    con->command_data= NULL;
 
228
  }
 
229
 
 
230
  if (con->command_offset == con->command_total)
 
231
  {
 
232
    drizzle_state_pop(con);
 
233
 
 
234
    if (!(con->options & (DRIZZLE_CON_RAW_PACKET |
 
235
                          DRIZZLE_CON_NO_RESULT_READ)) &&
 
236
        con->command != DRIZZLE_COMMAND_FIELD_LIST)
 
237
    {
 
238
      drizzle_state_push(con, drizzle_state_result_read);
 
239
      drizzle_state_push(con, drizzle_state_packet_read);
 
240
    }
 
241
  }
 
242
 
 
243
  drizzle_state_push(con, drizzle_state_write);
 
244
 
 
245
  return DRIZZLE_RETURN_OK;
 
246
}