~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
1241.9.12 by Monty Taylor
Trims more out of server_includes.h.
20
#include "config.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>
1241.9.64 by Monty Taylor
Moved remaining non-public portions of mysys and mystrings to drizzled/internal.
26
#include "drizzled/internal/my_sys.h"
27
#include "drizzled/internal/m_string.h"
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
28
#include <algorithm>
1633.6.2 by Vijay Samuel
Reverted changes.
29
#include <iostream>
30
#include <boost/program_options.hpp>
31
#include <drizzled/module/option_map.h>
971.3.14 by Eric Day
Created Protocol plugin interface and changed libdrizzleclient to be a plugin.
32
#include "pack.h"
33
#include "errmsg.h"
1300.5.1 by Monty Taylor
Put drizzle_protocol plugin in to its own namespace so that symbols won't
34
#include "drizzle_protocol.h"
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
35
#include "options.h"
1067.4.8 by Nathan Williams
Converted all usages of cmin/cmax in plugin directory to std::min/max.
36
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
37
#define PROTOCOL_VERSION 10
38
39
namespace drizzled
40
{
41
extern uint32_t global_thread_id;
42
}
1633.6.2 by Vijay Samuel
Reverted changes.
43
namespace po= boost::program_options;
1320.2.1 by Monty Taylor
Merged in drizzle_protocol namespace change.
44
using namespace drizzled;
1067.4.8 by Nathan Williams
Converted all usages of cmin/cmax in plugin directory to std::min/max.
45
using namespace std;
1300.5.1 by Monty Taylor
Put drizzle_protocol plugin in to its own namespace so that symbols won't
46
47
namespace drizzle_protocol
48
{
49
1067.4.8 by Nathan Williams
Converted all usages of cmin/cmax in plugin directory to std::min/max.
50
1192.3.40 by Monty Taylor
Removed port setting from configure. The situation is a bit different now than that code was designed for.
51
static const uint32_t DRIZZLE_TCP_PORT= 4427;
1 by brian
clean slate
52
static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024;
971.7.8 by Eric Day
Moved port options into protocol plugin and added MySQL protocol support.
53
static uint32_t port;
971.3.60 by Eric Day
Moved connect_timeout, net_*_timeout, and retry_count to plugin.
54
static uint32_t connect_timeout;
55
static uint32_t read_timeout;
56
static uint32_t write_timeout;
57
static uint32_t retry_count;
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
58
static uint32_t buffer_length;
59
static char* bind_address;
60
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
61
const char* ListenDrizzleProtocol::getHost(void) const
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
62
{
63
  return bind_address;
64
}
971.3.48 by Eric Day
New Listen interface about done, not quite compiling yet, but need a backup.
65
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
66
in_port_t ListenDrizzleProtocol::getPort(void) const
971.3.48 by Eric Day
New Listen interface about done, not quite compiling yet, but need a backup.
67
{
971.7.8 by Eric Day
Moved port options into protocol plugin and added MySQL protocol support.
68
  char *env;
69
70
  if (port == 0)
71
  {
72
    port= DRIZZLE_TCP_PORT;
73
74
    if ((env = getenv("DRIZZLE_TCP_PORT")))
75
      port= (uint32_t) atoi(env);
76
77
    assert(port != 0);
78
  }
79
80
  return (in_port_t) port;
971.3.48 by Eric Day
New Listen interface about done, not quite compiling yet, but need a backup.
81
}
82
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
83
plugin::Client *ListenDrizzleProtocol::getClient(int fd)
971.3.48 by Eric Day
New Listen interface about done, not quite compiling yet, but need a backup.
84
{
971.6.7 by Eric Day
Reworked listen interface to not require binding of TCP ports.
85
  int new_fd;
86
  new_fd= acceptTcp(fd);
87
  if (new_fd == -1)
88
    return NULL;
89
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
90
  return new (nothrow) ClientDrizzleProtocol(new_fd, using_mysql41_protocol);
971.3.48 by Eric Day
New Listen interface about done, not quite compiling yet, but need a backup.
91
}
971.3.8 by Eric Day
Moved NET to Protocol. libdrizzleclient is now completely isolated, need to start reworking Protocol now.
92
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
93
ClientDrizzleProtocol::ClientDrizzleProtocol(int fd, bool using_mysql41_protocol_arg):
971.7.9 by Eric Day
Renamed mysql protocol variable from Jay's suggestion.
94
  using_mysql41_protocol(using_mysql41_protocol_arg)
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
95
{
96
  net.vio= 0;
97
98
  if (fd == -1)
99
    return;
100
101
  if (drizzleclient_net_init_sock(&net, fd, 0, buffer_length))
102
    throw bad_alloc();
103
104
  drizzleclient_net_set_read_timeout(&net, read_timeout);
105
  drizzleclient_net_set_write_timeout(&net, write_timeout);
106
  net.retry_count=retry_count;
107
}
108
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
109
ClientDrizzleProtocol::~ClientDrizzleProtocol()
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
110
{
111
  if (net.vio)
112
    drizzleclient_vio_close(net.vio);
113
}
114
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
115
int ClientDrizzleProtocol::getFileDescriptor(void)
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
116
{
117
  return drizzleclient_net_get_sd(&net);
118
}
1 by brian
clean slate
119
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
120
bool ClientDrizzleProtocol::isConnected()
971.3.5 by Eric Day
Moved more drizzleclient/NET specific code to Protocol class.
121
{
971.3.8 by Eric Day
Moved NET to Protocol. libdrizzleclient is now completely isolated, need to start reworking Protocol now.
122
  return net.vio != 0;
971.3.5 by Eric Day
Moved more drizzleclient/NET specific code to Protocol class.
123
}
124
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
125
bool ClientDrizzleProtocol::isReading(void)
971.3.8 by Eric Day
Moved NET to Protocol. libdrizzleclient is now completely isolated, need to start reworking Protocol now.
126
{
127
  return net.reading_or_writing == 1;
128
}
129
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
130
bool ClientDrizzleProtocol::isWriting(void)
971.3.8 by Eric Day
Moved NET to Protocol. libdrizzleclient is now completely isolated, need to start reworking Protocol now.
131
{
132
  return net.reading_or_writing == 2;
971.3.5 by Eric Day
Moved more drizzleclient/NET specific code to Protocol class.
133
}
134
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
135
bool ClientDrizzleProtocol::flush()
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
136
{
137
  if (net.vio == NULL)
138
    return false;
139
  bool ret= drizzleclient_net_write(&net, (unsigned char*) packet.ptr(),
140
                           packet.length());
141
  packet.length(0);
142
  return ret;
143
}
144
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
145
void ClientDrizzleProtocol::close(void)
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
146
{
147
  if (net.vio)
148
  { 
149
    drizzleclient_net_close(&net);
150
    drizzleclient_net_end(&net);
151
  }
152
}
153
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
154
bool ClientDrizzleProtocol::authenticate()
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
155
{
156
  bool connection_is_valid;
157
158
  /* Use "connect_timeout" value during connection phase */
159
  drizzleclient_net_set_read_timeout(&net, connect_timeout);
160
  drizzleclient_net_set_write_timeout(&net, connect_timeout);
161
162
  connection_is_valid= checkConnection();
163
164
  if (connection_is_valid)
165
    sendOK();
166
  else
167
  {
168
    sendError(session->main_da.sql_errno(), session->main_da.message());
169
    return false;
170
  }
171
172
  /* Connect completed, set read/write timeouts back to default */
173
  drizzleclient_net_set_read_timeout(&net, read_timeout);
174
  drizzleclient_net_set_write_timeout(&net, write_timeout);
175
  return true;
176
}
177
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
178
bool ClientDrizzleProtocol::readCommand(char **l_packet, uint32_t *packet_length)
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
179
{
180
  /*
181
    This thread will do a blocking read from the client which
182
    will be interrupted when the next command is received from
183
    the client, the connection is closed or "net_wait_timeout"
184
    number of seconds has passed
185
  */
186
#ifdef NEVER
187
  /* We can do this much more efficiently with poll timeouts or watcher thread,
188
     disabling for now, which means net_wait_timeout == read_timeout. */
189
  drizzleclient_net_set_read_timeout(&net,
190
                                     session->variables.net_wait_timeout);
191
#endif
192
193
  net.pkt_nr=0;
194
195
  *packet_length= drizzleclient_net_read(&net);
196
  if (*packet_length == packet_error)
197
  {
198
    /* Check if we can continue without closing the connection */
199
200
    if(net.last_errno== CR_NET_PACKET_TOO_LARGE)
201
      my_error(ER_NET_PACKET_TOO_LARGE, MYF(0));
202
    if (session->main_da.status() == Diagnostics_area::DA_ERROR)
203
      sendError(session->main_da.sql_errno(), session->main_da.message());
204
    else
205
      sendOK();
206
207
    if (net.error != 3)
208
      return false;                       // We have to close it.
209
210
    net.error= 0;
211
    *packet_length= 0;
212
    return true;
213
  }
214
215
  *l_packet= (char*) net.read_pos;
216
217
  /*
218
    'packet_length' contains length of data, as it was stored in packet
219
    header. In case of malformed header, drizzleclient_net_read returns zero.
220
    If packet_length is not zero, drizzleclient_net_read ensures that the returned
221
    number of bytes was actually read from network.
222
    There is also an extra safety measure in drizzleclient_net_read:
223
    it sets packet[packet_length]= 0, but only for non-zero packets.
224
  */
225
226
  if (*packet_length == 0)                       /* safety */
227
  {
228
    /* Initialize with COM_SLEEP packet */
229
    (*l_packet)[0]= (unsigned char) COM_SLEEP;
230
    *packet_length= 1;
231
  }
971.7.9 by Eric Day
Renamed mysql protocol variable from Jay's suggestion.
232
  else if (using_mysql41_protocol)
971.7.8 by Eric Day
Moved port options into protocol plugin and added MySQL protocol support.
233
  {
234
    /* Map from MySQL commands to Drizzle commands. */
235
    switch ((int)(*l_packet)[0])
236
    {
237
    case 0: /* SLEEP */
238
    case 1: /* QUIT */
239
    case 2: /* INIT_DB */
240
    case 3: /* QUERY */
241
      break;
242
243
    case 8: /* SHUTDOWN */
244
      (*l_packet)[0]= (unsigned char) COM_SHUTDOWN;
245
      break;
246
247
    case 14: /* PING */
248
      (*l_packet)[0]= (unsigned char) COM_SHUTDOWN;
249
      break;
250
251
252
    default:
253
      /* Just drop connection for MySQL commands we don't support. */
254
      (*l_packet)[0]= (unsigned char) COM_QUIT;
255
      *packet_length= 1;
256
      break;
257
    }
258
  }
259
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
260
  /* Do not rely on drizzleclient_net_read, extra safety against programming errors. */
261
  (*l_packet)[*packet_length]= '\0';                  /* safety */
262
263
#ifdef NEVER
264
  /* See comment above. */
265
  /* Restore read timeout value */
266
  drizzleclient_net_set_read_timeout(&net,
267
                                     session->variables.net_read_timeout);
268
#endif
269
270
  return true;
271
}
1 by brian
clean slate
272
273
/**
274
  Return ok to the client.
275
276
  The ok packet has the following structure:
277
278
  - 0               : Marker (1 byte)
971.3.17 by Eric Day
Cleaned up int/date related store functions.
279
  - affected_rows    : Stored in 1-9 bytes
280
  - id        : Stored in 1-9 bytes
281
  - server_status    : Copy of session->server_status;  Can be used by client
1 by brian
clean slate
282
  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.
283
  New in 4.0 client
284
  - warning_count    : Stored in 2 bytes; New in 4.1 client
971.3.17 by Eric Day
Cleaned up int/date related store functions.
285
  - message        : Stored as packed length (1-9 bytes) + message.
1 by brian
clean slate
286
  Is not stored if no message.
287
971.3.17 by Eric Day
Cleaned up int/date related store functions.
288
  @param session           Thread handler
289
  @param affected_rows       Number of rows changed by statement
290
  @param id           Auto_increment id for first row (if used)
291
  @param message       Message to send to the client (Used by mysql_status)
1 by brian
clean slate
292
*/
293
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
294
void ClientDrizzleProtocol::sendOK()
971.3.12 by Eric Day
Started abstracting Protocol, removed init_connect, init_file.
295
{
296
  unsigned char buff[DRIZZLE_ERRMSG_SIZE+10],*pos;
297
  const char *message= NULL;
298
  uint32_t tmp;
299
971.3.17 by Eric Day
Cleaned up int/date related store functions.
300
  if (!net.vio)    // hack for re-parsing queries
971.3.12 by Eric Day
Started abstracting Protocol, removed init_connect, init_file.
301
  {
302
    return;
303
  }
304
971.3.17 by Eric Day
Cleaned up int/date related store functions.
305
  buff[0]=0;                    // No fields
971.3.12 by Eric Day
Started abstracting Protocol, removed init_connect, init_file.
306
  if (session->main_da.status() == Diagnostics_area::DA_OK)
307
  {
971.3.59 by Eric Day
Removed client_capabilities from session and pushed functionality into protocol plugin.
308
    if (client_capabilities & CLIENT_FOUND_ROWS && session->main_da.found_rows())
309
      pos=drizzleclient_net_store_length(buff+1,session->main_da.found_rows());
310
    else
311
      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.
312
    pos=drizzleclient_net_store_length(pos, session->main_da.last_insert_id());
313
    int2store(pos, session->main_da.server_status());
314
    pos+=2;
1067.4.8 by Nathan Williams
Converted all usages of cmin/cmax in plugin directory to std::min/max.
315
    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.
316
    message= session->main_da.message();
317
  }
318
  else
319
  {
320
    pos=drizzleclient_net_store_length(buff+1,0);
321
    pos=drizzleclient_net_store_length(pos, 0);
322
    int2store(pos, session->server_status);
323
    pos+=2;
1067.4.8 by Nathan Williams
Converted all usages of cmin/cmax in plugin directory to std::min/max.
324
    tmp= min(session->total_warn_count, (uint32_t)65535);
971.3.12 by Eric Day
Started abstracting Protocol, removed init_connect, init_file.
325
  }
326
327
  /* We can only return up to 65535 warnings in two bytes */
328
  int2store(pos, tmp);
329
  pos+= 2;
330
331
  session->main_da.can_overwrite_status= true;
332
333
  if (message && message[0])
334
  {
335
    size_t length= strlen(message);
336
    pos=drizzleclient_net_store_length(pos,length);
337
    memcpy(pos,(unsigned char*) message,length);
338
    pos+=length;
339
  }
340
  drizzleclient_net_write(&net, buff, (size_t) (pos-buff));
341
  drizzleclient_net_flush(&net);
342
343
  session->main_da.can_overwrite_status= false;
344
}
1 by brian
clean slate
345
346
/**
347
  Send eof (= end of result set) to the client.
348
349
  The eof packet has the following structure:
350
971.3.17 by Eric Day
Cleaned up int/date related store functions.
351
  - 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.
352
  - warning_count    : Stored in 2 bytes; New in 4.1 client
971.3.17 by Eric Day
Cleaned up int/date related store functions.
353
  - status_flag    : Stored in 2 bytes;
1 by brian
clean slate
354
  For flags like SERVER_MORE_RESULTS_EXISTS.
355
356
  Note that the warning count will not be sent if 'no_flush' is set as
357
  we don't want to report the warning count until all data is sent to the
358
  client.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
359
*/
1 by brian
clean slate
360
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
361
void ClientDrizzleProtocol::sendEOF()
971.3.12 by Eric Day
Started abstracting Protocol, removed init_connect, init_file.
362
{
363
  /* Set to true if no active vio, to work well in case of --init-file */
364
  if (net.vio != 0)
365
  {
366
    session->main_da.can_overwrite_status= true;
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
367
    writeEOFPacket(session->main_da.server_status(),
368
                   session->main_da.total_warn_count());
971.3.12 by Eric Day
Started abstracting Protocol, removed init_connect, init_file.
369
    drizzleclient_net_flush(&net);
370
    session->main_da.can_overwrite_status= false;
371
  }
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
372
  packet.shrink(buffer_length);
373
}
374
1 by brian
clean slate
375
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
376
void ClientDrizzleProtocol::sendError(uint32_t sql_errno, const char *err)
1 by brian
clean slate
377
{
482 by Brian Aker
Remove uint.
378
  uint32_t length;
1 by brian
clean slate
379
  /*
261.4.1 by Felipe
- Renamed MYSQL_ERROR to DRIZZLE_ERROR.
380
    buff[]: sql_errno:2 + ('#':1 + SQLSTATE_LENGTH:5) + DRIZZLE_ERRMSG_SIZE:512
1 by brian
clean slate
381
  */
481 by Brian Aker
Remove all of uchar.
382
  unsigned char buff[2+1+SQLSTATE_LENGTH+DRIZZLE_ERRMSG_SIZE], *pos;
1 by brian
clean slate
383
971.3.17 by Eric Day
Cleaned up int/date related store functions.
384
  assert(sql_errno);
385
  assert(err && err[0]);
386
387
  /*
388
    It's one case when we can push an error even though there
389
    is an OK or EOF already.
390
  */
391
  session->main_da.can_overwrite_status= true;
392
393
  /* Abort multi-result sets */
394
  session->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
395
396
  /**
397
    Send a error string to client.
398
399
    For SIGNAL/RESIGNAL and GET DIAGNOSTICS functionality it's
400
    critical that every error that can be intercepted is issued in one
401
    place only, my_message_sql.
402
  */
403
971.3.8 by Eric Day
Moved NET to Protocol. libdrizzleclient is now completely isolated, need to start reworking Protocol now.
404
  if (net.vio == 0)
1 by brian
clean slate
405
  {
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
406
    return;
1 by brian
clean slate
407
  }
408
409
  int2store(buff,sql_errno);
410
  pos= buff+2;
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
411
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
412
  /* The first # is to make the client backward compatible */
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
413
  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.
414
  pos= (unsigned char*) strcpy((char*) buff+3, drizzle_errno_to_sqlstate(sql_errno));
415
  pos+= strlen(drizzle_errno_to_sqlstate(sql_errno));
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
416
629.5.3 by Toru Maesaka
Third pass of replacing MySQL's strmake() with libc calls
417
  char *tmp= strncpy((char*)pos, err, DRIZZLE_ERRMSG_SIZE-1);
418
  tmp+= strlen((char*)pos);
419
  tmp[0]= '\0';
420
  length= (uint32_t)(tmp-(char*)buff);
1 by brian
clean slate
421
  err= (char*) buff;
422
971.3.8 by Eric Day
Moved NET to Protocol. libdrizzleclient is now completely isolated, need to start reworking Protocol now.
423
  drizzleclient_net_write_command(&net,(unsigned char) 255, (unsigned char*) "", 0, (unsigned char*) err, length);
424
425
  session->main_da.can_overwrite_status= false;
1 by brian
clean slate
426
}
427
428
/**
429
  Send name and type of result to client.
430
431
  Sum fields has table name empty and field_name.
432
971.3.17 by Eric Day
Cleaned up int/date related store functions.
433
  @param Session        Thread data object
434
  @param list            List of items to send to client
435
  @param flag            Bit mask with the following functions:
1 by brian
clean slate
436
                        - 1 send number of rows
437
                        - 2 send default values
438
                        - 4 don't write eof packet
439
440
  @retval
971.3.17 by Eric Day
Cleaned up int/date related store functions.
441
    0    ok
1 by brian
clean slate
442
  @retval
971.3.17 by Eric Day
Cleaned up int/date related store functions.
443
    1    Error  (Note that in this case the error is not sent to the
1 by brian
clean slate
444
    client)
445
*/
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
446
bool ClientDrizzleProtocol::sendFields(List<Item> *list)
1 by brian
clean slate
447
{
448
  List_iterator_fast<Item> it(*list);
449
  Item *item;
481 by Brian Aker
Remove all of uchar.
450
  unsigned char buff[80];
1 by brian
clean slate
451
  String tmp((char*) buff,sizeof(buff),&my_charset_bin);
452
971.3.63 by Eric Day
Removed protocol field flags.
453
  unsigned char *row_pos= drizzleclient_net_store_length(buff, list->elements);
454
  (void) drizzleclient_net_write(&net, buff, (size_t) (row_pos-buff));
1 by brian
clean slate
455
456
  while ((item=it++))
457
  {
458
    char *pos;
1052.2.4 by Nathan Williams
No actual code changes. Changed Send_field to SendField to be consistent with coding standards.
459
    SendField field;
1 by brian
clean slate
460
    item->make_field(&field);
461
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
462
    packet.length(0);
971.6.2 by Eric Day
Fixed bug, accidently removed prepareForResend call.
463
1054.2.9 by Monty Taylor
Removed CHARSET_INFO stuff from protocol plugin interface - it makes no sense.
464
    if (store(STRING_WITH_LEN("def")) ||
465
        store(field.db_name) ||
466
        store(field.table_name) ||
467
        store(field.org_table_name) ||
468
        store(field.col_name) ||
469
        store(field.org_col_name) ||
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
470
        packet.realloc(packet.length()+12))
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
471
      goto err;
472
473
    /* Store fixed length fields */
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
474
    pos= (char*) packet.ptr()+packet.length();
971.3.17 by Eric Day
Cleaned up int/date related store functions.
475
    *pos++= 12;                // Length of packed fields
1054.2.9 by Monty Taylor
Removed CHARSET_INFO stuff from protocol plugin interface - it makes no sense.
476
    /* No conversion */
477
    int2store(pos, field.charsetnr);
478
    int4store(pos+2, field.length);
971.7.8 by Eric Day
Moved port options into protocol plugin and added MySQL protocol support.
479
971.7.9 by Eric Day
Renamed mysql protocol variable from Jay's suggestion.
480
    if (using_mysql41_protocol)
971.7.8 by Eric Day
Moved port options into protocol plugin and added MySQL protocol support.
481
    {
482
      /* Switch to MySQL field numbering. */
483
      switch (field.type)
484
      {
485
      case DRIZZLE_TYPE_LONG:
486
        pos[6]= 3;
487
        break;
488
489
      case DRIZZLE_TYPE_DOUBLE:
490
        pos[6]= 5;
491
        break;
492
493
      case DRIZZLE_TYPE_NULL:
494
        pos[6]= 6;
495
        break;
496
497
      case DRIZZLE_TYPE_TIMESTAMP:
498
        pos[6]= 7;
499
        break;
500
501
      case DRIZZLE_TYPE_LONGLONG:
502
        pos[6]= 8;
503
        break;
504
505
      case DRIZZLE_TYPE_DATETIME:
506
        pos[6]= 12;
507
        break;
508
509
      case DRIZZLE_TYPE_DATE:
510
        pos[6]= 14;
511
        break;
512
513
      case DRIZZLE_TYPE_VARCHAR:
514
        pos[6]= 15;
515
        break;
516
1218 by Brian Aker
Merge Eric
517
      case DRIZZLE_TYPE_DECIMAL:
971.7.8 by Eric Day
Moved port options into protocol plugin and added MySQL protocol support.
518
        pos[6]= (char)246;
519
        break;
520
521
      case DRIZZLE_TYPE_ENUM:
522
        pos[6]= (char)247;
523
        break;
524
525
      case DRIZZLE_TYPE_BLOB:
526
        pos[6]= (char)252;
527
        break;
528
      }
529
    }
530
    else
531
    {
532
      /* Add one to compensate for tinyint removal from enum. */
533
      pos[6]= field.type + 1;
534
    }
535
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
536
    int2store(pos+7,field.flags);
537
    pos[9]= (char) field.decimals;
971.3.17 by Eric Day
Cleaned up int/date related store functions.
538
    pos[10]= 0;                // For the future
539
    pos[11]= 0;                // For the future
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
540
    pos+= 12;
1 by brian
clean slate
541
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
542
    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.
543
    if (flush())
971.6.11 by Eric Day
Removed purecov messages.
544
      break;
1 by brian
clean slate
545
  }
546
971.3.63 by Eric Day
Removed protocol field flags.
547
  /*
548
    Mark the end of meta-data result set, and store session->server_status,
549
    to show that there is no cursor.
550
    Send no warning information, as it will be sent at statement end.
551
  */
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
552
  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.
553
  return 0;
1 by brian
clean slate
554
555
err:
556
  my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES),
971.6.11 by Eric Day
Removed purecov messages.
557
             MYF(0));
