~drizzle-trunk/drizzle/development

971.3.12 by Eric Day
Started abstracting Protocol, removed init_connect, init_file.
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
4
 *  Copyright (C) 2008 Sun Microsystems
5
 *
6
 * This program is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; version 2 of the License.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 */
1 by brian
clean slate
19
243.1.17 by Jay Pipes
FINAL PHASE removal of mysql_priv.h (Bye, bye my friend.)
20
#include <drizzled/server_includes.h>
971.3.60 by Eric Day
Moved connect_timeout, net_*_timeout, and retry_count to plugin.
21
#include <drizzled/gettext.h>
549 by Monty Taylor
Took gettext.h out of header files.
22
#include <drizzled/error.h>
971.3.61 by Eric Day
Removed setRandom from Protocol class.
23
#include <drizzled/query_id.h>
468 by Monty Taylor
Repaced sql_state stuff with template function and c++ algorithm.
24
#include <drizzled/sql_state.h>
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
25
#include <drizzled/session.h>
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
26
#include <algorithm>
27
971.3.14 by Eric Day
Created Protocol plugin interface and changed libdrizzleclient to be a plugin.
28
#include "pack.h"
29
#include "errmsg.h"
971.3.16 by Eric Day
Cleaned up Protocol plugin interface (now a class factory) and moved libdrizzlclient to oldlibdrizzle to be clear.
30
#include "oldlibdrizzle.h"
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
31
#include "options.h"
1067.4.8 by Nathan Williams
Converted all usages of cmin/cmax in plugin directory to std::min/max.
32
33
using namespace std;
971.3.65 by Eric Day
Namespace cleanup for Protocol and Listen.
34
using namespace drizzled;
1067.4.8 by Nathan Williams
Converted all usages of cmin/cmax in plugin directory to std::min/max.
35
971.3.48 by Eric Day
New Listen interface about done, not quite compiling yet, but need a backup.
36
#define PROTOCOL_VERSION 10
37
38
extern uint32_t drizzled_tcp_port;
971.3.5 by Eric Day
Moved more drizzleclient/NET specific code to Protocol class.
39
1 by brian
clean slate
40
static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024;
971.3.60 by Eric Day
Moved connect_timeout, net_*_timeout, and retry_count to plugin.
41
static uint32_t connect_timeout;
42
static uint32_t read_timeout;
43
static uint32_t write_timeout;
44
static uint32_t retry_count;
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
45
static uint32_t buffer_length;
46
static char* bind_address;
47
48
const char* ListenOldLibdrizzle::getHost(void) const
49
{
50
  return bind_address;
51
}
971.3.48 by Eric Day
New Listen interface about done, not quite compiling yet, but need a backup.
52
971.3.51 by Eric Day
Finished up new Listen plugin interface.
53
in_port_t ListenOldLibdrizzle::getPort(void) const
971.3.48 by Eric Day
New Listen interface about done, not quite compiling yet, but need a backup.
54
{
971.6.7 by Eric Day
Reworked listen interface to not require binding of TCP ports.
55
  return (in_port_t) drizzled_tcp_port;
971.3.48 by Eric Day
New Listen interface about done, not quite compiling yet, but need a backup.
56
}
57
971.6.7 by Eric Day
Reworked listen interface to not require binding of TCP ports.
58
plugin::Client *ListenOldLibdrizzle::getClient(int fd)
971.3.48 by Eric Day
New Listen interface about done, not quite compiling yet, but need a backup.
59
{
971.6.7 by Eric Day
Reworked listen interface to not require binding of TCP ports.
60
  int new_fd;
61
  new_fd= acceptTcp(fd);
62
  if (new_fd == -1)
63
    return NULL;
64
65
  return new (nothrow) ClientOldLibdrizzle(new_fd);
971.3.48 by Eric Day
New Listen interface about done, not quite compiling yet, but need a backup.
66
}
971.3.8 by Eric Day
Moved NET to Protocol. libdrizzleclient is now completely isolated, need to start reworking Protocol now.
67
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
68
ClientOldLibdrizzle::ClientOldLibdrizzle(int fd)
69
{
70
  net.vio= 0;
71
72
  if (fd == -1)
73
    return;
74
75
  if (drizzleclient_net_init_sock(&net, fd, 0, buffer_length))
76
    throw bad_alloc();
77
78
  drizzleclient_net_set_read_timeout(&net, read_timeout);
79
  drizzleclient_net_set_write_timeout(&net, write_timeout);
80
  net.retry_count=retry_count;
81
}
82
83
ClientOldLibdrizzle::~ClientOldLibdrizzle()
84
{
85
  if (net.vio)
86
    drizzleclient_vio_close(net.vio);
87
}
88
89
int ClientOldLibdrizzle::getFileDescriptor(void)
90
{
91
  return drizzleclient_net_get_sd(&net);
92
}
1 by brian
clean slate
93
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
94
bool ClientOldLibdrizzle::isConnected()
971.3.5 by Eric Day
Moved more drizzleclient/NET specific code to Protocol class.
95
{
971.3.8 by Eric Day
Moved NET to Protocol. libdrizzleclient is now completely isolated, need to start reworking Protocol now.
96
  return net.vio != 0;
971.3.5 by Eric Day
Moved more drizzleclient/NET specific code to Protocol class.
97
}
98
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
99
bool ClientOldLibdrizzle::isReading(void)
971.3.8 by Eric Day
Moved NET to Protocol. libdrizzleclient is now completely isolated, need to start reworking Protocol now.
100
{
101
  return net.reading_or_writing == 1;
102
}
103
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
104
bool ClientOldLibdrizzle::isWriting(void)
971.3.8 by Eric Day
Moved NET to Protocol. libdrizzleclient is now completely isolated, need to start reworking Protocol now.
105
{
106
  return net.reading_or_writing == 2;
971.3.5 by Eric Day
Moved more drizzleclient/NET specific code to Protocol class.
107
}
108
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
109
bool ClientOldLibdrizzle::flush()
110
{
111
  if (net.vio == NULL)
112
    return false;
113
  bool ret= drizzleclient_net_write(&net, (unsigned char*) packet.ptr(),
114
                           packet.length());
115
  packet.length(0);
116
  return ret;
117
}
118
119
void ClientOldLibdrizzle::close(void)
120
{
121
  if (net.vio)
122
  { 
123
    drizzleclient_net_close(&net);
124
    drizzleclient_net_end(&net);
125
  }
126
}
127
128
bool ClientOldLibdrizzle::authenticate()
129
{
130
  bool connection_is_valid;
131
132
  /* Use "connect_timeout" value during connection phase */
133
  drizzleclient_net_set_read_timeout(&net, connect_timeout);
134
  drizzleclient_net_set_write_timeout(&net, connect_timeout);
135
136
  connection_is_valid= checkConnection();
137
138
  if (connection_is_valid)
139
    sendOK();
140
  else
141
  {
142
    sendError(session->main_da.sql_errno(), session->main_da.message());
143
    return false;
144
  }
145
146
  /* Connect completed, set read/write timeouts back to default */
147
  drizzleclient_net_set_read_timeout(&net, read_timeout);
148
  drizzleclient_net_set_write_timeout(&net, write_timeout);
149
  return true;
150
}
151
152
bool ClientOldLibdrizzle::readCommand(char **l_packet, uint32_t *packet_length)
153
{
154
  /*
155
    This thread will do a blocking read from the client which
156
    will be interrupted when the next command is received from
157
    the client, the connection is closed or "net_wait_timeout"
158
    number of seconds has passed
159
  */
160
#ifdef NEVER
161
  /* We can do this much more efficiently with poll timeouts or watcher thread,
162
     disabling for now, which means net_wait_timeout == read_timeout. */
163
  drizzleclient_net_set_read_timeout(&net,
164
                                     session->variables.net_wait_timeout);
165
#endif
166
167
  net.pkt_nr=0;
168
169
  *packet_length= drizzleclient_net_read(&net);
170
  if (*packet_length == packet_error)
171
  {
172
    /* Check if we can continue without closing the connection */
173
174
    if(net.last_errno== CR_NET_PACKET_TOO_LARGE)
175
      my_error(ER_NET_PACKET_TOO_LARGE, MYF(0));
176
    if (session->main_da.status() == Diagnostics_area::DA_ERROR)
177
      sendError(session->main_da.sql_errno(), session->main_da.message());
178
    else
179
      sendOK();
180
181
    if (net.error != 3)
182
      return false;                       // We have to close it.
183
184
    net.error= 0;
185
    *packet_length= 0;
186
    return true;
187
  }
188
189
  *l_packet= (char*) net.read_pos;
190
191
  /*
192
    'packet_length' contains length of data, as it was stored in packet
193
    header. In case of malformed header, drizzleclient_net_read returns zero.
194
    If packet_length is not zero, drizzleclient_net_read ensures that the returned
195
    number of bytes was actually read from network.
196
    There is also an extra safety measure in drizzleclient_net_read:
197
    it sets packet[packet_length]= 0, but only for non-zero packets.
198
  */
199
200
  if (*packet_length == 0)                       /* safety */
201
  {
202
    /* Initialize with COM_SLEEP packet */
203
    (*l_packet)[0]= (unsigned char) COM_SLEEP;
204
    *packet_length= 1;
205
  }
206
  /* Do not rely on drizzleclient_net_read, extra safety against programming errors. */
207
  (*l_packet)[*packet_length]= '\0';                  /* safety */
208
209
#ifdef NEVER
210
  /* See comment above. */
211
  /* Restore read timeout value */
212
  drizzleclient_net_set_read_timeout(&net,
213
                                     session->variables.net_read_timeout);
214
#endif
215
216
  return true;
217
}
1 by brian
clean slate
218
219
/**
220
  Return ok to the client.
221
222
  The ok packet has the following structure:
223
224
  - 0               : Marker (1 byte)
971.3.17 by Eric Day
Cleaned up int/date related store functions.
225
  - affected_rows    : Stored in 1-9 bytes
226
  - id        : Stored in 1-9 bytes
227
  - server_status    : Copy of session->server_status;  Can be used by client
1 by brian
clean slate
228
  to check if we are inside an transaction.
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
229
  New in 4.0 client
230
  - warning_count    : Stored in 2 bytes; New in 4.1 client
971.3.17 by Eric Day
Cleaned up int/date related store functions.
231
  - message        : Stored as packed length (1-9 bytes) + message.
1 by brian
clean slate
232
  Is not stored if no message.
233
971.3.17 by Eric Day
Cleaned up int/date related store functions.
234
  @param session           Thread handler
235
  @param affected_rows       Number of rows changed by statement
236
  @param id           Auto_increment id for first row (if used)
237
  @param message       Message to send to the client (Used by mysql_status)
1 by brian
clean slate
238
*/
239
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
240
void ClientOldLibdrizzle::sendOK()
971.3.12 by Eric Day
Started abstracting Protocol, removed init_connect, init_file.
241
{
242
  unsigned char buff[DRIZZLE_ERRMSG_SIZE+10],*pos;
243
  const char *message= NULL;
244
  uint32_t tmp;
245
971.3.17 by Eric Day
Cleaned up int/date related store functions.
246
  if (!net.vio)    // hack for re-parsing queries
971.3.12 by Eric Day
Started abstracting Protocol, removed init_connect, init_file.
247
  {
248
    return;
249
  }
250
971.3.17 by Eric Day
Cleaned up int/date related store functions.
251
  buff[0]=0;                    // No fields
971.3.12 by Eric Day
Started abstracting Protocol, removed init_connect, init_file.
252
  if (session->main_da.status() == Diagnostics_area::DA_OK)
253
  {
971.3.59 by Eric Day
Removed client_capabilities from session and pushed functionality into protocol plugin.
254
    if (client_capabilities & CLIENT_FOUND_ROWS && session->main_da.found_rows())
255
      pos=drizzleclient_net_store_length(buff+1,session->main_da.found_rows());
256
    else
257
      pos=drizzleclient_net_store_length(buff+1,session->main_da.affected_rows());
971.3.12 by Eric Day
Started abstracting Protocol, removed init_connect, init_file.
258
    pos=drizzleclient_net_store_length(pos, session->main_da.last_insert_id());
259
    int2store(pos, session->main_da.server_status());
260
    pos+=2;
1067.4.8 by Nathan Williams
Converted all usages of cmin/cmax in plugin directory to std::min/max.
261
    tmp= min(session->main_da.total_warn_count(), (uint32_t)65535);
971.3.12 by Eric Day
Started abstracting Protocol, removed init_connect, init_file.
262
    message= session->main_da.message();
263
  }
264
  else
265
  {
266
    pos=drizzleclient_net_store_length(buff+1,0);
267
    pos=drizzleclient_net_store_length(pos, 0);
268
    int2store(pos, session->server_status);
269
    pos+=2;
1067.4.8 by Nathan Williams
Converted all usages of cmin/cmax in plugin directory to std::min/max.
270
    tmp= min(session->total_warn_count, (uint32_t)65535);
971.3.12 by Eric Day
Started abstracting Protocol, removed init_connect, init_file.
271
  }
272
273
  /* We can only return up to 65535 warnings in two bytes */
274
  int2store(pos, tmp);
275
  pos+= 2;
276
277
  session->main_da.can_overwrite_status= true;
278
279
  if (message && message[0])
280
  {
281
    size_t length= strlen(message);
282
    pos=drizzleclient_net_store_length(pos,length);
283
    memcpy(pos,(unsigned char*) message,length);
284
    pos+=length;
285
  }
286
  drizzleclient_net_write(&net, buff, (size_t) (pos-buff));
287
  drizzleclient_net_flush(&net);
288
289
  session->main_da.can_overwrite_status= false;
290
}
1 by brian
clean slate
291
292
/**
293
  Send eof (= end of result set) to the client.
294
295
  The eof packet has the following structure:
296
971.3.17 by Eric Day
Cleaned up int/date related store functions.
297
  - 254    (DRIZZLE_PROTOCOL_NO_MORE_DATA)    : Marker (1 byte)
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
298
  - warning_count    : Stored in 2 bytes; New in 4.1 client
971.3.17 by Eric Day
Cleaned up int/date related store functions.
299
  - status_flag    : Stored in 2 bytes;
1 by brian
clean slate
300
  For flags like SERVER_MORE_RESULTS_EXISTS.
301
302
  Note that the warning count will not be sent if 'no_flush' is set as
303
  we don't want to report the warning count until all data is sent to the
304
  client.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
305
*/
1 by brian
clean slate
306
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
307
void ClientOldLibdrizzle::sendEOF()
971.3.12 by Eric Day
Started abstracting Protocol, removed init_connect, init_file.
308
{
309
  /* Set to true if no active vio, to work well in case of --init-file */
310
  if (net.vio != 0)
311
  {
312
    session->main_da.can_overwrite_status= true;
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
313
    writeEOFPacket(session->main_da.server_status(),
314
                   session->main_da.total_warn_count());
971.3.12 by Eric Day
Started abstracting Protocol, removed init_connect, init_file.
315
    drizzleclient_net_flush(&net);
316
    session->main_da.can_overwrite_status= false;
317
  }
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
318
  packet.shrink(buffer_length);
319
}
320
1 by brian
clean slate
321
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
322
void ClientOldLibdrizzle::sendError(uint32_t sql_errno, const char *err)
1 by brian
clean slate
323
{
482 by Brian Aker
Remove uint.
324
  uint32_t length;
1 by brian
clean slate
325
  /*
261.4.1 by Felipe
- Renamed MYSQL_ERROR to DRIZZLE_ERROR.
326
    buff[]: sql_errno:2 + ('#':1 + SQLSTATE_LENGTH:5) + DRIZZLE_ERRMSG_SIZE:512
1 by brian
clean slate
327
  */
481 by Brian Aker
Remove all of uchar.
328
  unsigned char buff[2+1+SQLSTATE_LENGTH+DRIZZLE_ERRMSG_SIZE], *pos;
1 by brian
clean slate
329
971.3.17 by Eric Day
Cleaned up int/date related store functions.
330
  assert(sql_errno);
331
  assert(err && err[0]);
332
333
  /*
334
    It's one case when we can push an error even though there
335
    is an OK or EOF already.
336
  */
337
  session->main_da.can_overwrite_status= true;
338
339
  /* Abort multi-result sets */
340
  session->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
341
342
  /**
343
    Send a error string to client.
344
345
    For SIGNAL/RESIGNAL and GET DIAGNOSTICS functionality it's
346
    critical that every error that can be intercepted is issued in one
347
    place only, my_message_sql.
348
  */
349
971.3.8 by Eric Day
Moved NET to Protocol. libdrizzleclient is now completely isolated, need to start reworking Protocol now.
350
  if (net.vio == 0)
1 by brian
clean slate
351
  {
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
352
    return;
1 by brian
clean slate
353
  }
354
355
  int2store(buff,sql_errno);
356
  pos= buff+2;
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
357
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
358
  /* The first # is to make the client backward compatible */
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
359
  buff[2]= '#';
971.3.4 by Eric Day
Further drizzleclient cleanup. Starting to move all NET related functions into Protocol, removed some dead code, removing drizzleclient dependencies spread throughout drizzled.
360
  pos= (unsigned char*) strcpy((char*) buff+3, drizzle_errno_to_sqlstate(sql_errno));
361
  pos+= strlen(drizzle_errno_to_sqlstate(sql_errno));
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
362
629.5.3 by Toru Maesaka
Third pass of replacing MySQL's strmake() with libc calls
363
  char *tmp= strncpy((char*)pos, err, DRIZZLE_ERRMSG_SIZE-1);
364
  tmp+= strlen((char*)pos);
365
  tmp[0]= '\0';
366
  length= (uint32_t)(tmp-(char*)buff);
1 by brian
clean slate
367
  err= (char*) buff;
368
971.3.8 by Eric Day
Moved NET to Protocol. libdrizzleclient is now completely isolated, need to start reworking Protocol now.
369
  drizzleclient_net_write_command(&net,(unsigned char) 255, (unsigned char*) "", 0, (unsigned char*) err, length);
370
371
  session->main_da.can_overwrite_status= false;
1 by brian
clean slate
372
}
373
374
/**
375
  Send name and type of result to client.
376
377
  Sum fields has table name empty and field_name.
378
971.3.17 by Eric Day
Cleaned up int/date related store functions.
379
  @param Session        Thread data object
380
  @param list            List of items to send to client
381
  @param flag            Bit mask with the following functions:
1 by brian
clean slate
382
                        - 1 send number of rows
383
                        - 2 send default values
384
                        - 4 don't write eof packet
385
386
  @retval
971.3.17 by Eric Day
Cleaned up int/date related store functions.
387
    0    ok
1 by brian
clean slate
388
  @retval
971.3.17 by Eric Day
Cleaned up int/date related store functions.
389
    1    Error  (Note that in this case the error is not sent to the
1 by brian
clean slate
390
    client)
391
*/
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
392
bool ClientOldLibdrizzle::sendFields(List<Item> *list)
1 by brian
clean slate
393
{
394
  List_iterator_fast<Item> it(*list);
395
  Item *item;
481 by Brian Aker
Remove all of uchar.
396
  unsigned char buff[80];
1 by brian
clean slate
397
  String tmp((char*) buff,sizeof(buff),&my_charset_bin);
398
971.3.63 by Eric Day
Removed protocol field flags.
399
  unsigned char *row_pos= drizzleclient_net_store_length(buff, list->elements);
400
  (void) drizzleclient_net_write(&net, buff, (size_t) (row_pos-buff));
1 by brian
clean slate
401
402
  while ((item=it++))
403
  {
404
    char *pos;
1052.2.4 by Nathan Williams
No actual code changes. Changed Send_field to SendField to be consistent with coding standards.
405
    SendField field;
1 by brian
clean slate
406
    item->make_field(&field);
407
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
408
    packet.length(0);
971.6.2 by Eric Day
Fixed bug, accidently removed prepareForResend call.
409
1054.2.9 by Monty Taylor
Removed CHARSET_INFO stuff from protocol plugin interface - it makes no sense.
410
    if (store(STRING_WITH_LEN("def")) ||
411
        store(field.db_name) ||
412
        store(field.table_name) ||
413
        store(field.org_table_name) ||
414
        store(field.col_name) ||
415
        store(field.org_col_name) ||
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
416
        packet.realloc(packet.length()+12))
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
417
      goto err;
418
419
    /* Store fixed length fields */
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
420
    pos= (char*) packet.ptr()+packet.length();
971.3.17 by Eric Day
Cleaned up int/date related store functions.
421
    *pos++= 12;                // Length of packed fields
1054.2.9 by Monty Taylor
Removed CHARSET_INFO stuff from protocol plugin interface - it makes no sense.
422
    /* No conversion */
423
    int2store(pos, field.charsetnr);
424
    int4store(pos+2, field.length);
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
425
    pos[6]= field.type;
426
    int2store(pos+7,field.flags);
427
    pos[9]= (char) field.decimals;
971.3.17 by Eric Day
Cleaned up int/date related store functions.
428
    pos[10]= 0;                // For the future
429
    pos[11]= 0;                // For the future
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
430
    pos+= 12;
1 by brian
clean slate
431
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
432
    packet.length((uint32_t) (pos - packet.ptr()));
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
433
    if (flush())
971.6.11 by Eric Day
Removed purecov messages.
434
      break;
1 by brian
clean slate
435
  }
436
971.3.63 by Eric Day
Removed protocol field flags.
437
  /*
438
    Mark the end of meta-data result set, and store session->server_status,
439
    to show that there is no cursor.
440
    Send no warning information, as it will be sent at statement end.
441
  */
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
442
  writeEOFPacket(session->server_status, session->total_warn_count);
971.3.19 by Eric Day
Finished first pass at Protocol cleanup, still some things to remove but they are a bit more involved.
443
  return 0;
1 by brian
clean slate
444
445
err:
446
  my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES),