558
  return 1;
1 by brian
clean slate
559
}
560
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
561
bool ClientDrizzleProtocol::store(Field *from)
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
562
{
563
  if (from->is_null())
564
    return store();
565
  char buff[MAX_FIELD_WIDTH];
566
  String str(buff,sizeof(buff), &my_charset_bin);
567
568
  from->val_str(&str);
569
570
  return netStoreData((const unsigned char *)str.ptr(), str.length());
1 by brian
clean slate
571
}
572
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
573
bool ClientDrizzleProtocol::store(void)
1 by brian
clean slate
574
{
575
  char buff[1];
576
  buff[0]= (char)251;
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
577
  return packet.append(buff, sizeof(buff), PACKET_BUFFER_EXTRA_ALLOC);
578
}
1 by brian
clean slate
579
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
580
bool ClientDrizzleProtocol::store(int32_t from)
971.3.17 by Eric Day
Cleaned up int/date related store functions.
581
{
582
  char buff[12];
583
  return netStoreData((unsigned char*) buff,
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
584
                      (size_t) (internal::int10_to_str(from, buff, -10) - buff));
971.3.17 by Eric Day
Cleaned up int/date related store functions.
585
}
586
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
587
bool ClientDrizzleProtocol::store(uint32_t from)
971.3.17 by Eric Day
Cleaned up int/date related store functions.
588
{
589
  char buff[11];
590
  return netStoreData((unsigned char*) buff,
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
591
                      (size_t) (internal::int10_to_str(from, buff, 10) - buff));
971.3.17 by Eric Day
Cleaned up int/date related store functions.
592
}
593
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
594
bool ClientDrizzleProtocol::store(int64_t from)
1 by brian
clean slate
595
{
596
  char buff[22];
971.3.12 by Eric Day
Started abstracting Protocol, removed init_connect, init_file.
597
  return netStoreData((unsigned char*) buff,
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
598
                      (size_t) (internal::int64_t10_to_str(from, buff, -10) - buff));
971.3.17 by Eric Day
Cleaned up int/date related store functions.
599
}
600
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
601
bool ClientDrizzleProtocol::store(uint64_t from)
971.3.17 by Eric Day
Cleaned up int/date related store functions.
602
{
603
  char buff[21];
604
  return netStoreData((unsigned char*) buff,
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
605
                      (size_t) (internal::int64_t10_to_str(from, buff, 10) - buff));
1 by brian
clean slate
606
}
607
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
608
bool ClientDrizzleProtocol::store(double from, uint32_t decimals, String *buffer)
1 by brian
clean slate
609
{
520.1.22 by Brian Aker
Second pass of thd cleanup
610
  buffer->set_real(from, decimals, session->charset());
971.3.12 by Eric Day
Started abstracting Protocol, removed init_connect, init_file.
611
  return netStoreData((unsigned char*) buffer->ptr(), buffer->length());
1 by brian
clean slate
612
}
613
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
614
bool ClientDrizzleProtocol::store(const char *from, size_t length)
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
615
{
616
  return netStoreData((const unsigned char *)from, length);
617
}
618
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
619
bool ClientDrizzleProtocol::wasAborted(void)
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
620
{
621
  return net.error && net.vio != 0;
622
}
623
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
624
bool ClientDrizzleProtocol::haveMoreData(void)
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
625
{
626
  return drizzleclient_net_more_data(&net);
627
}
628
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
629
bool ClientDrizzleProtocol::haveError(void)
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
630
{
631
  return net.error || net.vio == 0;
1 by brian
clean slate
632
}
633
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
634
bool ClientDrizzleProtocol::checkConnection(void)
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
635
{
636
  uint32_t pkt_len= 0;
637
  char *end;
638
639
  // TCP/IP connection
640
  {
641
    char ip[NI_MAXHOST];
971.7.8 by Eric Day
Moved port options into protocol plugin and added MySQL protocol support.
642
    uint16_t peer_port;
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
643
971.7.8 by Eric Day
Moved port options into protocol plugin and added MySQL protocol support.
644
    if (drizzleclient_net_peer_addr(&net, ip, &peer_port, NI_MAXHOST))
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
645
    {
1273.11.5 by Dennis Schoen
add getSecurityContext()
646
      my_error(ER_BAD_HOST_ERROR, MYF(0), session->getSecurityContext().getIp().c_str());
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
647
      return false;
648
    }
649
1273.11.5 by Dennis Schoen
add getSecurityContext()
650
    session->getSecurityContext().setIp(ip);
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
651
  }
971.3.8 by Eric Day
Moved NET to Protocol. libdrizzleclient is now completely isolated, need to start reworking Protocol now.
652
  drizzleclient_net_keepalive(&net, true);
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
653
654
  uint32_t server_capabilites;
655
  {
656
    /* buff[] needs to big enough to hold the server_version variable */
657
    char buff[SERVER_VERSION_LENGTH + SCRAMBLE_LENGTH + 64];
658
659
    server_capabilites= CLIENT_BASIC_FLAGS;
660
971.7.9 by Eric Day
Renamed mysql protocol variable from Jay's suggestion.
661
    if (using_mysql41_protocol)
971.7.8 by Eric Day
Moved port options into protocol plugin and added MySQL protocol support.
662
      server_capabilites|= CLIENT_PROTOCOL_MYSQL41;
663
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
664
#ifdef HAVE_COMPRESS
665
    server_capabilites|= CLIENT_COMPRESS;
666
#endif /* HAVE_COMPRESS */
667
1502.4.1 by Monty Taylor
Don't overwrite the pandora_vc_revinfo file if we don't have new
668
    end= buff + strlen(PANDORA_RELEASE_VERSION);
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
669
    if ((end - buff) >= SERVER_VERSION_LENGTH)
670
      end= buff + (SERVER_VERSION_LENGTH - 1);
1502.4.1 by Monty Taylor
Don't overwrite the pandora_vc_revinfo file if we don't have new
671
    memcpy(buff, PANDORA_RELEASE_VERSION, end - buff);
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
672
    *end= 0;
673
    end++;
674
971.3.66 by Eric Day
Fixed thread_id bug from session refactoring work.
675
    int4store((unsigned char*) end, global_thread_id);
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
676
    end+= 4;
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
677
678
    /* We don't use scramble anymore. */
679
    memset(end, 'X', SCRAMBLE_LENGTH_323);
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
680
    end+= SCRAMBLE_LENGTH_323;
681
    *end++= 0; /* an empty byte for some reason */
682
683
    int2store(end, server_capabilites);
684
    /* write server characteristics: up to 16 bytes allowed */
685
    end[2]=(char) default_charset_info->number;
686
    int2store(end+3, session->server_status);
687
    memset(end+5, 0, 13);
688
    end+= 18;
689
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
690
    /* Write scramble tail. */
691
    memset(end, 'X', SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323);
692
    end+= (SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323);
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
693
    *end++= 0; /* an empty byte for some reason */
694
695
    /* 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.
696
    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.
697
          , (unsigned char) PROTOCOL_VERSION
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
698
          , (unsigned char*) ""
699
          , 0
700
          , (unsigned char*) buff
701
          , (size_t) (end-buff)) 
971.3.17 by Eric Day
Cleaned up int/date related store functions.
702
        ||    (pkt_len= drizzleclient_net_read(&net)) == packet_error 
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
703
        || pkt_len < MIN_HANDSHAKE_SIZE)
704
    {
1273.11.5 by Dennis Schoen
add getSecurityContext()
705
      my_error(ER_HANDSHAKE_ERROR, MYF(0), session->getSecurityContext().getIp().c_str());
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
706
      return false;
707
    }
708
  }
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
709
  if (packet.alloc(buffer_length))
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
710
    return false; /* The error is set by alloc(). */
711
971.3.59 by Eric Day
Removed client_capabilities from session and pushed functionality into protocol plugin.
712
  client_capabilities= uint2korr(net.read_pos);
713
714
715
  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.
716
  session->max_client_packet_length= uint4korr(net.read_pos + 4);
717
  end= (char*) net.read_pos + 32;
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
718
719
  /*
720
    Disable those bits which are not supported by the server.
721
    This is a precautionary measure, if the client lies. See Bug#27944.
722
  */
971.3.59 by Eric Day
Removed client_capabilities from session and pushed functionality into protocol plugin.
723
  client_capabilities&= server_capabilites;
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
724
971.3.8 by Eric Day
Moved NET to Protocol. libdrizzleclient is now completely isolated, need to start reworking Protocol now.
725
  if (end >= (char*) net.read_pos + pkt_len + 2)
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
726
  {
1273.11.5 by Dennis Schoen
add getSecurityContext()
727
    my_error(ER_HANDSHAKE_ERROR, MYF(0), session->getSecurityContext().getIp().c_str());
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
728
    return false;
729
  }
730
971.3.8 by Eric Day
Moved NET to Protocol. libdrizzleclient is now completely isolated, need to start reworking Protocol now.
731
  net.return_status= &session->server_status;
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
732
733
  char *user= end;
734
  char *passwd= strchr(user, '\0')+1;
735
  uint32_t user_len= passwd - user - 1;
736
  char *l_db= passwd;
737
738
  /*
739
    Old clients send null-terminated string as password; new clients send
740
    the size (1 byte) + string (not null-terminated). Hence in case of empty
741
    password both send '\0'.
742
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
743
    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.
744
745
    Cast *passwd to an unsigned char, so that it doesn't extend the sign for
746
    *passwd > 127 and become 2**32-127+ after casting to uint.
747
  */
971.3.59 by Eric Day
Removed client_capabilities from session and pushed functionality into protocol plugin.
748
  uint32_t passwd_len= client_capabilities & CLIENT_SECURE_CONNECTION ?
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
749
    (unsigned char)(*passwd++) : strlen(passwd);
971.3.59 by Eric Day
Removed client_capabilities from session and pushed functionality into protocol plugin.
750
  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.
751
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
752
  /* strlen() can't be easily deleted without changing client */
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
753
  uint32_t db_len= l_db ? strlen(l_db) : 0;
754
971.3.8 by Eric Day
Moved NET to Protocol. libdrizzleclient is now completely isolated, need to start reworking Protocol now.
755
  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.
756
  {
1273.11.5 by Dennis Schoen
add getSecurityContext()
757
    my_error(ER_HANDSHAKE_ERROR, MYF(0), session->getSecurityContext().getIp().c_str());
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
758
    return false;
759
  }
760
761
  /* If username starts and ends in "'", chop them off */
762
  if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'')
763
  {
764
    user[user_len-1]= 0;
765
    user++;
766
    user_len-= 2;
767
  }
768
1273.11.5 by Dennis Schoen
add getSecurityContext()
769
  session->getSecurityContext().setUser(user);
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
770
771
  return session->checkUser(passwd, passwd_len, l_db);
772
}
971.3.14 by Eric Day
Created Protocol plugin interface and changed libdrizzleclient to be a plugin.
773
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
774
bool ClientDrizzleProtocol::netStoreData(const unsigned char *from, size_t length)
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
775
{
776
  size_t packet_length= packet.length();
777
  /*
778
     The +9 comes from that strings of length longer than 16M require
779
     9 bytes to be stored (see drizzleclient_net_store_length).
780
  */
781
  if (packet_length+9+length > packet.alloced_length() &&
782
      packet.realloc(packet_length+9+length))
783
    return 1;
784
  unsigned char *to= drizzleclient_net_store_length((unsigned char*) packet.ptr()+packet_length, length);
785
  memcpy(to,from,length);
786
  packet.length((size_t) (to+length-(unsigned char*) packet.ptr()));
787
  return 0;
788
}
789
790
/**
791
  Format EOF packet according to the current client and
792
  write it to the network output buffer.
793
*/
794
971.7.10 by Eric Day
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.
795
void ClientDrizzleProtocol::writeEOFPacket(uint32_t server_status,
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
796
                                         uint32_t total_warn_count)
797
{
798
  unsigned char buff[5];
799
  /*
800
    Don't send warn count during SP execution, as the warn_list
801
    is cleared between substatements, and mysqltest gets confused
802
  */
803
  uint32_t tmp= min(total_warn_count, (uint32_t)65535);
804
  buff[0]= DRIZZLE_PROTOCOL_NO_MORE_DATA;
805
  int2store(buff+1, tmp);
806
  /*
807
    The following test should never be true, but it's better to do it
808
    because if 'is_fatal_error' is set the server is not going to execute
809
    other queries (see the if test in dispatch_command / COM_QUERY)
810
  */
811
  if (session->is_fatal_error)
812
    server_status&= ~SERVER_MORE_RESULTS_EXISTS;
813
  int2store(buff + 3, server_status);
814
  drizzleclient_net_write(&net, buff, 5);
815
}
816
1530.2.6 by Monty Taylor
Moved plugin::Context to module::Context.
817
static int init(module::Context &context)
971.3.14 by Eric Day
Created Protocol plugin interface and changed libdrizzleclient to be a plugin.
818
{
1633.6.2 by Vijay Samuel
Reverted changes.
819
  const module::option_map &vm= context.getOptions();
820
  if (vm.count("port"))
821
  { 
822
    if (port > 65535)
823
    {
1633.6.5 by Vijay Samuel
Merge changes for error printing.
824
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value of port\n"));
1633.6.2 by Vijay Samuel
Reverted changes.
825
      exit(-1);
826
    }
827
  }
828
829
  if (vm.count("connect-timeout"))
830
  {
831
    if (connect_timeout < 1 || connect_timeout > 300)
832
    {
1633.6.5 by Vijay Samuel
Merge changes for error printing.
833
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for connect_timeout\n"));
1633.6.2 by Vijay Samuel
Reverted changes.
834
      exit(-1);
835
    }
836
  }
837
838
  if (vm.count("read-timeout"))
839
  {
840
    if (read_timeout < 1 || read_timeout > 300)
841
    {
1633.6.5 by Vijay Samuel
Merge changes for error printing.
842
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for read_timeout\n"));
1633.6.2 by Vijay Samuel
Reverted changes.
843
      exit(-1);
844
    }
845
  }
846
847
  if (vm.count("write-timeout"))
848
  {
849
    if (write_timeout < 1 || write_timeout > 300)
850
    {
1633.6.5 by Vijay Samuel
Merge changes for error printing.
851
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for write_timeout\n"));
1633.6.2 by Vijay Samuel
Reverted changes.
852
      exit(-1);
853
    }
854
  }
855
856
  if (vm.count("retry-count"))
857
  {
858
    if (retry_count < 1 || retry_count > 100)
859
    {
1633.6.5 by Vijay Samuel
Merge changes for error printing.
860
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for retry_count\n"));
1633.6.2 by Vijay Samuel
Reverted changes.
861
      exit(-1);
862
    }
863
  }
864
865
  if (vm.count("buffer-length"))
866
  {
867
    if (buffer_length < 1024 || buffer_length > 1024*1024)
868
    {
1633.6.5 by Vijay Samuel
Merge changes for error printing.
869
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for buffer_length\n"));
1633.6.2 by Vijay Samuel
Reverted changes.
870
      exit(-1);
871
    }
872
  }
873
874
  if (vm.count("bind-address"))
875
  {
876
    bind_address= strdup(vm["bind-address"].as<string>().c_str());
877
  }
878
879
  else
880
  {
881
    bind_address= NULL;
882
  }
883
  
884
  context.add(new ListenDrizzleProtocol("drizzle_protocol", false)); 
971.3.16 by Eric Day
Cleaned up Protocol plugin interface (now a class factory) and moved libdrizzlclient to oldlibdrizzle to be clear.
885
  return 0;
886
}
887
971.7.8 by Eric Day
Moved port options into protocol plugin and added MySQL protocol support.
888
static DRIZZLE_SYSVAR_UINT(port, port, PLUGIN_VAR_RQCMDARG,
1192.3.40 by Monty Taylor
Removed port setting from configure. The situation is a bit different now than that code was designed for.
889
                           N_("Port number to use for connection or 0 for "
890
                              "default to, in order of "
891
                              "preference, drizzle.cnf, $DRIZZLE_TCP_PORT, "
892
                              "built-in default (4427)."),
971.7.8 by Eric Day
Moved port options into protocol plugin and added MySQL protocol support.
893
                           NULL, NULL, 0, 0, 65535, 0);