971.6.11 by Eric Day
Removed purecov messages.
447
             MYF(0));
448
  return 1;
1 by brian
clean slate
449
}
450
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
451
bool ClientOldLibdrizzle::store(Field *from)
452
{
453
  if (from->is_null())
454
    return store();
455
  char buff[MAX_FIELD_WIDTH];
456
  String str(buff,sizeof(buff), &my_charset_bin);
457
458
  from->val_str(&str);
459
460
  return netStoreData((const unsigned char *)str.ptr(), str.length());
1 by brian
clean slate
461
}
462
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
463
bool ClientOldLibdrizzle::store(void)
1 by brian
clean slate
464
{
465
  char buff[1];
466
  buff[0]= (char)251;
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
467
  return packet.append(buff, sizeof(buff), PACKET_BUFFER_EXTRA_ALLOC);
468
}
1 by brian
clean slate
469
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
470
bool ClientOldLibdrizzle::store(int32_t from)
971.3.17 by Eric Day
Cleaned up int/date related store functions.
471
{
472
  char buff[12];
473
  return netStoreData((unsigned char*) buff,
474
                      (size_t) (int10_to_str(from, buff, -10) - buff));
475
}
476
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
477
bool ClientOldLibdrizzle::store(uint32_t from)
971.3.17 by Eric Day
Cleaned up int/date related store functions.
478
{
479
  char buff[11];
480
  return netStoreData((unsigned char*) buff,
481
                      (size_t) (int10_to_str(from, buff, 10) - buff));
482
}
483
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
484
bool ClientOldLibdrizzle::store(int64_t from)
1 by brian
clean slate
485
{
486
  char buff[22];
971.3.12 by Eric Day
Started abstracting Protocol, removed init_connect, init_file.
487
  return netStoreData((unsigned char*) buff,
971.3.17 by Eric Day
Cleaned up int/date related store functions.
488
                      (size_t) (int64_t10_to_str(from, buff, -10) - buff));
489
}
490
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
491
bool ClientOldLibdrizzle::store(uint64_t from)
971.3.17 by Eric Day
Cleaned up int/date related store functions.
492
{
493
  char buff[21];
494
  return netStoreData((unsigned char*) buff,
495
                      (size_t) (int64_t10_to_str(from, buff, 10) - buff));
1 by brian
clean slate
496
}
497
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
498
bool ClientOldLibdrizzle::store(double from, uint32_t decimals, String *buffer)
1 by brian
clean slate
499
{
520.1.22 by Brian Aker
Second pass of thd cleanup
500
  buffer->set_real(from, decimals, session->charset());
971.3.12 by Eric Day
Started abstracting Protocol, removed init_connect, init_file.
501
  return netStoreData((unsigned char*) buffer->ptr(), buffer->length());
1 by brian
clean slate
502
}
503
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
504
bool ClientOldLibdrizzle::store(const char *from, size_t length)
505
{
506
  return netStoreData((const unsigned char *)from, length);
507
}
508
509
bool ClientOldLibdrizzle::wasAborted(void)
510
{
511
  return net.error && net.vio != 0;
512
}
513
514
bool ClientOldLibdrizzle::haveMoreData(void)
515
{
516
  return drizzleclient_net_more_data(&net);
517
}
518
519
bool ClientOldLibdrizzle::haveError(void)
520
{
521
  return net.error || net.vio == 0;
1 by brian
clean slate
522
}
523
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
524
bool ClientOldLibdrizzle::checkConnection(void)
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
525
{
526
  uint32_t pkt_len= 0;
527
  char *end;
528
529
  // TCP/IP connection
530
  {
531
    char ip[NI_MAXHOST];
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
532
    uint16_t port;
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
533
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
534
    if (drizzleclient_net_peer_addr(&net, ip, &port, NI_MAXHOST))
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
535
    {
536
      my_error(ER_BAD_HOST_ERROR, MYF(0), session->security_ctx.ip.c_str());
537
      return false;
538
    }
539
540
    session->security_ctx.ip.assign(ip);
541
  }
971.3.8 by Eric Day
Moved NET to Protocol. libdrizzleclient is now completely isolated, need to start reworking Protocol now.
542
  drizzleclient_net_keepalive(&net, true);
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
543
544
  uint32_t server_capabilites;
545
  {
546
    /* buff[] needs to big enough to hold the server_version variable */
547
    char buff[SERVER_VERSION_LENGTH + SCRAMBLE_LENGTH + 64];
548
549
    server_capabilites= CLIENT_BASIC_FLAGS;
550
551
#ifdef HAVE_COMPRESS
552
    server_capabilites|= CLIENT_COMPRESS;
553
#endif /* HAVE_COMPRESS */
554
1081.1.1 by Monty Taylor
Whole boat-load of build fixes.
555
    end= buff + strlen(VERSION);
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
556
    if ((end - buff) >= SERVER_VERSION_LENGTH)
557
      end= buff + (SERVER_VERSION_LENGTH - 1);
1081.1.1 by Monty Taylor
Whole boat-load of build fixes.
558
    memcpy(buff, VERSION, end - buff);
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
559
    *end= 0;
560
    end++;
561
971.3.66 by Eric Day
Fixed thread_id bug from session refactoring work.
562
    int4store((unsigned char*) end, global_thread_id);
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
563
    end+= 4;
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
564
565
    /* We don't use scramble anymore. */
566
    memset(end, 'X', SCRAMBLE_LENGTH_323);
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
567
    end+= SCRAMBLE_LENGTH_323;
568
    *end++= 0; /* an empty byte for some reason */
569
570
    int2store(end, server_capabilites);
571
    /* write server characteristics: up to 16 bytes allowed */
572
    end[2]=(char) default_charset_info->number;
573
    int2store(end+3, session->server_status);
574
    memset(end+5, 0, 13);
575
    end+= 18;
576
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
577
    /* Write scramble tail. */
578
    memset(end, 'X', SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323);
579
    end+= (SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323);
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
580
    *end++= 0; /* an empty byte for some reason */
581
582
    /* At this point we write connection message and read reply */
971.3.8 by Eric Day
Moved NET to Protocol. libdrizzleclient is now completely isolated, need to start reworking Protocol now.
583
    if (drizzleclient_net_write_command(&net
971.3.48 by Eric Day
New Listen interface about done, not quite compiling yet, but need a backup.
584
          , (unsigned char) PROTOCOL_VERSION
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
585
          , (unsigned char*) ""
586
          , 0
587
          , (unsigned char*) buff
588
          , (size_t) (end-buff)) 
971.3.17 by Eric Day
Cleaned up int/date related store functions.
589
        ||    (pkt_len= drizzleclient_net_read(&net)) == packet_error 
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
590
        || pkt_len < MIN_HANDSHAKE_SIZE)
591
    {
592
      my_error(ER_HANDSHAKE_ERROR, MYF(0), session->security_ctx.ip.c_str());
593
      return false;
594
    }
595
  }
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
596
  if (packet.alloc(buffer_length))
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
597
    return false; /* The error is set by alloc(). */
598
971.3.59 by Eric Day
Removed client_capabilities from session and pushed functionality into protocol plugin.
599
  client_capabilities= uint2korr(net.read_pos);
600
601
602
  client_capabilities|= ((uint32_t) uint2korr(net.read_pos + 2)) << 16;
971.3.8 by Eric Day
Moved NET to Protocol. libdrizzleclient is now completely isolated, need to start reworking Protocol now.
603
  session->max_client_packet_length= uint4korr(net.read_pos + 4);
604
  end= (char*) net.read_pos + 32;
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
605
606
  /*
607
    Disable those bits which are not supported by the server.
608
    This is a precautionary measure, if the client lies. See Bug#27944.
609
  */
971.3.59 by Eric Day
Removed client_capabilities from session and pushed functionality into protocol plugin.
610
  client_capabilities&= server_capabilites;
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
611
971.3.8 by Eric Day
Moved NET to Protocol. libdrizzleclient is now completely isolated, need to start reworking Protocol now.
612
  if (end >= (char*) net.read_pos + pkt_len + 2)
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
613
  {
614
    my_error(ER_HANDSHAKE_ERROR, MYF(0), session->security_ctx.ip.c_str());
615
    return false;
616
  }
617
971.3.8 by Eric Day
Moved NET to Protocol. libdrizzleclient is now completely isolated, need to start reworking Protocol now.
618
  net.return_status= &session->server_status;
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
619
620
  char *user= end;
621
  char *passwd= strchr(user, '\0')+1;
622
  uint32_t user_len= passwd - user - 1;
623
  char *l_db= passwd;
624
625
  /*
626
    Old clients send null-terminated string as password; new clients send
627
    the size (1 byte) + string (not null-terminated). Hence in case of empty
628
    password both send '\0'.
629
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
630
    This strlen() can't be easily deleted without changing client.
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
631
632
    Cast *passwd to an unsigned char, so that it doesn't extend the sign for
633
    *passwd > 127 and become 2**32-127+ after casting to uint.
634
  */
971.3.59 by Eric Day
Removed client_capabilities from session and pushed functionality into protocol plugin.
635
  uint32_t passwd_len= client_capabilities & CLIENT_SECURE_CONNECTION ?
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
636
    (unsigned char)(*passwd++) : strlen(passwd);
971.3.59 by Eric Day
Removed client_capabilities from session and pushed functionality into protocol plugin.
637
  l_db= client_capabilities & CLIENT_CONNECT_WITH_DB ? l_db + passwd_len + 1 : 0;
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
638
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
639
  /* strlen() can't be easily deleted without changing client */
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
640
  uint32_t db_len= l_db ? strlen(l_db) : 0;
641
971.3.8 by Eric Day
Moved NET to Protocol. libdrizzleclient is now completely isolated, need to start reworking Protocol now.
642
  if (passwd + passwd_len + db_len > (char *) net.read_pos + pkt_len)
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
643
  {
644
    my_error(ER_HANDSHAKE_ERROR, MYF(0), session->security_ctx.ip.c_str());
645
    return false;
646
  }
647
648
  /* If username starts and ends in "'", chop them off */
649
  if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'')