971.3.60 by Eric Day
Moved connect_timeout, net_*_timeout, and retry_count to plugin.
894
static DRIZZLE_SYSVAR_UINT(connect_timeout, connect_timeout,
895
                           PLUGIN_VAR_RQCMDARG, N_("Connect Timeout."),
896
                           NULL, NULL, 10, 1, 300, 0);
897
static DRIZZLE_SYSVAR_UINT(read_timeout, read_timeout, PLUGIN_VAR_RQCMDARG,
898
                           N_("Read Timeout."), NULL, NULL, 30, 1, 300, 0);
899
static DRIZZLE_SYSVAR_UINT(write_timeout, write_timeout, PLUGIN_VAR_RQCMDARG,
900
                           N_("Write Timeout."), NULL, NULL, 60, 1, 300, 0);
901
static DRIZZLE_SYSVAR_UINT(retry_count, retry_count, PLUGIN_VAR_RQCMDARG,
902
                           N_("Retry Count."), NULL, NULL, 10, 1, 100, 0);
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
903
static DRIZZLE_SYSVAR_UINT(buffer_length, buffer_length, PLUGIN_VAR_RQCMDARG,
904
                           N_("Buffer length."), NULL, NULL, 16384, 1024,
905
                           1024*1024, 0);
906
static DRIZZLE_SYSVAR_STR(bind_address, bind_address, PLUGIN_VAR_READONLY,
907
                          N_("Address to bind to."), NULL, NULL, NULL);
971.3.60 by Eric Day
Moved connect_timeout, net_*_timeout, and retry_count to plugin.
908
1633.6.2 by Vijay Samuel
Reverted changes.
909
static void init_options(drizzled::module::option_context &context)
910
{
911
  context("port",
912
          po::value<uint32_t>(&port)->default_value(0),
913
          N_("Port number to use for connection or 0 for "
914
                              "default to, in order of "
915
                              "preference, drizzle.cnf, $DRIZZLE_TCP_PORT, "
916
                              "built-in default (4427)."));
917
  context("connect-timeout",
918
          po::value<uint32_t>(&connect_timeout)->default_value(10),
919
          N_("Connect Timeout."));
920
  context("read-timeout",
921
          po::value<uint32_t>(&read_timeout)->default_value(30),
922
          N_("Read Timeout."));
923
  context("write-timeout",
924
          po::value<uint32_t>(&write_timeout)->default_value(60),
925
          N_("Write Timeout."));
926
  context("retry-count",
927
          po::value<uint32_t>(&retry_count)->default_value(10),
928
          N_("Retry Count."));
929
  context("buffer-length",
930
          po::value<uint32_t>(&buffer_length)->default_value(16384),
931
          N_("Buffer length."));
932
  context("bind-address",
933
          po::value<string>(),
934
          N_("Address to bind to."));
935
}
936
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
937
static drizzle_sys_var* sys_variables[]= {
971.7.8 by Eric Day
Moved port options into protocol plugin and added MySQL protocol support.
938
  DRIZZLE_SYSVAR(port),
971.3.60 by Eric Day
Moved connect_timeout, net_*_timeout, and retry_count to plugin.
939
  DRIZZLE_SYSVAR(connect_timeout),
940
  DRIZZLE_SYSVAR(read_timeout),
941
  DRIZZLE_SYSVAR(write_timeout),
942
  DRIZZLE_SYSVAR(retry_count),
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
943
  DRIZZLE_SYSVAR(buffer_length),
944
  DRIZZLE_SYSVAR(bind_address),
971.3.60 by Eric Day
Moved connect_timeout, net_*_timeout, and retry_count to plugin.
945
  NULL
946
};
947
1320.2.1 by Monty Taylor
Merged in drizzle_protocol namespace change.
948
} /* namespace drizzle_protocol */
1300.5.1 by Monty Taylor
Put drizzle_protocol plugin in to its own namespace so that symbols won't
949
1633.6.2 by Vijay Samuel
Reverted changes.
950
DRIZZLE_PLUGIN(drizzle_protocol::init, drizzle_protocol::sys_variables, drizzle_protocol::init_options);