650
  {
651
    user[user_len-1]= 0;
652
    user++;
653
    user_len-= 2;
654
  }
655
656
  session->security_ctx.user.assign(user);
657
658
  return session->checkUser(passwd, passwd_len, l_db);
659
}
971.3.14 by Eric Day
Created Protocol plugin interface and changed libdrizzleclient to be a plugin.
660
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
661
bool ClientOldLibdrizzle::netStoreData(const unsigned char *from, size_t length)
662
{
663
  size_t packet_length= packet.length();
664
  /*
665
     The +9 comes from that strings of length longer than 16M require
666
     9 bytes to be stored (see drizzleclient_net_store_length).
667
  */
668
  if (packet_length+9+length > packet.alloced_length() &&
669
      packet.realloc(packet_length+9+length))
670
    return 1;
671
  unsigned char *to= drizzleclient_net_store_length((unsigned char*) packet.ptr()+packet_length, length);
672
  memcpy(to,from,length);
673
  packet.length((size_t) (to+length-(unsigned char*) packet.ptr()));
674
  return 0;
675
}
676
677
/**
678
  Format EOF packet according to the current client and
679
  write it to the network output buffer.
680
*/
681
682
void ClientOldLibdrizzle::writeEOFPacket(uint32_t server_status,
683
                                         uint32_t total_warn_count)
684
{
685
  unsigned char buff[5];
686
  /*
687
    Don't send warn count during SP execution, as the warn_list
688
    is cleared between substatements, and mysqltest gets confused
689
  */
690
  uint32_t tmp= min(total_warn_count, (uint32_t)65535);
691
  buff[0]= DRIZZLE_PROTOCOL_NO_MORE_DATA;
692
  int2store(buff+1, tmp);
693
  /*
694
    The following test should never be true, but it's better to do it
695
    because if 'is_fatal_error' is set the server is not going to execute
696
    other queries (see the if test in dispatch_command / COM_QUERY)
697
  */
698
  if (session->is_fatal_error)
699
    server_status&= ~SERVER_MORE_RESULTS_EXISTS;
700
  int2store(buff + 3, server_status);
701
  drizzleclient_net_write(&net, buff, 5);
702
}
703
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
704
static ListenOldLibdrizzle *listen_obj= NULL;
971.1.51 by Monty Taylor
New-style plugin registration now works.
705
1110.1.5 by Monty Taylor
Renamed PluginRegistry to plugin::Registry.
706
static int init(drizzled::plugin::Registry &registry)
971.3.14 by Eric Day
Created Protocol plugin interface and changed libdrizzleclient to be a plugin.
707
{
1130.2.3 by Monty Taylor
Made Listen into a Plugin.
708
  listen_obj= new ListenOldLibdrizzle("oldlibdrizzle");
1130.1.8 by Monty Taylor
Added polymorphic add/remove methods around slot add/remove methods.
709
  registry.add(listen_obj); 
971.3.16 by Eric Day
Cleaned up Protocol plugin interface (now a class factory) and moved libdrizzlclient to oldlibdrizzle to be clear.
710
  return 0;
711
}
712
1110.1.5 by Monty Taylor
Renamed PluginRegistry to plugin::Registry.
713
static int deinit(drizzled::plugin::Registry &registry)
971.3.16 by Eric Day
Cleaned up Protocol plugin interface (now a class factory) and moved libdrizzlclient to oldlibdrizzle to be clear.
714
{
1130.1.8 by Monty Taylor
Added polymorphic add/remove methods around slot add/remove methods.
715
  registry.remove(listen_obj);
1130.2.3 by Monty Taylor
Made Listen into a Plugin.
716
  delete listen_obj;
971.3.16 by Eric Day
Cleaned up Protocol plugin interface (now a class factory) and moved libdrizzlclient to oldlibdrizzle to be clear.
717
  return 0;
718
}
719
971.3.60 by Eric Day
Moved connect_timeout, net_*_timeout, and retry_count to plugin.
720
static DRIZZLE_SYSVAR_UINT(connect_timeout, connect_timeout,
721
                           PLUGIN_VAR_RQCMDARG, N_("Connect Timeout."),
722
                           NULL, NULL, 10, 1, 300, 0);
723
static DRIZZLE_SYSVAR_UINT(read_timeout, read_timeout, PLUGIN_VAR_RQCMDARG,
724
                           N_("Read Timeout."), NULL, NULL, 30, 1, 300, 0);
725
static DRIZZLE_SYSVAR_UINT(write_timeout, write_timeout, PLUGIN_VAR_RQCMDARG,
726
                           N_("Write Timeout."), NULL, NULL, 60, 1, 300, 0);
727
static DRIZZLE_SYSVAR_UINT(retry_count, retry_count, PLUGIN_VAR_RQCMDARG,
728
                           N_("Retry Count."), NULL, NULL, 10, 1, 100, 0);
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
729
static DRIZZLE_SYSVAR_UINT(buffer_length, buffer_length, PLUGIN_VAR_RQCMDARG,
730
                           N_("Buffer length."), NULL, NULL, 16384, 1024,
731
                           1024*1024, 0);
732
static DRIZZLE_SYSVAR_STR(bind_address, bind_address, PLUGIN_VAR_READONLY,
733
                          N_("Address to bind to."), NULL, NULL, NULL);
971.3.60 by Eric Day
Moved connect_timeout, net_*_timeout, and retry_count to plugin.
734
735
static struct st_mysql_sys_var* system_variables[]= {
736
  DRIZZLE_SYSVAR(connect_timeout),
737
  DRIZZLE_SYSVAR(read_timeout),
738
  DRIZZLE_SYSVAR(write_timeout),
739
  DRIZZLE_SYSVAR(retry_count),
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
740
  DRIZZLE_SYSVAR(buffer_length),
741
  DRIZZLE_SYSVAR(bind_address),
971.3.60 by Eric Day
Moved connect_timeout, net_*_timeout, and retry_count to plugin.
742
  NULL
743
};
744
971.3.16 by Eric Day
Cleaned up Protocol plugin interface (now a class factory) and moved libdrizzlclient to oldlibdrizzle to be clear.
745
drizzle_declare_plugin(oldlibdrizzle)
971.3.14 by Eric Day
Created Protocol plugin interface and changed libdrizzleclient to be a plugin.
746
{
971.3.16 by Eric Day
Cleaned up Protocol plugin interface (now a class factory) and moved libdrizzlclient to oldlibdrizzle to be clear.
747
  "oldlibdrizzle",
971.3.14 by Eric Day
Created Protocol plugin interface and changed libdrizzleclient to be a plugin.
748
  "0.1",
749
  "Eric Day",
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
750
  "Old libdrizzle Client",
971.3.14 by Eric Day
Created Protocol plugin interface and changed libdrizzleclient to be a plugin.
751
  PLUGIN_LICENSE_GPL,
971.3.60 by Eric Day
Moved connect_timeout, net_*_timeout, and retry_count to plugin.
752
  init,             /* Plugin Init */
753
  deinit,           /* Plugin Deinit */
754
  NULL,             /* status variables */
755
  system_variables, /* system variables */
756
  NULL              /* config options */
971.3.14 by Eric Day
Created Protocol plugin interface and changed libdrizzleclient to be a plugin.
757
}
758
drizzle_declare_plugin_end;