~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzle/client.c

  • Committer: Brian Aker
  • Date: 2008-07-27 21:07:26 UTC
  • Revision ID: brian@tangent.org-20080727210726-zxwx10dy0w55qswh
Rename of fields (fix issue with string and decimal .h clashing).

Show diffs side-by-side

added added

removed removed

Lines of Context:
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, Inc.
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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 
 */
 
1
/* Copyright (C) 2008 Drizzle Open Source Project
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
19
15
 
20
16
/*
21
17
  This file is included by both libdrizzle.c (the DRIZZLE client C API)
28
24
    drizzle_connect()
29
25
  - Support for reading local file with LOAD DATA LOCAL
30
26
  - SHARED memory handling
 
27
  - Protection against sigpipe
31
28
  - Prepared statements
32
 
 
 
29
 
33
30
  - Things that only works for the server
34
31
  - Alarm handling on connect
35
 
 
 
32
 
36
33
  In all other cases, the code should be idential for the client and
37
34
  server.
38
35
*/
39
36
 
40
 
#include <stdarg.h>
41
 
 
42
 
#include <libdrizzle/libdrizzle.h>
43
 
#include <libdrizzle/net_serv.h>
44
 
#include "libdrizzle_priv.h"
45
 
#include <libdrizzle/pack.h>
46
 
 
47
 
#include <sys/poll.h>
48
 
#include <sys/ioctl.h>
 
37
#include <my_global.h>
 
38
 
 
39
#include "drizzle.h"
49
40
 
50
41
#include <netdb.h>
51
42
 
53
44
#undef max_allowed_packet
54
45
#undef net_buffer_length
55
46
 
56
 
#include <libdrizzle/errmsg.h>
 
47
#define CLI_DRIZZLE_CONNECT STDCALL drizzle_connect
 
48
 
 
49
#include <my_sys.h>
 
50
#include <mysys_err.h>
 
51
#include <m_string.h>
 
52
#include <m_ctype.h>
 
53
#include "drizzle_version.h"
 
54
#include "mysqld_error.h"
 
55
#include "errmsg.h"
 
56
#include <violite.h>
 
57
#include <my_pthread.h>        /* because of signal()  */
57
58
 
58
59
#include <sys/stat.h>
59
60
#include <signal.h>
76
77
#include <sys/un.h>
77
78
 
78
79
#include <errno.h>
79
 
 
80
 
 
81
 
#include <drizzled/gettext.h>
82
 
#include "local_infile.h"
83
 
 
84
 
 
85
 
 
86
 
 
87
 
 
88
 
 
89
 
 
90
 
 
91
 
#if defined(HAVE_GETPWUID) && defined(NO_GETPWUID_DECL)
92
 
struct passwd *getpwuid(uid_t);
93
 
char* getlogin(void);
94
 
#endif
95
 
 
96
 
 
 
80
#define SOCKET_ERROR -1
 
81
 
 
82
#define CONNECT_TIMEOUT 0
 
83
 
 
84
#include "client_settings.h"
 
85
#include <sql_common.h>
 
86
 
 
87
uint    drizzle_port=0;
 
88
char    *drizzle_unix_port= 0;
 
89
const char  *unknown_sqlstate= "HY000";
 
90
const char  *not_error_sqlstate= "00000";
 
91
const char  *cant_connect_sqlstate= "08001";
 
92
 
 
93
static bool drizzle_client_init= false;
 
94
static bool org_my_init_done= false;
 
95
 
 
96
static void drizzle_close_free_options(DRIZZLE *drizzle);
 
97
static void drizzle_close_free(DRIZZLE *drizzle);
 
98
 
 
99
static int wait_for_data(my_socket fd, uint timeout);
 
100
 
 
101
CHARSET_INFO *default_client_charset_info = &my_charset_latin1;
 
102
 
 
103
/* Server error code and message */
 
104
unsigned int drizzle_server_last_errno;
 
105
char drizzle_server_last_error[MYSQL_ERRMSG_SIZE];
 
106
 
 
107
/****************************************************************************
 
108
  A modified version of connect().  my_connect() allows you to specify
 
109
  a timeout value, in seconds, that we should wait until we
 
110
  derermine we can't connect to a particular host.  If timeout is 0,
 
111
  my_connect() will behave exactly like connect().
 
112
 
 
113
  Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
 
114
*****************************************************************************/
 
115
 
 
116
int my_connect(my_socket fd, const struct sockaddr *name, uint namelen,
 
117
         uint timeout)
 
118
{
 
119
  int flags, res, s_err;
 
120
 
 
121
  /*
 
122
    If they passed us a timeout of zero, we should behave
 
123
    exactly like the normal connect() call does.
 
124
  */
 
125
 
 
126
  if (timeout == 0)
 
127
    return connect(fd, (struct sockaddr*) name, namelen);
 
128
 
 
129
  flags = fcntl(fd, F_GETFL, 0);    /* Set socket to not block */
 
130
#ifdef O_NONBLOCK
 
131
  fcntl(fd, F_SETFL, flags | O_NONBLOCK);  /* and save the flags..  */
 
132
#endif
 
133
 
 
134
  res= connect(fd, (struct sockaddr*) name, namelen);
 
135
  s_err= errno;      /* Save the error... */
 
136
  fcntl(fd, F_SETFL, flags);
 
137
  if ((res != 0) && (s_err != EINPROGRESS))
 
138
  {
 
139
    errno= s_err;      /* Restore it */
 
140
    return(-1);
 
141
  }
 
142
  if (res == 0)        /* Connected quickly! */
 
143
    return(0);
 
144
  return wait_for_data(fd, timeout);
 
145
}
 
146
 
 
147
 
 
148
/*
 
149
  Wait up to timeout seconds for a connection to be established.
 
150
 
 
151
  We prefer to do this with poll() as there is no limitations with this.
 
152
  If not, we will use select()
 
153
*/
 
154
 
 
155
static int wait_for_data(my_socket fd, uint timeout)
 
156
{
 
157
#ifdef HAVE_POLL
 
158
  struct pollfd ufds;
 
159
  int res;
 
160
 
 
161
  ufds.fd= fd;
 
162
  ufds.events= POLLIN | POLLPRI;
 
163
  if (!(res= poll(&ufds, 1, (int) timeout*1000)))
 
164
  {
 
165
    errno= EINTR;
 
166
    return -1;
 
167
  }
 
168
  if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI)))
 
169
    return -1;
 
170
  return 0;
 
171
#else
 
172
  SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint);
 
173
  fd_set sfds;
 
174
  struct timeval tv;
 
175
  time_t start_time, now_time;
 
176
  int res, s_err;
 
177
 
 
178
  if (fd >= FD_SETSIZE)        /* Check if wrong error */
 
179
    return 0;          /* Can't use timeout */
 
180
 
 
181
  /*
 
182
    Our connection is "in progress."  We can use the select() call to wait
 
183
    up to a specified period of time for the connection to suceed.
 
184
    If select() returns 0 (after waiting howevermany seconds), our socket
 
185
    never became writable (host is probably unreachable.)  Otherwise, if
 
186
    select() returns 1, then one of two conditions exist:
 
187
  
 
188
    1. An error occured.  We use getsockopt() to check for this.
 
189
    2. The connection was set up sucessfully: getsockopt() will
 
190
    return 0 as an error.
 
191
  
 
192
    Thanks goes to Andrew Gierth <andrew@erlenstar.demon.co.uk>
 
193
    who posted this method of timing out a connect() in
 
194
    comp.unix.programmer on August 15th, 1997.
 
195
  */
 
196
 
 
197
  FD_ZERO(&sfds);
 
198
  FD_SET(fd, &sfds);
 
199
  /*
 
200
    select could be interrupted by a signal, and if it is,
 
201
    the timeout should be adjusted and the select restarted
 
202
    to work around OSes that don't restart select and
 
203
    implementations of select that don't adjust tv upon
 
204
    failure to reflect the time remaining
 
205
   */
 
206
  start_time= my_time(0);
 
207
  for (;;)
 
208
  {
 
209
    tv.tv_sec = (long) timeout;
 
210
    tv.tv_usec = 0;
 
211
#if defined(HPUX10)
 
212
    if ((res = select(fd+1, NULL, (int*) &sfds, NULL, &tv)) > 0)
 
213
      break;
 
214
#else
 
215
    if ((res = select(fd+1, NULL, &sfds, NULL, &tv)) > 0)
 
216
      break;
 
217
#endif
 
218
    if (res == 0)          /* timeout */
 
219
      return -1;
 
220
    now_time= my_time(0);
 
221
    timeout-= (uint) (now_time - start_time);
 
222
    if (errno != EINTR || (int) timeout <= 0)
 
223
      return -1;
 
224
  }
 
225
 
 
226
  /*
 
227
    select() returned something more interesting than zero, let's
 
228
    see if we have any errors.  If the next two statements pass,
 
229
    we've got an open socket!
 
230
  */
 
231
 
 
232
  s_err=0;
 
233
  if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)
 
234
    return(-1);
 
235
 
 
236
  if (s_err)
 
237
  {            /* getsockopt could succeed */
 
238
    errno = s_err;
 
239
    return(-1);          /* but return an error... */
 
240
  }
 
241
  return (0);          /* ok */
 
242
#endif /* HAVE_POLL */
 
243
}
 
244
 
 
245
/**
 
246
  Set the internal error message to DRIZZLE handler
 
247
 
 
248
  @param drizzle connection handle (client side)
 
249
  @param errcode  CR_ error code, passed to ER macro to get
 
250
                  error text
 
251
  @parma sqlstate SQL standard sqlstate
 
252
*/
 
253
 
 
254
void set_drizzle_error(DRIZZLE *drizzle, int errcode, const char *sqlstate)
 
255
{
 
256
  NET *net;
 
257
  assert(drizzle != 0);
 
258
 
 
259
  if (drizzle)
 
260
  {
 
261
    net= &drizzle->net;
 
262
    net->last_errno= errcode;
 
263
    strmov(net->last_error, ER(errcode));
 
264
    strmov(net->sqlstate, sqlstate);
 
265
  }
 
266
  else
 
267
  {
 
268
    drizzle_server_last_errno= errcode;
 
269
    strmov(drizzle_server_last_error, ER(errcode));
 
270
  }
 
271
  return;
 
272
}
 
273
 
 
274
/**
 
275
  Clear possible error state of struct NET
 
276
 
 
277
  @param net  clear the state of the argument
 
278
*/
 
279
 
 
280
void net_clear_error(NET *net)
 
281
{
 
282
  net->last_errno= 0;
 
283
  net->last_error[0]= '\0';
 
284
  strmov(net->sqlstate, not_error_sqlstate);
 
285
}
 
286
 
 
287
/**
 
288
  Set an error message on the client.
 
289
 
 
290
  @param drizzle connection handle
 
291
  @param errcode   CR_* errcode, for client errors
 
292
  @param sqlstate  SQL standard sql state, unknown_sqlstate for the
 
293
                   majority of client errors.
 
294
  @param format    error message template, in sprintf format
 
295
  @param ...       variable number of arguments
 
296
*/
 
297
 
 
298
static void set_drizzle_extended_error(DRIZZLE *drizzle, int errcode,
 
299
                                     const char *sqlstate,
 
300
                                     const char *format, ...)
 
301
{
 
302
  NET *net;
 
303
  va_list args;
 
304
  assert(drizzle != 0);
 
305
 
 
306
  net= &drizzle->net;
 
307
  net->last_errno= errcode;
 
308
  va_start(args, format);
 
309
  vsnprintf(net->last_error, sizeof(net->last_error)-1,
 
310
               format, args);
 
311
  va_end(args);
 
312
  strmov(net->sqlstate, sqlstate);
 
313
 
 
314
  return;
 
315
}
97
316
 
98
317
/*****************************************************************************
99
318
  Read a packet from server. Give error message if socket was down
103
322
uint32_t cli_safe_read(DRIZZLE *drizzle)
104
323
{
105
324
  NET *net= &drizzle->net;
106
 
  uint32_t len=0;
 
325
  ulong len=0;
 
326
  init_sigpipe_variables
107
327
 
 
328
  /* Don't give sigpipe errors if the client doesn't want them */
 
329
  set_sigpipe(drizzle);
108
330
  if (net->vio != 0)
109
331
    len=my_net_read(net);
 
332
  reset_sigpipe(drizzle);
110
333
 
111
334
  if (len == packet_error || len == 0)
112
335
  {
113
 
#ifdef DRIZZLE_SERVER
 
336
#ifdef MYSQL_SERVER
114
337
    if (net->vio && vio_was_interrupted(net->vio))
115
338
      return (packet_error);
116
339
#endif /*DRIZZLE_SERVER*/
117
 
    drizzle_disconnect(drizzle);
118
 
    drizzle_set_error(drizzle, net->last_errno == CR_NET_PACKET_TOO_LARGE ?
119
 
                      CR_NET_PACKET_TOO_LARGE : CR_SERVER_LOST,
120
 
                      sqlstate_get_unknown());
 
340
    end_server(drizzle);
 
341
    set_drizzle_error(drizzle, net->last_errno == ER_NET_PACKET_TOO_LARGE ?
 
342
                    CR_NET_PACKET_TOO_LARGE: CR_SERVER_LOST, unknown_sqlstate);
121
343
    return (packet_error);
122
344
  }
123
345
  if (net->read_pos[0] == 255)
128
350
      net->last_errno=uint2korr(pos);
129
351
      pos+=2;
130
352
      len-=2;
131
 
      if (pos[0] == '#')
 
353
      if (protocol_41(drizzle) && pos[0] == '#')
132
354
      {
133
 
        strncpy(net->sqlstate, pos+1, LIBDRIZZLE_SQLSTATE_LENGTH);
134
 
        pos+= LIBDRIZZLE_SQLSTATE_LENGTH+1;
 
355
  strmake(net->sqlstate, pos+1, SQLSTATE_LENGTH);
 
356
  pos+= SQLSTATE_LENGTH+1;
135
357
      }
136
358
      else
137
359
      {
140
362
          (unknown error sql state).
141
363
        */
142
364
 
143
 
        strcpy(net->sqlstate, sqlstate_get_unknown());
 
365
        strmov(net->sqlstate, unknown_sqlstate);
144
366
      }
145
367
 
146
 
      strncpy(net->last_error,(char*) pos, min((uint32_t) len,
147
 
              (uint32_t) sizeof(net->last_error)-1));
 
368
      (void) strmake(net->last_error,(char*) pos,
 
369
         min((uint) len,(uint) sizeof(net->last_error)-1));
148
370
    }
149
371
    else
150
 
      drizzle_set_error(drizzle, CR_UNKNOWN_ERROR, sqlstate_get_unknown());
 
372
      set_drizzle_error(drizzle, CR_UNKNOWN_ERROR, unknown_sqlstate);
151
373
    /*
152
374
      Cover a protocol design error: error packet does not
153
375
      contain the server status. Therefore, the client has no way
164
386
  return len;
165
387
}
166
388
 
 
389
void free_rows(DRIZZLE_DATA *cur)
 
390
{
 
391
  if (cur)
 
392
  {
 
393
    free_root(&cur->alloc,MYF(0));
 
394
    my_free((uchar*) cur,MYF(0));
 
395
  }
 
396
}
 
397
 
167
398
bool
168
399
cli_advanced_command(DRIZZLE *drizzle, enum enum_server_command command,
169
400
         const unsigned char *header, uint32_t header_length,
170
401
         const unsigned char *arg, uint32_t arg_length, bool skip_check)
171
402
{
172
403
  NET *net= &drizzle->net;
173
 
  bool result= 1;
174
 
  bool stmt_skip= false;
 
404
  my_bool result= 1;
 
405
  init_sigpipe_variables
 
406
  my_bool stmt_skip= false;
 
407
 
 
408
  /* Don't give sigpipe errors if the client doesn't want them */
 
409
  set_sigpipe(drizzle);
175
410
 
176
411
  if (drizzle->net.vio == 0)
177
412
  {            /* Do reconnect if possible */
181
416
  if (drizzle->status != DRIZZLE_STATUS_READY ||
182
417
      drizzle->server_status & SERVER_MORE_RESULTS_EXISTS)
183
418
  {
184
 
    drizzle_set_error(drizzle, CR_COMMANDS_OUT_OF_SYNC,
185
 
                      sqlstate_get_unknown());
 
419
    set_drizzle_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
186
420
    return(1);
187
421
  }
188
422
 
196
430
  */
197
431
  net_clear(&drizzle->net, (command != COM_QUIT));
198
432
 
199
 
  if (net_write_command(net,(unsigned char) command, header, header_length,
 
433
  if (net_write_command(net,(uchar) command, header, header_length,
200
434
      arg, arg_length))
201
435
  {
202
 
    if (net->last_errno == CR_NET_PACKET_TOO_LARGE)
 
436
    if (net->last_errno == ER_NET_PACKET_TOO_LARGE)
203
437
    {
204
 
      drizzle_set_error(drizzle, CR_NET_PACKET_TOO_LARGE, sqlstate_get_unknown());
 
438
      set_drizzle_error(drizzle, CR_NET_PACKET_TOO_LARGE, unknown_sqlstate);
205
439
      goto end;
206
440
    }
207
 
    drizzle_disconnect(drizzle);
 
441
    end_server(drizzle);
208
442
    if (drizzle_reconnect(drizzle) || stmt_skip)
209
443
      goto end;
210
 
    if (net_write_command(net,(unsigned char) command, header, header_length,
 
444
    if (net_write_command(net,(uchar) command, header, header_length,
211
445
        arg, arg_length))
212
446
    {
213
 
      drizzle_set_error(drizzle, CR_SERVER_GONE_ERROR, sqlstate_get_unknown());
 
447
      set_drizzle_error(drizzle, CR_SERVER_GONE_ERROR, unknown_sqlstate);
214
448
      goto end;
215
449
    }
216
450
  }
219
453
    result= ((drizzle->packet_length=cli_safe_read(drizzle)) == packet_error ?
220
454
       1 : 0);
221
455
end:
 
456
  reset_sigpipe(drizzle);
222
457
  return(result);
223
458
}
224
459
 
225
460
void free_old_query(DRIZZLE *drizzle)
226
461
{
227
462
  if (drizzle->fields)
228
 
  {
229
 
    /* TODO - we need to de-alloc field storage */
230
 
    free(drizzle->fields->catalog);
231
 
    free(drizzle->fields->db);
232
 
    free(drizzle->fields->table);
233
 
    free(drizzle->fields->org_table);
234
 
    free(drizzle->fields->name);
235
 
    free(drizzle->fields->org_name);
236
 
    free(drizzle->fields->def);
237
 
    free(drizzle->fields);
238
 
 
239
 
  }
240
 
  /* init_alloc_root(&drizzle->field_alloc,8192,0); */ /* Assume rowlength < 8192 */
 
463
    free_root(&drizzle->field_alloc,MYF(0));
 
464
  init_alloc_root(&drizzle->field_alloc,8192,0); /* Assume rowlength < 8192 */
241
465
  drizzle->fields= 0;
242
466
  drizzle->field_count= 0;      /* For API */
243
467
  drizzle->warning_count= 0;
245
469
  return;
246
470
}
247
471
 
248
 
 
249
 
 
250
 
 
251
 
 
252
 
void
 
472
/*
 
473
  Flush result set sent from server
 
474
*/
 
475
 
 
476
static void cli_flush_use_result(DRIZZLE *drizzle)
 
477
{
 
478
  /* Clear the current execution status */
 
479
  for (;;)
 
480
  {
 
481
    ulong pkt_len;
 
482
    if ((pkt_len=cli_safe_read(drizzle)) == packet_error)
 
483
      break;
 
484
    if (pkt_len <= 8 && drizzle->net.read_pos[0] == 254)
 
485
    {
 
486
      if (protocol_41(drizzle))
 
487
      {
 
488
        char *pos= (char*) drizzle->net.read_pos + 1;
 
489
        drizzle->warning_count=uint2korr(pos); pos+=2;
 
490
        drizzle->server_status=uint2korr(pos); pos+=2;
 
491
      }
 
492
      break;                            /* End of data */
 
493
    }
 
494
  }
 
495
  return;
 
496
}
 
497
 
 
498
 
 
499
/**************************************************************************
 
500
  Shut down connection
 
501
**************************************************************************/
 
502
 
 
503
void end_server(DRIZZLE *drizzle)
 
504
{
 
505
  int save_errno= errno;
 
506
  if (drizzle->net.vio != 0)
 
507
  {
 
508
    init_sigpipe_variables
 
509
    set_sigpipe(drizzle);
 
510
    vio_delete(drizzle->net.vio);
 
511
    reset_sigpipe(drizzle);
 
512
    drizzle->net.vio= 0;          /* Marker */
 
513
  }
 
514
  net_end(&drizzle->net);
 
515
  free_old_query(drizzle);
 
516
  errno= save_errno;
 
517
  return;
 
518
}
 
519
 
 
520
 
 
521
void STDCALL
253
522
drizzle_free_result(DRIZZLE_RES *result)
254
523
{
255
524
  if (result)
268
537
      }
269
538
    }
270
539
    free_rows(result->data);
271
 
    /* TODO: free result->fields */
 
540
    if (result->fields)
 
541
      free_root(&result->field_alloc,MYF(0));
272
542
    if (result->row)
273
 
      free((unsigned char*) result->row);
274
 
    free((unsigned char*) result);
275
 
  }
276
 
}
277
 
 
278
 
 
279
 
 
 
543
      my_free((uchar*) result->row,MYF(0));
 
544
    my_free((uchar*) result,MYF(0));
 
545
  }
 
546
  return;
 
547
}
 
548
 
 
549
/****************************************************************************
 
550
  Get options from my.cnf
 
551
****************************************************************************/
 
552
 
 
553
static const char *default_options[]=
 
554
{
 
555
  "port","socket","compress","password","pipe", "timeout", "user",
 
556
  "init-command", "host", "database", "return-found-rows",
 
557
  "ssl-key" ,"ssl-cert" ,"ssl-ca" ,"ssl-capath",
 
558
  "character-sets-dir", "default-character-set", "interactive-timeout",
 
559
  "connect-timeout", "local-infile", "disable-local-infile",
 
560
  "ssl-cipher", "max-allowed-packet", "protocol", "shared-memory-base-name",
 
561
  "multi-results", "multi-statements", "multi-queries", "secure-auth",
 
562
  "report-data-truncation",
 
563
  NullS
 
564
};
 
565
 
 
566
static TYPELIB option_types={array_elements(default_options)-1,
 
567
           "options",default_options, NULL};
 
568
 
 
569
const char *sql_protocol_names_lib[] =
 
570
{ "TCP", "SOCKET", "PIPE", "MEMORY", NullS };
 
571
TYPELIB sql_protocol_typelib = {array_elements(sql_protocol_names_lib)-1,"",
 
572
        sql_protocol_names_lib, NULL};
 
573
 
 
574
static int add_init_command(struct st_drizzle_options *options, const char *cmd)
 
575
{
 
576
  char *tmp;
 
577
 
 
578
  if (!options->init_commands)
 
579
  {
 
580
    options->init_commands= (DYNAMIC_ARRAY*)my_malloc(sizeof(DYNAMIC_ARRAY),
 
581
                  MYF(MY_WME));
 
582
    init_dynamic_array(options->init_commands,sizeof(char*),0,5 CALLER_INFO);
 
583
  }
 
584
 
 
585
  if (!(tmp= my_strdup(cmd,MYF(MY_WME))) ||
 
586
      insert_dynamic(options->init_commands, (uchar*)&tmp))
 
587
  {
 
588
    my_free(tmp, MYF(MY_ALLOW_ZERO_PTR));
 
589
    return 1;
 
590
  }
 
591
 
 
592
  return 0;
 
593
}
 
594
 
 
595
void drizzle_read_default_options(struct st_drizzle_options *options,
 
596
        const char *filename,const char *group)
 
597
{
 
598
  int argc;
 
599
  char *argv_buff[1],**argv;
 
600
  const char *groups[3];
 
601
 
 
602
  argc=1; argv=argv_buff; argv_buff[0]= (char*) "client";
 
603
  groups[0]= (char*) "client"; groups[1]= (char*) group; groups[2]=0;
 
604
 
 
605
  load_defaults(filename, groups, &argc, &argv);
 
606
  if (argc != 1)        /* If some default option */
 
607
  {
 
608
    char **option=argv;
 
609
    while (*++option)
 
610
    {
 
611
      if (option[0][0] == '-' && option[0][1] == '-')
 
612
      {
 
613
  char *end=strcend(*option,'=');
 
614
  char *opt_arg=0;
 
615
  if (*end)
 
616
  {
 
617
    opt_arg=end+1;
 
618
    *end=0;        /* Remove '=' */
 
619
  }
 
620
  /* Change all '_' in variable name to '-' */
 
621
  for (end= *option ; *(end= strcend(end,'_')) ; )
 
622
    *end= '-';
 
623
  switch (find_type(*option+2,&option_types,2)) {
 
624
  case 1:        /* port */
 
625
    if (opt_arg)
 
626
      options->port=atoi(opt_arg);
 
627
    break;
 
628
  case 2:        /* socket */
 
629
    if (opt_arg)
 
630
    {
 
631
      my_free(options->unix_socket,MYF(MY_ALLOW_ZERO_PTR));
 
632
      options->unix_socket=my_strdup(opt_arg,MYF(MY_WME));
 
633
    }
 
634
    break;
 
635
  case 3:        /* compress */
 
636
    options->compress=1;
 
637
    options->client_flag|= CLIENT_COMPRESS;
 
638
    break;
 
639
  case 4:        /* password */
 
640
    if (opt_arg)
 
641
    {
 
642
      my_free(options->password,MYF(MY_ALLOW_ZERO_PTR));
 
643
      options->password=my_strdup(opt_arg,MYF(MY_WME));
 
644
    }
 
645
    break;
 
646
        case 5:
 
647
          options->protocol = DRIZZLE_PROTOCOL_PIPE;
 
648
  case 20:      /* connect_timeout */
 
649
  case 6:        /* timeout */
 
650
    if (opt_arg)
 
651
      options->connect_timeout=atoi(opt_arg);
 
652
    break;
 
653
  case 7:        /* user */
 
654
    if (opt_arg)
 
655
    {
 
656
      my_free(options->user,MYF(MY_ALLOW_ZERO_PTR));
 
657
      options->user=my_strdup(opt_arg,MYF(MY_WME));
 
658
    }
 
659
    break;
 
660
  case 8:        /* init-command */
 
661
    add_init_command(options,opt_arg);
 
662
    break;
 
663
  case 9:        /* host */
 
664
    if (opt_arg)
 
665
    {
 
666
      my_free(options->host,MYF(MY_ALLOW_ZERO_PTR));
 
667
      options->host=my_strdup(opt_arg,MYF(MY_WME));
 
668
    }
 
669
    break;
 
670
  case 10:      /* database */
 
671
    if (opt_arg)
 
672
    {
 
673
      my_free(options->db,MYF(MY_ALLOW_ZERO_PTR));
 
674
      options->db=my_strdup(opt_arg,MYF(MY_WME));
 
675
    }
 
676
    break;
 
677
  case 12:      /* return-found-rows */
 
678
    options->client_flag|=CLIENT_FOUND_ROWS;
 
679
    break;
 
680
  case 13:        /* Ignore SSL options */
 
681
  case 14:
 
682
  case 15:
 
683
  case 16:
 
684
        case 23:
 
685
    break;
 
686
  case 17:      /* charset-lib */
 
687
    my_free(options->charset_dir,MYF(MY_ALLOW_ZERO_PTR));
 
688
          options->charset_dir = my_strdup(opt_arg, MYF(MY_WME));
 
689
    break;
 
690
  case 18:
 
691
    my_free(options->charset_name,MYF(MY_ALLOW_ZERO_PTR));
 
692
          options->charset_name = my_strdup(opt_arg, MYF(MY_WME));
 
693
    break;
 
694
  case 19:        /* Interactive-timeout */
 
695
    options->client_flag|= CLIENT_INTERACTIVE;
 
696
    break;
 
697
  case 21:
 
698
    if (!opt_arg || atoi(opt_arg) != 0)
 
699
      options->client_flag|= CLIENT_LOCAL_FILES;
 
700
    else
 
701
      options->client_flag&= ~CLIENT_LOCAL_FILES;
 
702
    break;
 
703
  case 22:
 
704
    options->client_flag&= ~CLIENT_LOCAL_FILES;
 
705
          break;
 
706
  case 24: /* max-allowed-packet */
 
707
          if (opt_arg)
 
708
      options->max_allowed_packet= atoi(opt_arg);
 
709
    break;
 
710
        case 25: /* protocol */
 
711
          if ((options->protocol= find_type(opt_arg,
 
712
              &sql_protocol_typelib,0)) <= 0)
 
713
          {
 
714
            fprintf(stderr, "Unknown option to protocol: %s\n", opt_arg);
 
715
            exit(1);
 
716
          }
 
717
          break;
 
718
        case 26: /* shared_memory_base_name */
 
719
#ifdef HAVE_SMEM
 
720
          if (options->shared_memory_base_name != def_shared_memory_base_name)
 
721
            my_free(options->shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
 
722
          options->shared_memory_base_name=my_strdup(opt_arg,MYF(MY_WME));
 
723
#endif
 
724
          break;
 
725
  case 27: /* multi-results */
 
726
    options->client_flag|= CLIENT_MULTI_RESULTS;
 
727
    break;
 
728
  case 28: /* multi-statements */
 
729
  case 29: /* multi-queries */
 
730
    options->client_flag|= CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS;
 
731
    break;
 
732
        case 30: /* secure-auth */
 
733
          options->secure_auth= true;
 
734
          break;
 
735
        case 31: /* report-data-truncation */
 
736
          options->report_data_truncation= opt_arg ? test(atoi(opt_arg)) : 1;
 
737
          break;
 
738
  default:
 
739
          break;
 
740
  }
 
741
      }
 
742
    }
 
743
  }
 
744
  free_defaults(argv);
 
745
  return;
 
746
}
 
747
 
 
748
 
 
749
/**************************************************************************
 
750
  Get column lengths of the current row
 
751
  If one uses drizzle_use_result, res->lengths contains the length information,
 
752
  else the lengths are calculated from the offset between pointers.
 
753
**************************************************************************/
 
754
 
 
755
static void cli_fetch_lengths(uint32_t *to, DRIZZLE_ROW column, uint32_t field_count)
 
756
{
 
757
  uint32_t *prev_length;
 
758
  char *start=0;
 
759
  DRIZZLE_ROW end;
 
760
 
 
761
  prev_length=0;        /* Keep gcc happy */
 
762
  for (end=column + field_count + 1 ; column != end ; column++, to++)
 
763
  {
 
764
    if (!*column)
 
765
    {
 
766
      *to= 0;          /* Null */
 
767
      continue;
 
768
    }
 
769
    if (start)          /* Found end of prev string */
 
770
      *prev_length= (ulong) (*column-start-1);
 
771
    start= *column;
 
772
    prev_length= to;
 
773
  }
 
774
}
 
775
 
 
776
/***************************************************************************
 
777
  Change field rows to field structs
 
778
***************************************************************************/
 
779
 
 
780
DRIZZLE_FIELD *
 
781
unpack_fields(DRIZZLE_DATA *data,MEM_ROOT *alloc,uint fields,
 
782
        my_bool default_value, uint server_capabilities)
 
783
{
 
784
  DRIZZLE_ROWS  *row;
 
785
  DRIZZLE_FIELD  *field,*result;
 
786
  uint32_t lengths[9];        /* Max of fields */
 
787
 
 
788
  field= result= (DRIZZLE_FIELD*) alloc_root(alloc,
 
789
             (uint) sizeof(*field)*fields);
 
790
  if (!result)
 
791
  {
 
792
    free_rows(data);        /* Free old data */
 
793
    return(0);
 
794
  }
 
795
  bzero((char*) field, (uint) sizeof(DRIZZLE_FIELD)*fields);
 
796
  if (server_capabilities & CLIENT_PROTOCOL_41)
 
797
  {
 
798
    /* server is 4.1, and returns the new field result format */
 
799
    for (row=data->data; row ; row = row->next,field++)
 
800
    {
 
801
      uchar *pos;
 
802
      /* fields count may be wrong */
 
803
      assert((uint) (field - result) < fields);
 
804
      cli_fetch_lengths(&lengths[0], row->data, default_value ? 8 : 7);
 
805
      field->catalog=   strmake_root(alloc,(char*) row->data[0], lengths[0]);
 
806
      field->db=        strmake_root(alloc,(char*) row->data[1], lengths[1]);
 
807
      field->table=     strmake_root(alloc,(char*) row->data[2], lengths[2]);
 
808
      field->org_table= strmake_root(alloc,(char*) row->data[3], lengths[3]);
 
809
      field->name=      strmake_root(alloc,(char*) row->data[4], lengths[4]);
 
810
      field->org_name=  strmake_root(alloc,(char*) row->data[5], lengths[5]);
 
811
 
 
812
      field->catalog_length=  lengths[0];
 
813
      field->db_length=    lengths[1];
 
814
      field->table_length=  lengths[2];
 
815
      field->org_table_length=  lengths[3];
 
816
      field->name_length=  lengths[4];
 
817
      field->org_name_length=  lengths[5];
 
818
 
 
819
      /* Unpack fixed length parts */
 
820
      pos= (uchar*) row->data[6];
 
821
      field->charsetnr= uint2korr(pos);
 
822
      field->length=  (uint) uint4korr(pos+2);
 
823
      field->type=  (enum enum_field_types) pos[6];
 
824
      field->flags=  uint2korr(pos+7);
 
825
      field->decimals=  (uint) pos[9];
 
826
 
 
827
      if (INTERNAL_NUM_FIELD(field))
 
828
        field->flags|= NUM_FLAG;
 
829
      if (default_value && row->data[7])
 
830
      {
 
831
        field->def=strmake_root(alloc,(char*) row->data[7], lengths[7]);
 
832
  field->def_length= lengths[7];
 
833
      }
 
834
      else
 
835
        field->def=0;
 
836
      field->max_length= 0;
 
837
    }
 
838
  }
 
839
#ifndef DELETE_SUPPORT_OF_4_0_PROTOCOL
 
840
  else
 
841
  {
 
842
    /* old protocol, for backward compatibility */
 
843
    for (row=data->data; row ; row = row->next,field++)
 
844
    {
 
845
      cli_fetch_lengths(&lengths[0], row->data, default_value ? 6 : 5);
 
846
      field->org_table= field->table=  strdup_root(alloc,(char*) row->data[0]);
 
847
      field->name=   strdup_root(alloc,(char*) row->data[1]);
 
848
      field->length= (uint) uint3korr(row->data[2]);
 
849
      field->type=   (enum enum_field_types) (uchar) row->data[3][0];
 
850
 
 
851
      field->catalog=(char*)  "";
 
852
      field->db=     (char*)  "";
 
853
      field->catalog_length= 0;
 
854
      field->db_length= 0;
 
855
      field->org_table_length=  field->table_length=  lengths[0];
 
856
      field->name_length=  lengths[1];
 
857
 
 
858
      if (server_capabilities & CLIENT_LONG_FLAG)
 
859
      {
 
860
        field->flags=   uint2korr(row->data[4]);
 
861
        field->decimals=(uint) (uchar) row->data[4][2];
 
862
      }
 
863
      else
 
864
      {
 
865
        field->flags=   (uint) (uchar) row->data[4][0];
 
866
        field->decimals=(uint) (uchar) row->data[4][1];
 
867
      }
 
868
      if (INTERNAL_NUM_FIELD(field))
 
869
        field->flags|= NUM_FLAG;
 
870
      if (default_value && row->data[5])
 
871
      {
 
872
        field->def=strdup_root(alloc,(char*) row->data[5]);
 
873
  field->def_length= lengths[5];
 
874
      }
 
875
      else
 
876
        field->def=0;
 
877
      field->max_length= 0;
 
878
    }
 
879
  }
 
880
#endif /* DELETE_SUPPORT_OF_4_0_PROTOCOL */
 
881
  free_rows(data);        /* Free old data */
 
882
  return(result);
 
883
}
280
884
 
281
885
/* Read all rows (fields or data) from server */
282
886
 
283
 
DRIZZLE_DATA *cli_read_rows(DRIZZLE *drizzle, DRIZZLE_FIELD *DRIZZLE_FIELDs, uint32_t fields)
 
887
DRIZZLE_DATA *cli_read_rows(DRIZZLE *drizzle,DRIZZLE_FIELD *DRIZZLE_FIELDs,
 
888
        unsigned int fields)
284
889
{
285
 
  uint32_t  field;
286
 
  uint32_t pkt_len;
287
 
  uint32_t len;
288
 
  unsigned char *cp;
 
890
  uint  field;
 
891
  ulong pkt_len;
 
892
  ulong len;
 
893
  uchar *cp;
289
894
  char  *to, *end_to;
290
895
  DRIZZLE_DATA *result;
291
896
  DRIZZLE_ROWS **prev_ptr,*cur;
293
898
 
294
899
  if ((pkt_len= cli_safe_read(drizzle)) == packet_error)
295
900
    return(0);
296
 
  if (!(result=(DRIZZLE_DATA*) malloc(sizeof(DRIZZLE_DATA))))
 
901
  if (!(result=(DRIZZLE_DATA*) my_malloc(sizeof(DRIZZLE_DATA),
 
902
               MYF(MY_WME | MY_ZEROFILL))))
297
903
  {
298
 
    drizzle_set_error(drizzle, CR_OUT_OF_MEMORY,
299
 
                      sqlstate_get_unknown());
 
904
    set_drizzle_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
300
905
    return(0);
301
906
  }
302
 
  memset(result, 0, sizeof(DRIZZLE_DATA));
 
907
  init_alloc_root(&result->alloc,8192,0);  /* Assume rowlength < 8192 */
 
908
  result->alloc.min_malloc=sizeof(DRIZZLE_ROWS);
303
909
  prev_ptr= &result->data;
304
910
  result->rows=0;
305
911
  result->fields=fields;
306
912
 
307
913
  /*
308
 
    The last EOF packet is either a 254 (0xFE) character followed by 1-7 status bytes.
 
914
    The last EOF packet is either a single 254 character or (in DRIZZLE 4.1)
 
915
    254 followed by 1-7 status bytes.
309
916
 
310
917
    This doesn't conflict with normal usage of 254 which stands for a
311
918
    string where the length of the string is 8 bytes. (see net_field_length())
312
919
  */
313
920
 
314
 
  while (*(cp=net->read_pos) != DRIZZLE_PROTOCOL_NO_MORE_DATA || pkt_len >= 8)
 
921
  while (*(cp=net->read_pos) != 254 || pkt_len >= 8)
315
922
  {
316
923
    result->rows++;
317
 
    if (!(cur= (DRIZZLE_ROWS*) malloc(sizeof(DRIZZLE_ROWS))) ||
318
 
        !(cur->data= ((DRIZZLE_ROW) malloc((fields+1)*sizeof(char *)+pkt_len))))
 
924
    if (!(cur= (DRIZZLE_ROWS*) alloc_root(&result->alloc,
 
925
          sizeof(DRIZZLE_ROWS))) ||
 
926
  !(cur->data= ((DRIZZLE_ROW)
 
927
          alloc_root(&result->alloc,
 
928
         (fields+1)*sizeof(char *)+pkt_len))))
319
929
    {
320
930
      free_rows(result);
321
 
      drizzle_set_error(drizzle, CR_OUT_OF_MEMORY, sqlstate_get_unknown());
 
931
      set_drizzle_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
322
932
      return(0);
323
933
    }
324
934
    *prev_ptr=cur;
327
937
    end_to=to+pkt_len-1;
328
938
    for (field=0 ; field < fields ; field++)
329
939
    {
330
 
      if ((len= net_field_length(&cp)) == NULL_LENGTH)
 
940
      if ((len=(ulong) net_field_length(&cp)) == NULL_LENGTH)
331
941
      {            /* null field */
332
 
        cur->data[field] = 0;
 
942
  cur->data[field] = 0;
333
943
      }
334
944
      else
335
945
      {
336
 
        cur->data[field] = to;
337
 
        if (len > (uint32_t) (end_to - to))
 
946
  cur->data[field] = to;
 
947
        if (len > (ulong) (end_to - to))
338
948
        {
339
949
          free_rows(result);
340
 
          drizzle_set_error(drizzle, CR_MALFORMED_PACKET,
341
 
                            sqlstate_get_unknown());
 
950
          set_drizzle_error(drizzle, CR_MALFORMED_PACKET, unknown_sqlstate);
342
951
          return(0);
343
952
        }
344
 
        memcpy(to, cp, len);
345
 
        to[len]=0;
346
 
        to+=len+1;
347
 
        cp+=len;
348
 
        if (DRIZZLE_FIELDs)
349
 
        {
350
 
          if (DRIZZLE_FIELDs[field].max_length < len)
351
 
            DRIZZLE_FIELDs[field].max_length=len;
352
 
        }
 
953
  memcpy(to,(char*) cp,len); to[len]=0;
 
954
  to+=len+1;
 
955
  cp+=len;
 
956
  if (DRIZZLE_FIELDs)
 
957
  {
 
958
    if (DRIZZLE_FIELDs[field].max_length < len)
 
959
      DRIZZLE_FIELDs[field].max_length=len;
 
960
  }
353
961
      }
354
962
    }
355
963
    cur->data[field]=to;      /* End of last field */
377
985
static int32_t
378
986
read_one_row(DRIZZLE *drizzle, uint32_t fields, DRIZZLE_ROW row, uint32_t *lengths)
379
987
{
380
 
  uint32_t field;
381
 
  uint32_t pkt_len,len;
382
 
  unsigned char *pos, *prev_pos, *end_pos;
 
988
  uint field;
 
989
  ulong pkt_len,len;
 
990
  uchar *pos, *prev_pos, *end_pos;
383
991
  NET *net= &drizzle->net;
384
992
 
385
993
  if ((pkt_len=cli_safe_read(drizzle)) == packet_error)
386
994
    return -1;
387
 
  if (pkt_len <= 8 && net->read_pos[0] == DRIZZLE_PROTOCOL_NO_MORE_DATA)
 
995
  if (pkt_len <= 8 && net->read_pos[0] == 254)
388
996
  {
389
997
    if (pkt_len > 1)        /* DRIZZLE 4.1 protocol */
390
998
    {
398
1006
  end_pos=pos+pkt_len;
399
1007
  for (field=0 ; field < fields ; field++)
400
1008
  {
401
 
    if ((len= net_field_length(&pos)) == NULL_LENGTH)
 
1009
    if ((len=(ulong) net_field_length(&pos)) == NULL_LENGTH)
402
1010
    {            /* null field */
403
1011
      row[field] = 0;
404
1012
      *lengths++=0;
405
1013
    }
406
1014
    else
407
1015
    {
408
 
      if (len > (uint32_t) (end_pos - pos))
 
1016
      if (len > (ulong) (end_pos - pos))
409
1017
      {
410
 
        drizzle_set_error(drizzle, CR_UNKNOWN_ERROR,
411
 
                          sqlstate_get_unknown());
 
1018
        set_drizzle_error(drizzle, CR_UNKNOWN_ERROR, unknown_sqlstate);
412
1019
        return -1;
413
1020
      }
414
1021
      row[field] = (char*) pos;
425
1032
}
426
1033
 
427
1034
 
 
1035
/****************************************************************************
 
1036
  Init DRIZZLE structure or allocate one
 
1037
****************************************************************************/
 
1038
 
 
1039
DRIZZLE *
 
1040
drizzle_create(DRIZZLE *ptr)
 
1041
{
 
1042
 
 
1043
  if (!drizzle_client_init)
 
1044
  {
 
1045
    drizzle_client_init=true;
 
1046
    org_my_init_done=my_init_done;
 
1047
 
 
1048
    /* Will init threads */
 
1049
    if (my_init())
 
1050
      return NULL;
 
1051
 
 
1052
    init_client_errs();
 
1053
 
 
1054
    if (!drizzle_port)
 
1055
    {
 
1056
      drizzle_port = MYSQL_PORT;
 
1057
      {
 
1058
        struct servent *serv_ptr;
 
1059
        char *env;
 
1060
 
 
1061
        /*
 
1062
          if builder specifically requested a default port, use that
 
1063
          (even if it coincides with our factory default).
 
1064
          only if they didn't do we check /etc/services (and, failing
 
1065
          on that, fall back to the factory default of 4427).
 
1066
          either default can be overridden by the environment variable
 
1067
          MYSQL_TCP_PORT, which in turn can be overridden with command
 
1068
          line options.
 
1069
        */
 
1070
 
 
1071
#if MYSQL_PORT_DEFAULT == 0
 
1072
        if ((serv_ptr = getservbyname("drizzle", "tcp")))
 
1073
          drizzle_port = (uint) ntohs((ushort) serv_ptr->s_port);
 
1074
#endif
 
1075
        if ((env = getenv("DRIZZLE_TCP_PORT")))
 
1076
          drizzle_port =(uint) atoi(env);
 
1077
      }
 
1078
    }
 
1079
    if (!drizzle_unix_port)
 
1080
    {
 
1081
      char *env;
 
1082
      drizzle_unix_port = (char*) MYSQL_UNIX_ADDR;
 
1083
      if ((env = getenv("DRIZZLE_UNIX_PORT")))
 
1084
        drizzle_unix_port = env;
 
1085
    }
 
1086
#if defined(SIGPIPE)
 
1087
    (void) signal(SIGPIPE, SIG_IGN);
 
1088
#endif
 
1089
  }
 
1090
  else
 
1091
    /* Init if new thread */
 
1092
    if (my_thread_init())
 
1093
      return NULL;
 
1094
 
 
1095
  if (ptr == NULL)
 
1096
  {
 
1097
    ptr= (DRIZZLE *) malloc(sizeof(DRIZZLE));
 
1098
 
 
1099
    if (ptr == NULL)
 
1100
    {
 
1101
      set_drizzle_error(NULL, CR_OUT_OF_MEMORY, unknown_sqlstate);
 
1102
      return 0;
 
1103
    }
 
1104
    memset(ptr, 0, sizeof(DRIZZLE));
 
1105
    ptr->free_me=1;
 
1106
  }
 
1107
  else
 
1108
  {
 
1109
    memset(ptr, 0, sizeof(DRIZZLE)); 
 
1110
  }
 
1111
 
 
1112
  ptr->options.connect_timeout= CONNECT_TIMEOUT;
 
1113
  ptr->charset=default_client_charset_info;
 
1114
  strcpy(ptr->net.sqlstate, not_error_sqlstate);
 
1115
 
 
1116
  /*
 
1117
    Only enable LOAD DATA INFILE by default if configured with
 
1118
    --enable-local-infile
 
1119
  */
 
1120
 
 
1121
#if defined(ENABLED_LOCAL_INFILE) && !defined(DRIZZLE_SERVER)
 
1122
  ptr->options.client_flag|= CLIENT_LOCAL_FILES;
 
1123
#endif
 
1124
 
 
1125
#ifdef HAVE_SMEM
 
1126
  ptr->options.shared_memory_base_name= (char*) def_shared_memory_base_name;
 
1127
#endif
 
1128
 
 
1129
  ptr->options.methods_to_use= DRIZZLE_OPT_GUESS_CONNECTION;
 
1130
  ptr->options.report_data_truncation= true;  /* default */
 
1131
 
 
1132
  /*
 
1133
    By default we don't reconnect because it could silently corrupt data (after
 
1134
    reconnection you potentially lose table locks, user variables, session
 
1135
    variables (transactions but they are specifically dealt with in
 
1136
    drizzle_reconnect()).
 
1137
    This is a change: < 5.0.3 drizzle->reconnect was set to 1 by default.
 
1138
    How this change impacts existing apps:
 
1139
    - existing apps which relyed on the default will see a behaviour change;
 
1140
    they will have to set reconnect=1 after drizzle_connect().
 
1141
    - existing apps which explicitely asked for reconnection (the only way they
 
1142
    could do it was by setting drizzle.reconnect to 1 after drizzle_connect())
 
1143
    will not see a behaviour change.
 
1144
    - existing apps which explicitely asked for no reconnection
 
1145
    (drizzle.reconnect=0) will not see a behaviour change.
 
1146
  */
 
1147
  ptr->reconnect= 0;
 
1148
 
 
1149
  return ptr;
 
1150
}
 
1151
 
 
1152
 
 
1153
/*
 
1154
  Free all memory and resources used by the client library
 
1155
 
 
1156
  NOTES
 
1157
    When calling this there should not be any other threads using
 
1158
    the library.
 
1159
 
 
1160
    To make things simpler when used with windows dll's (which calls this
 
1161
    function automaticly), it's safe to call this function multiple times.
 
1162
*/
 
1163
 
 
1164
 
 
1165
void STDCALL drizzle_server_end()
 
1166
{
 
1167
  if (!drizzle_client_init)
 
1168
    return;
 
1169
 
 
1170
  finish_client_errs();
 
1171
  vio_end();
 
1172
 
 
1173
  /* If library called my_init(), free memory allocated by it */
 
1174
  if (!org_my_init_done)
 
1175
  {
 
1176
    my_end(0);
 
1177
  }
 
1178
  else
 
1179
  {
 
1180
    free_charsets();
 
1181
    drizzle_thread_end();
 
1182
  }
 
1183
 
 
1184
  drizzle_client_init= org_my_init_done= 0;
 
1185
#ifdef EMBEDDED_SERVER
 
1186
  if (stderror_file)
 
1187
  {
 
1188
    fclose(stderror_file);
 
1189
    stderror_file= 0;
 
1190
  }
 
1191
#endif
 
1192
}
 
1193
 
 
1194
 
 
1195
/*
 
1196
  Fill in SSL part of DRIZZLE structure and set 'use_ssl' flag.
 
1197
  NB! Errors are not reported until you do drizzle_connect.
 
1198
*/
 
1199
 
 
1200
#define strdup_if_not_null(A) (A) == 0 ? 0 : my_strdup((A),MYF(MY_WME))
 
1201
 
 
1202
/*
 
1203
  Note that the drizzle argument must be initialized with drizzle_init()
 
1204
  before calling drizzle_connect !
 
1205
*/
 
1206
 
 
1207
static bool cli_read_query_result(DRIZZLE *drizzle);
 
1208
static DRIZZLE_RES *cli_use_result(DRIZZLE *drizzle);
 
1209
 
 
1210
static DRIZZLE_METHODS client_methods=
 
1211
{
 
1212
  cli_read_query_result,                       /* read_query_result */
 
1213
  cli_advanced_command,                        /* advanced_command */
 
1214
  cli_read_rows,                               /* read_rows */
 
1215
  cli_use_result,                              /* use_result */
 
1216
  cli_fetch_lengths,                           /* fetch_lengths */
 
1217
  cli_flush_use_result,                         /* flush_use_result */
 
1218
#ifndef MYSQL_SERVER
 
1219
  cli_list_fields,                            /* list_fields */
 
1220
  cli_unbuffered_fetch,                        /* unbuffered_fetch */
 
1221
  cli_read_statistics,                         /* read_statistics */
 
1222
  cli_read_query_result,                       /* next_result */
 
1223
  cli_read_change_user_result,                 /* read_change_user_result */
 
1224
#else
 
1225
  0,0,0,0,0
 
1226
#endif
 
1227
};
 
1228
 
 
1229
C_MODE_START
 
1230
int drizzle_init_character_set(DRIZZLE *drizzle)
 
1231
{
 
1232
  const char *default_collation_name;
 
1233
 
 
1234
  /* Set character set */
 
1235
  if (!drizzle->options.charset_name)
 
1236
  {
 
1237
    default_collation_name= MYSQL_DEFAULT_COLLATION_NAME;
 
1238
    if (!(drizzle->options.charset_name=
 
1239
       my_strdup(MYSQL_DEFAULT_CHARSET_NAME,MYF(MY_WME))))
 
1240
    return 1;
 
1241
  }
 
1242
  else
 
1243
    default_collation_name= NULL;
 
1244
 
 
1245
  {
 
1246
    const char *save= charsets_dir;
 
1247
    if (drizzle->options.charset_dir)
 
1248
      charsets_dir=drizzle->options.charset_dir;
 
1249
    drizzle->charset=get_charset_by_csname(drizzle->options.charset_name,
 
1250
                                         MY_CS_PRIMARY, MYF(MY_WME));
 
1251
    if (drizzle->charset && default_collation_name)
 
1252
    {
 
1253
      CHARSET_INFO *collation;
 
1254
      if ((collation=
 
1255
           get_charset_by_name(default_collation_name, MYF(MY_WME))))
 
1256
      {
 
1257
        if (!my_charset_same(drizzle->charset, collation))
 
1258
        {
 
1259
          my_printf_error(ER_UNKNOWN_ERROR,
 
1260
                         "COLLATION %s is not valid for CHARACTER SET %s",
 
1261
                         MYF(0),
 
1262
                         default_collation_name, drizzle->options.charset_name);
 
1263
          drizzle->charset= NULL;
 
1264
        }
 
1265
        else
 
1266
        {
 
1267
          drizzle->charset= collation;
 
1268
        }
 
1269
      }
 
1270
      else
 
1271
        drizzle->charset= NULL;
 
1272
    }
 
1273
    charsets_dir= save;
 
1274
  }
 
1275
 
 
1276
  if (!drizzle->charset)
 
1277
  {
 
1278
    if (drizzle->options.charset_dir)
 
1279
      set_drizzle_extended_error(drizzle, CR_CANT_READ_CHARSET, unknown_sqlstate,
 
1280
                               ER(CR_CANT_READ_CHARSET),
 
1281
                               drizzle->options.charset_name,
 
1282
                               drizzle->options.charset_dir);
 
1283
    else
 
1284
    {
 
1285
      char cs_dir_name[FN_REFLEN];
 
1286
      get_charsets_dir(cs_dir_name);
 
1287
      set_drizzle_extended_error(drizzle, CR_CANT_READ_CHARSET, unknown_sqlstate,
 
1288
                               ER(CR_CANT_READ_CHARSET),
 
1289
                               drizzle->options.charset_name,
 
1290
                               cs_dir_name);
 
1291
    }
 
1292
    return 1;
 
1293
  }
 
1294
  return 0;
 
1295
}
 
1296
C_MODE_END
 
1297
 
 
1298
 
 
1299
DRIZZLE * STDCALL
 
1300
CLI_DRIZZLE_CONNECT(DRIZZLE *drizzle,const char *host, const char *user,
 
1301
                       const char *passwd, const char *db,
 
1302
                       uint32_t port, const char *unix_socket, uint32_t client_flag)
 
1303
{
 
1304
  char          buff[NAME_LEN+USERNAME_LENGTH+100];
 
1305
  char          *end,*host_info=NULL;
 
1306
  uint32_t         pkt_length;
 
1307
  NET           *net= &drizzle->net;
 
1308
  struct        sockaddr_un UNIXaddr;
 
1309
  init_sigpipe_variables
 
1310
 
 
1311
  /* Don't give sigpipe errors if the client doesn't want them */
 
1312
  set_sigpipe(drizzle);
 
1313
  drizzle->methods= &client_methods;
 
1314
  net->vio = 0;        /* If something goes wrong */
 
1315
  drizzle->client_flag=0;      /* For handshake */
 
1316
 
 
1317
  /* use default options */
 
1318
  if (drizzle->options.my_cnf_file || drizzle->options.my_cnf_group)
 
1319
  {
 
1320
    drizzle_read_default_options(&drizzle->options,
 
1321
             (drizzle->options.my_cnf_file ?
 
1322
        drizzle->options.my_cnf_file : "my"),
 
1323
             drizzle->options.my_cnf_group);
 
1324
    my_free(drizzle->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
 
1325
    my_free(drizzle->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
 
1326
    drizzle->options.my_cnf_file=drizzle->options.my_cnf_group=0;
 
1327
  }
 
1328
 
 
1329
  /* Some empty-string-tests are done because of ODBC */
 
1330
  if (!host || !host[0])
 
1331
    host=drizzle->options.host;
 
1332
  if (!user || !user[0])
 
1333
  {
 
1334
    user=drizzle->options.user;
 
1335
    if (!user)
 
1336
      user= "";
 
1337
  }
 
1338
  if (!passwd)
 
1339
  {
 
1340
    passwd=drizzle->options.password;
 
1341
    if (!passwd)
 
1342
      passwd= "";
 
1343
  }
 
1344
  if (!db || !db[0])
 
1345
    db=drizzle->options.db;
 
1346
  if (!port)
 
1347
    port=drizzle->options.port;
 
1348
  if (!unix_socket)
 
1349
    unix_socket=drizzle->options.unix_socket;
 
1350
 
 
1351
  drizzle->server_status=SERVER_STATUS_AUTOCOMMIT;
 
1352
 
 
1353
  /*
 
1354
    Part 0: Grab a socket and connect it to the server
 
1355
  */
 
1356
#if defined(HAVE_SMEM)
 
1357
  if ((!drizzle->options.protocol ||
 
1358
       drizzle->options.protocol == DRIZZLE_PROTOCOL_MEMORY) &&
 
1359
      (!host || !strcmp(host,LOCAL_HOST)))
 
1360
  {
 
1361
    if ((create_shared_memory(drizzle,net, drizzle->options.connect_timeout)) ==
 
1362
  INVALID_HANDLE_VALUE)
 
1363
    {
 
1364
      if (drizzle->options.protocol == DRIZZLE_PROTOCOL_MEMORY)
 
1365
  goto error;
 
1366
 
 
1367
      /*
 
1368
        Try also with PIPE or TCP/IP. Clear the error from
 
1369
        create_shared_memory().
 
1370
      */
 
1371
 
 
1372
      net_clear_error(net);
 
1373
    }
 
1374
    else
 
1375
    {
 
1376
      drizzle->options.protocol=DRIZZLE_PROTOCOL_MEMORY;
 
1377
      unix_socket = 0;
 
1378
      host=drizzle->options.shared_memory_base_name;
 
1379
      snprintf(host_info=buff, sizeof(buff)-1,
 
1380
               ER(CR_SHARED_MEMORY_CONNECTION), host);
 
1381
    }
 
1382
  }
 
1383
#endif /* HAVE_SMEM */
 
1384
  if (!net->vio &&
 
1385
      (!drizzle->options.protocol ||
 
1386
       drizzle->options.protocol == DRIZZLE_PROTOCOL_SOCKET) &&
 
1387
      (unix_socket || drizzle_unix_port) &&
 
1388
      (!host || !strcmp(host,LOCAL_HOST)))
 
1389
  {
 
1390
    my_socket sock= socket(AF_UNIX, SOCK_STREAM, 0);
 
1391
    if (sock == SOCKET_ERROR)
 
1392
    {
 
1393
      set_drizzle_extended_error(drizzle, CR_SOCKET_CREATE_ERROR,
 
1394
                               unknown_sqlstate,
 
1395
                               ER(CR_SOCKET_CREATE_ERROR),
 
1396
                               socket_errno);
 
1397
      goto error;
 
1398
    }
 
1399
 
 
1400
    net->vio= vio_new(sock, VIO_TYPE_SOCKET,
 
1401
                      VIO_LOCALHOST | VIO_BUFFERED_READ);
 
1402
    if (!net->vio)
 
1403
    {
 
1404
      set_drizzle_error(drizzle, CR_CONN_UNKNOW_PROTOCOL, unknown_sqlstate);
 
1405
      closesocket(sock);
 
1406
      goto error;
 
1407
    }
 
1408
 
 
1409
    host= LOCAL_HOST;
 
1410
    if (!unix_socket)
 
1411
      unix_socket= drizzle_unix_port;
 
1412
    host_info= (char*) ER(CR_LOCALHOST_CONNECTION);
 
1413
 
 
1414
    bzero((char*) &UNIXaddr, sizeof(UNIXaddr));
 
1415
    UNIXaddr.sun_family= AF_UNIX;
 
1416
    strmake(UNIXaddr.sun_path, unix_socket, sizeof(UNIXaddr.sun_path)-1);
 
1417
 
 
1418
    if (my_connect(sock, (struct sockaddr *) &UNIXaddr, sizeof(UNIXaddr),
 
1419
       drizzle->options.connect_timeout))
 
1420
    {
 
1421
      set_drizzle_extended_error(drizzle, CR_CONNECTION_ERROR,
 
1422
                               unknown_sqlstate,
 
1423
                               ER(CR_CONNECTION_ERROR),
 
1424
                               unix_socket, socket_errno);
 
1425
      vio_delete(net->vio);
 
1426
      net->vio= 0;
 
1427
      goto error;
 
1428
    }
 
1429
    drizzle->options.protocol=DRIZZLE_PROTOCOL_SOCKET;
 
1430
  }
 
1431
  if (!net->vio &&
 
1432
      (!drizzle->options.protocol ||
 
1433
       drizzle->options.protocol == DRIZZLE_PROTOCOL_TCP))
 
1434
  {
 
1435
    struct addrinfo *res_lst, hints, *t_res;
 
1436
    int gai_errno;
 
1437
    char port_buf[NI_MAXSERV];
 
1438
 
 
1439
    unix_socket=0;        /* This is not used */
 
1440
 
 
1441
    if (!port)
 
1442
      port= drizzle_port;
 
1443
 
 
1444
    if (!host)
 
1445
      host= LOCAL_HOST;
 
1446
 
 
1447
    snprintf(host_info=buff, sizeof(buff)-1, ER(CR_TCP_CONNECTION), host);
 
1448
 
 
1449
    memset(&hints, 0, sizeof(hints));
 
1450
    hints.ai_socktype= SOCK_STREAM;
 
1451
    hints.ai_protocol= IPPROTO_TCP;
 
1452
    hints.ai_family= AF_UNSPEC;
 
1453
 
 
1454
    snprintf(port_buf, NI_MAXSERV, "%d", port);
 
1455
    gai_errno= getaddrinfo(host, port_buf, &hints, &res_lst);
 
1456
 
 
1457
    if (gai_errno != 0)
 
1458
    {
 
1459
      set_drizzle_extended_error(drizzle, CR_UNKNOWN_HOST, unknown_sqlstate,
 
1460
                               ER(CR_UNKNOWN_HOST), host, errno);
 
1461
 
 
1462
      goto error;
 
1463
    }
 
1464
 
 
1465
    /* We only look at the first item (something to think about changing in the future) */
 
1466
    t_res= res_lst;
 
1467
    {
 
1468
      my_socket sock= socket(t_res->ai_family, t_res->ai_socktype,
 
1469
                             t_res->ai_protocol);
 
1470
      if (sock == SOCKET_ERROR)
 
1471
      {
 
1472
        set_drizzle_extended_error(drizzle, CR_IPSOCK_ERROR, unknown_sqlstate,
 
1473
                                 ER(CR_IPSOCK_ERROR), socket_errno);
 
1474
        freeaddrinfo(res_lst);
 
1475
        goto error;
 
1476
      }
 
1477
 
 
1478
      net->vio= vio_new(sock, VIO_TYPE_TCPIP, VIO_BUFFERED_READ);
 
1479
      if (! net->vio )
 
1480
      {
 
1481
        set_drizzle_error(drizzle, CR_CONN_UNKNOW_PROTOCOL, unknown_sqlstate);
 
1482
        closesocket(sock);
 
1483
        freeaddrinfo(res_lst);
 
1484
        goto error;
 
1485
      }
 
1486
 
 
1487
      if (my_connect(sock, t_res->ai_addr, t_res->ai_addrlen,
 
1488
                     drizzle->options.connect_timeout))
 
1489
      {
 
1490
        set_drizzle_extended_error(drizzle, CR_CONN_HOST_ERROR, unknown_sqlstate,
 
1491
                                 ER(CR_CONN_HOST_ERROR), host, socket_errno);
 
1492
        vio_delete(net->vio);
 
1493
        net->vio= 0;
 
1494
        freeaddrinfo(res_lst);
 
1495
        goto error;
 
1496
      }
 
1497
    }
 
1498
 
 
1499
    freeaddrinfo(res_lst);
 
1500
  }
 
1501
 
 
1502
  if (!net->vio)
 
1503
  {
 
1504
    set_drizzle_error(drizzle, CR_CONN_UNKNOW_PROTOCOL, unknown_sqlstate);
 
1505
    goto error;
 
1506
  }
 
1507
 
 
1508
  if (my_net_init(net, net->vio))
 
1509
  {
 
1510
    vio_delete(net->vio);
 
1511
    net->vio = 0;
 
1512
    set_drizzle_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
 
1513
    goto error;
 
1514
  }
 
1515
  vio_keepalive(net->vio,true);
 
1516
 
 
1517
  /* If user set read_timeout, let it override the default */
 
1518
  if (drizzle->options.read_timeout)
 
1519
    my_net_set_read_timeout(net, drizzle->options.read_timeout);
 
1520
 
 
1521
  /* If user set write_timeout, let it override the default */
 
1522
  if (drizzle->options.write_timeout)
 
1523
    my_net_set_write_timeout(net, drizzle->options.write_timeout);
 
1524
 
 
1525
  if (drizzle->options.max_allowed_packet)
 
1526
    net->max_packet_size= drizzle->options.max_allowed_packet;
 
1527
 
 
1528
  /* Get version info */
 
1529
  drizzle->protocol_version= PROTOCOL_VERSION;  /* Assume this */
 
1530
  if (drizzle->options.connect_timeout &&
 
1531
      vio_poll_read(net->vio, drizzle->options.connect_timeout))
 
1532
  {
 
1533
    set_drizzle_extended_error(drizzle, CR_SERVER_LOST, unknown_sqlstate,
 
1534
                             ER(CR_SERVER_LOST_EXTENDED),
 
1535
                             "waiting for initial communication packet",
 
1536
                             errno);
 
1537
    goto error;
 
1538
  }
 
1539
 
 
1540
  /*
 
1541
    Part 1: Connection established, read and parse first packet
 
1542
  */
 
1543
 
 
1544
  if ((pkt_length=cli_safe_read(drizzle)) == packet_error)
 
1545
  {
 
1546
    if (drizzle->net.last_errno == CR_SERVER_LOST)
 
1547
      set_drizzle_extended_error(drizzle, CR_SERVER_LOST, unknown_sqlstate,
 
1548
                               ER(CR_SERVER_LOST_EXTENDED),
 
1549
                               "reading initial communication packet",
 
1550
                               errno);
 
1551
    goto error;
 
1552
  }
 
1553
  /* Check if version of protocol matches current one */
 
1554
 
 
1555
  drizzle->protocol_version= net->read_pos[0];
 
1556
  if (drizzle->protocol_version != PROTOCOL_VERSION)
 
1557
  {
 
1558
    set_drizzle_extended_error(drizzle, CR_VERSION_ERROR, unknown_sqlstate,
 
1559
                             ER(CR_VERSION_ERROR), drizzle->protocol_version,
 
1560
                             PROTOCOL_VERSION);
 
1561
    goto error;
 
1562
  }
 
1563
  end=strend((char*) net->read_pos+1);
 
1564
  drizzle->thread_id=uint4korr(end+1);
 
1565
  end+=5;
 
1566
  /*
 
1567
    Scramble is split into two parts because old clients does not understand
 
1568
    long scrambles; here goes the first part.
 
1569
  */
 
1570
  strmake(drizzle->scramble, end, SCRAMBLE_LENGTH_323);
 
1571
  end+= SCRAMBLE_LENGTH_323+1;
 
1572
 
 
1573
  if (pkt_length >= (uint) (end+1 - (char*) net->read_pos))
 
1574
    drizzle->server_capabilities=uint2korr(end);
 
1575
  if (pkt_length >= (uint) (end+18 - (char*) net->read_pos))
 
1576
  {
 
1577
    /* New protocol with 16 bytes to describe server characteristics */
 
1578
    drizzle->server_language=end[2];
 
1579
    drizzle->server_status=uint2korr(end+3);
 
1580
  }
 
1581
  end+= 18;
 
1582
  if (pkt_length >= (uint) (end + SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323 + 1 -
 
1583
                           (char *) net->read_pos))
 
1584
    strmake(drizzle->scramble+SCRAMBLE_LENGTH_323, end,
 
1585
            SCRAMBLE_LENGTH-SCRAMBLE_LENGTH_323);
 
1586
  else
 
1587
    drizzle->server_capabilities&= ~CLIENT_SECURE_CONNECTION;
 
1588
 
 
1589
  if (drizzle->options.secure_auth && passwd[0] &&
 
1590
      !(drizzle->server_capabilities & CLIENT_SECURE_CONNECTION))
 
1591
  {
 
1592
    set_drizzle_error(drizzle, CR_SECURE_AUTH, unknown_sqlstate);
 
1593
    goto error;
 
1594
  }
 
1595
 
 
1596
  if (drizzle_init_character_set(drizzle))
 
1597
    goto error;
 
1598
 
 
1599
  /* Save connection information */
 
1600
  if (!my_multi_malloc(MYF(0),
 
1601
           &drizzle->host_info, (uint) strlen(host_info)+1,
 
1602
           &drizzle->host,      (uint) strlen(host)+1,
 
1603
           &drizzle->unix_socket,unix_socket ?
 
1604
           (uint) strlen(unix_socket)+1 : (uint) 1,
 
1605
           &drizzle->server_version,
 
1606
           (uint) (end - (char*) net->read_pos),
 
1607
           NullS) ||
 
1608
      !(drizzle->user=my_strdup(user,MYF(0))) ||
 
1609
      !(drizzle->passwd=my_strdup(passwd,MYF(0))))
 
1610
  {
 
1611
    set_drizzle_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
 
1612
    goto error;
 
1613
  }
 
1614
  strmov(drizzle->host_info,host_info);
 
1615
  strmov(drizzle->host,host);
 
1616
  if (unix_socket)
 
1617
    strmov(drizzle->unix_socket,unix_socket);
 
1618
  else
 
1619
    drizzle->unix_socket=0;
 
1620
  strmov(drizzle->server_version,(char*) net->read_pos+1);
 
1621
  drizzle->port=port;
 
1622
 
 
1623
  /*
 
1624
    Part 2: format and send client info to the server for access check
 
1625
  */
 
1626
 
 
1627
  client_flag|=drizzle->options.client_flag;
 
1628
  client_flag|=CLIENT_CAPABILITIES;
 
1629
  if (client_flag & CLIENT_MULTI_STATEMENTS)
 
1630
    client_flag|= CLIENT_MULTI_RESULTS;
 
1631
 
 
1632
  if (db)
 
1633
    client_flag|=CLIENT_CONNECT_WITH_DB;
 
1634
 
 
1635
  /* Remove options that server doesn't support */
 
1636
  client_flag= ((client_flag &
 
1637
     ~(CLIENT_COMPRESS | CLIENT_SSL | CLIENT_PROTOCOL_41)) |
 
1638
    (client_flag & drizzle->server_capabilities));
 
1639
  client_flag&= ~CLIENT_COMPRESS;
 
1640
 
 
1641
  if (client_flag & CLIENT_PROTOCOL_41)
 
1642
  {
 
1643
    /* 4.1 server and 4.1 client has a 32 byte option flag */
 
1644
    int4store(buff,client_flag);
 
1645
    int4store(buff+4, net->max_packet_size);
 
1646
    buff[8]= (char) drizzle->charset->number;
 
1647
    bzero(buff+9, 32-9);
 
1648
    end= buff+32;
 
1649
  }
 
1650
  else
 
1651
  {
 
1652
    int2store(buff,client_flag);
 
1653
    int3store(buff+2,net->max_packet_size);
 
1654
    end= buff+5;
 
1655
  }
 
1656
  drizzle->client_flag=client_flag;
 
1657
 
 
1658
  /* This needs to be changed as it's not useful with big packets */
 
1659
  if (user && user[0])
 
1660
    strmake(end,user,USERNAME_LENGTH);          /* Max user name */
 
1661
  else
 
1662
    read_user_name((char*) end);
 
1663
 
 
1664
  /* We have to handle different version of handshake here */
 
1665
#ifdef _CUSTOMCONFIG_
 
1666
#include "_cust_libdrizzle.h"
 
1667
#endif
 
1668
  end= strend(end) + 1;
 
1669
  if (passwd[0])
 
1670
  {
 
1671
    {
 
1672
      *end++= SCRAMBLE_LENGTH;
 
1673
      scramble(end, drizzle->scramble, passwd);
 
1674
      end+= SCRAMBLE_LENGTH;
 
1675
    }
 
1676
  }
 
1677
  else
 
1678
    *end++= '\0';                               /* empty password */
 
1679
 
 
1680
  /* Add database if needed */
 
1681
  if (db && (drizzle->server_capabilities & CLIENT_CONNECT_WITH_DB))
 
1682
  {
 
1683
    end= strmake(end, db, NAME_LEN) + 1;
 
1684
    drizzle->db= my_strdup(db,MYF(MY_WME));
 
1685
    db= 0;
 
1686
  }
 
1687
  /* Write authentication package */
 
1688
  if (my_net_write(net, (uchar*) buff, (size_t) (end-buff)) || net_flush(net))
 
1689
  {
 
1690
    set_drizzle_extended_error(drizzle, CR_SERVER_LOST, unknown_sqlstate,
 
1691
                             ER(CR_SERVER_LOST_EXTENDED),
 
1692
                             "sending authentication information",
 
1693
                             errno);
 
1694
    goto error;
 
1695
  }
 
1696
 
 
1697
  /*
 
1698
    Part 3: Authorization data's been sent. Now server can reply with
 
1699
    OK-packet, or re-request scrambled password.
 
1700
  */
 
1701
 
 
1702
  if ((pkt_length=cli_safe_read(drizzle)) == packet_error)
 
1703
  {
 
1704
    if (drizzle->net.last_errno == CR_SERVER_LOST)
 
1705
      set_drizzle_extended_error(drizzle, CR_SERVER_LOST, unknown_sqlstate,
 
1706
                               ER(CR_SERVER_LOST_EXTENDED),
 
1707
                               "reading authorization packet",
 
1708
                               errno);
 
1709
    goto error;
 
1710
  }
 
1711
 
 
1712
  if (client_flag & CLIENT_COMPRESS)    /* We will use compression */
 
1713
    net->compress=1;
 
1714
 
 
1715
 
 
1716
  if (db && drizzle_select_db(drizzle, db))
 
1717
  {
 
1718
    if (drizzle->net.last_errno == CR_SERVER_LOST)
 
1719
        set_drizzle_extended_error(drizzle, CR_SERVER_LOST, unknown_sqlstate,
 
1720
                                 ER(CR_SERVER_LOST_EXTENDED),
 
1721
                                 "Setting intital database",
 
1722
                                 errno);
 
1723
    goto error;
 
1724
  }
 
1725
 
 
1726
  if (drizzle->options.init_commands)
 
1727
  {
 
1728
    DYNAMIC_ARRAY *init_commands= drizzle->options.init_commands;
 
1729
    char **ptr= (char**)init_commands->buffer;
 
1730
    char **end_command= ptr + init_commands->elements;
 
1731
 
 
1732
    my_bool reconnect=drizzle->reconnect;
 
1733
    drizzle->reconnect=0;
 
1734
 
 
1735
    for (; ptr < end_command; ptr++)
 
1736
    {
 
1737
      DRIZZLE_RES *res;
 
1738
      if (drizzle_real_query(drizzle,*ptr, (ulong) strlen(*ptr)))
 
1739
  goto error;
 
1740
      if (drizzle->fields)
 
1741
      {
 
1742
  if (!(res= cli_use_result(drizzle)))
 
1743
    goto error;
 
1744
  drizzle_free_result(res);
 
1745
      }
 
1746
    }
 
1747
    drizzle->reconnect=reconnect;
 
1748
  }
 
1749
 
 
1750
  reset_sigpipe(drizzle);
 
1751
  return(drizzle);
 
1752
 
 
1753
error:
 
1754
  reset_sigpipe(drizzle);
 
1755
  {
 
1756
    /* Free alloced memory */
 
1757
    end_server(drizzle);
 
1758
    drizzle_close_free(drizzle);
 
1759
    if (!(((ulong) client_flag) & CLIENT_REMEMBER_OPTIONS))
 
1760
      drizzle_close_free_options(drizzle);
 
1761
  }
 
1762
  return(0);
 
1763
}
 
1764
 
 
1765
 
 
1766
my_bool drizzle_reconnect(DRIZZLE *drizzle)
 
1767
{
 
1768
  DRIZZLE tmp_drizzle;
 
1769
  assert(drizzle);
 
1770
 
 
1771
  if (!drizzle->reconnect ||
 
1772
      (drizzle->server_status & SERVER_STATUS_IN_TRANS) || !drizzle->host_info)
 
1773
  {
 
1774
    /* Allow reconnect next time */
 
1775
    drizzle->server_status&= ~SERVER_STATUS_IN_TRANS;
 
1776
    set_drizzle_error(drizzle, CR_SERVER_GONE_ERROR, unknown_sqlstate);
 
1777
    return(1);
 
1778
  }
 
1779
  drizzle_create(&tmp_drizzle);
 
1780
  tmp_drizzle.options= drizzle->options;
 
1781
  tmp_drizzle.options.my_cnf_file= tmp_drizzle.options.my_cnf_group= 0;
 
1782
 
 
1783
  if (!drizzle_connect(&tmp_drizzle,drizzle->host,drizzle->user,drizzle->passwd,
 
1784
        drizzle->db, drizzle->port, drizzle->unix_socket,
 
1785
        drizzle->client_flag | CLIENT_REMEMBER_OPTIONS))
 
1786
  {
 
1787
    drizzle->net.last_errno= tmp_drizzle.net.last_errno;
 
1788
    strmov(drizzle->net.last_error, tmp_drizzle.net.last_error);
 
1789
    strmov(drizzle->net.sqlstate, tmp_drizzle.net.sqlstate);
 
1790
    return(1);
 
1791
  }
 
1792
  if (drizzle_set_character_set(&tmp_drizzle, drizzle->charset->csname))
 
1793
  {
 
1794
    bzero((char*) &tmp_drizzle.options,sizeof(tmp_drizzle.options));
 
1795
    drizzle_close(&tmp_drizzle);
 
1796
    drizzle->net.last_errno= tmp_drizzle.net.last_errno;
 
1797
    strmov(drizzle->net.last_error, tmp_drizzle.net.last_error);
 
1798
    strmov(drizzle->net.sqlstate, tmp_drizzle.net.sqlstate);
 
1799
    return(1);
 
1800
  }
 
1801
 
 
1802
  tmp_drizzle.reconnect= 1;
 
1803
  tmp_drizzle.free_me= drizzle->free_me;
 
1804
 
 
1805
  /* Don't free options as these are now used in tmp_drizzle */
 
1806
  bzero((char*) &drizzle->options,sizeof(drizzle->options));
 
1807
  drizzle->free_me=0;
 
1808
  drizzle_close(drizzle);
 
1809
  *drizzle=tmp_drizzle;
 
1810
  net_clear(&drizzle->net, 1);
 
1811
  drizzle->affected_rows= ~(uint64_t) 0;
 
1812
  return(0);
 
1813
}
 
1814
 
 
1815
 
 
1816
/**************************************************************************
 
1817
  Set current database
 
1818
**************************************************************************/
 
1819
 
 
1820
int STDCALL
 
1821
drizzle_select_db(DRIZZLE *drizzle, const char *db)
 
1822
{
 
1823
  int error;
 
1824
 
 
1825
  if ((error=simple_command(drizzle,COM_INIT_DB, (const uchar*) db,
 
1826
                            (ulong) strlen(db),0)))
 
1827
    return(error);
 
1828
  my_free(drizzle->db,MYF(MY_ALLOW_ZERO_PTR));
 
1829
  drizzle->db=my_strdup(db,MYF(MY_WME));
 
1830
  return(0);
 
1831
}
 
1832
 
 
1833
 
 
1834
/*************************************************************************
 
1835
  Send a QUIT to the server and close the connection
 
1836
  If handle is alloced by DRIZZLE connect free it.
 
1837
*************************************************************************/
 
1838
 
 
1839
static void drizzle_close_free_options(DRIZZLE *drizzle)
 
1840
{
 
1841
  my_free(drizzle->options.user,MYF(MY_ALLOW_ZERO_PTR));
 
1842
  my_free(drizzle->options.host,MYF(MY_ALLOW_ZERO_PTR));
 
1843
  my_free(drizzle->options.password,MYF(MY_ALLOW_ZERO_PTR));
 
1844
  my_free(drizzle->options.unix_socket,MYF(MY_ALLOW_ZERO_PTR));
 
1845
  my_free(drizzle->options.db,MYF(MY_ALLOW_ZERO_PTR));
 
1846
  my_free(drizzle->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
 
1847
  my_free(drizzle->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
 
1848
  my_free(drizzle->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR));
 
1849
  my_free(drizzle->options.charset_name,MYF(MY_ALLOW_ZERO_PTR));
 
1850
  my_free(drizzle->options.client_ip,MYF(MY_ALLOW_ZERO_PTR));
 
1851
  if (drizzle->options.init_commands)
 
1852
  {
 
1853
    DYNAMIC_ARRAY *init_commands= drizzle->options.init_commands;
 
1854
    char **ptr= (char**)init_commands->buffer;
 
1855
    char **end= ptr + init_commands->elements;
 
1856
    for (; ptr<end; ptr++)
 
1857
      my_free(*ptr,MYF(MY_WME));
 
1858
    delete_dynamic(init_commands);
 
1859
    my_free((char*)init_commands,MYF(MY_WME));
 
1860
  }
 
1861
#ifdef HAVE_SMEM
 
1862
  if (drizzle->options.shared_memory_base_name != def_shared_memory_base_name)
 
1863
    my_free(drizzle->options.shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
 
1864
#endif /* HAVE_SMEM */
 
1865
  bzero((char*) &drizzle->options,sizeof(drizzle->options));
 
1866
  return;
 
1867
}
 
1868
 
 
1869
 
 
1870
static void drizzle_close_free(DRIZZLE *drizzle)
 
1871
{
 
1872
  my_free((uchar*) drizzle->host_info,MYF(MY_ALLOW_ZERO_PTR));
 
1873
  my_free(drizzle->user,MYF(MY_ALLOW_ZERO_PTR));
 
1874
  my_free(drizzle->passwd,MYF(MY_ALLOW_ZERO_PTR));
 
1875
  my_free(drizzle->db,MYF(MY_ALLOW_ZERO_PTR));
 
1876
  my_free(drizzle->info_buffer,MYF(MY_ALLOW_ZERO_PTR));
 
1877
  drizzle->info_buffer= 0;
 
1878
 
 
1879
  /* Clear pointers for better safety */
 
1880
  drizzle->host_info= drizzle->user= drizzle->passwd= drizzle->db= 0;
 
1881
}
 
1882
 
 
1883
 
 
1884
void STDCALL drizzle_close(DRIZZLE *drizzle)
 
1885
{
 
1886
  if (drizzle)          /* Some simple safety */
 
1887
  {
 
1888
    /* If connection is still up, send a QUIT message */
 
1889
    if (drizzle->net.vio != 0)
 
1890
    {
 
1891
      free_old_query(drizzle);
 
1892
      drizzle->status=DRIZZLE_STATUS_READY; /* Force command */
 
1893
      drizzle->reconnect=0;
 
1894
      simple_command(drizzle,COM_QUIT,(uchar*) 0,0,1);
 
1895
      end_server(drizzle);      /* Sets drizzle->net.vio= 0 */
 
1896
    }
 
1897
    drizzle_close_free_options(drizzle);
 
1898
    drizzle_close_free(drizzle);
 
1899
    if (drizzle->free_me)
 
1900
      my_free((uchar*) drizzle,MYF(0));
 
1901
  }
 
1902
  return;
 
1903
}
 
1904
 
 
1905
 
 
1906
static bool cli_read_query_result(DRIZZLE *drizzle)
 
1907
{
 
1908
  uchar *pos;
 
1909
  ulong field_count;
 
1910
  DRIZZLE_DATA *fields;
 
1911
  ulong length;
 
1912
 
 
1913
  if ((length = cli_safe_read(drizzle)) == packet_error)
 
1914
    return(1);
 
1915
  free_old_query(drizzle);    /* Free old result */
 
1916
#ifdef MYSQL_CLIENT      /* Avoid warn of unused labels*/
 
1917
get_info:
 
1918
#endif
 
1919
  pos=(uchar*) drizzle->net.read_pos;
 
1920
  if ((field_count= net_field_length(&pos)) == 0)
 
1921
  {
 
1922
    drizzle->affected_rows= net_field_length_ll(&pos);
 
1923
    drizzle->insert_id=    net_field_length_ll(&pos);
 
1924
    if (protocol_41(drizzle))
 
1925
    {
 
1926
      drizzle->server_status=uint2korr(pos); pos+=2;
 
1927
      drizzle->warning_count=uint2korr(pos); pos+=2;
 
1928
    }
 
1929
    else if (drizzle->server_capabilities & CLIENT_TRANSACTIONS)
 
1930
    {
 
1931
      /* DRIZZLE 4.0 protocol */
 
1932
      drizzle->server_status=uint2korr(pos); pos+=2;
 
1933
      drizzle->warning_count= 0;
 
1934
    }
 
1935
    if (pos < drizzle->net.read_pos+length && net_field_length(&pos))
 
1936
      drizzle->info=(char*) pos;
 
1937
    return(0);
 
1938
  }
 
1939
#ifdef MYSQL_CLIENT
 
1940
  if (field_count == NULL_LENGTH)    /* LOAD DATA LOCAL INFILE */
 
1941
  {
 
1942
    int error;
 
1943
 
 
1944
    if (!(drizzle->options.client_flag & CLIENT_LOCAL_FILES))
 
1945
    {
 
1946
      set_drizzle_error(drizzle, CR_MALFORMED_PACKET, unknown_sqlstate);
 
1947
      return(1);
 
1948
    }  
 
1949
 
 
1950
    error= handle_local_infile(drizzle,(char*) pos);
 
1951
    if ((length= cli_safe_read(drizzle)) == packet_error || error)
 
1952
      return(1);
 
1953
    goto get_info;        /* Get info packet */
 
1954
  }
 
1955
#endif
 
1956
  if (!(drizzle->server_status & SERVER_STATUS_AUTOCOMMIT))
 
1957
    drizzle->server_status|= SERVER_STATUS_IN_TRANS;
 
1958
 
 
1959
  if (!(fields=cli_read_rows(drizzle,(DRIZZLE_FIELD*)0, protocol_41(drizzle) ? 7:5)))
 
1960
    return(1);
 
1961
  if (!(drizzle->fields=unpack_fields(fields,&drizzle->field_alloc,
 
1962
            (uint) field_count,0,
 
1963
            drizzle->server_capabilities)))
 
1964
    return(1);
 
1965
  drizzle->status= DRIZZLE_STATUS_GET_RESULT;
 
1966
  drizzle->field_count= (uint) field_count;
 
1967
  return(0);
 
1968
}
 
1969
 
 
1970
 
 
1971
/*
 
1972
  Send the query and return so we can do something else.
 
1973
  Needs to be followed by drizzle_read_query_result() when we want to
 
1974
  finish processing it.
 
1975
*/
 
1976
 
 
1977
int32_t STDCALL
 
1978
drizzle_send_query(DRIZZLE *drizzle, const char* query, uint32_t length)
 
1979
{
 
1980
  return(simple_command(drizzle, COM_QUERY, (uchar*) query, length, 1));
 
1981
}
 
1982
 
 
1983
 
 
1984
int32_t STDCALL
 
1985
drizzle_real_query(DRIZZLE *drizzle, const char *query, uint32_t length)
 
1986
{
 
1987
  if (drizzle_send_query(drizzle,query,length))
 
1988
    return(1);
 
1989
  return((int) (*drizzle->methods->read_query_result)(drizzle));
 
1990
}
 
1991
 
 
1992
 
 
1993
/**************************************************************************
 
1994
  Alloc result struct for buffered results. All rows are read to buffer.
 
1995
  drizzle_data_seek may be used.
 
1996
**************************************************************************/
 
1997
 
 
1998
DRIZZLE_RES * STDCALL drizzle_store_result(DRIZZLE *drizzle)
 
1999
{
 
2000
  DRIZZLE_RES *result;
 
2001
 
 
2002
  if (!drizzle->fields)
 
2003
    return(0);
 
2004
  if (drizzle->status != DRIZZLE_STATUS_GET_RESULT)
 
2005
  {
 
2006
    set_drizzle_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
 
2007
    return(0);
 
2008
  }
 
2009
  drizzle->status=DRIZZLE_STATUS_READY;    /* server is ready */
 
2010
  if (!(result=(DRIZZLE_RES*) my_malloc((uint) (sizeof(DRIZZLE_RES)+
 
2011
                sizeof(ulong) *
 
2012
                drizzle->field_count),
 
2013
              MYF(MY_WME | MY_ZEROFILL))))
 
2014
  {
 
2015
    set_drizzle_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
 
2016
    return(0);
 
2017
  }
 
2018
  result->methods= drizzle->methods;
 
2019
  result->eof= 1;        /* Marker for buffered */
 
2020
  result->lengths= (uint32_t*) (result+1);
 
2021
  if (!(result->data=
 
2022
  (*drizzle->methods->read_rows)(drizzle,drizzle->fields,drizzle->field_count)))
 
2023
  {
 
2024
    my_free((uchar*) result,MYF(0));
 
2025
    return(0);
 
2026
  }
 
2027
  drizzle->affected_rows= result->row_count= result->data->rows;
 
2028
  result->data_cursor=  result->data->data;
 
2029
  result->fields=  drizzle->fields;
 
2030
  result->field_alloc=  drizzle->field_alloc;
 
2031
  result->field_count=  drizzle->field_count;
 
2032
  /* The rest of result members is bzeroed in malloc */
 
2033
  drizzle->fields=0;        /* fields is now in result */
 
2034
  clear_alloc_root(&drizzle->field_alloc);
 
2035
  /* just in case this was mistakenly called after drizzle_stmt_execute() */
 
2036
  drizzle->unbuffered_fetch_owner= 0;
 
2037
  return(result);        /* Data fetched */
 
2038
}
 
2039
 
 
2040
 
 
2041
/**************************************************************************
 
2042
  Alloc struct for use with unbuffered reads. Data is fetched by domand
 
2043
  when calling to drizzle_fetch_row.
 
2044
  DRIZZLE_DATA_seek is a noop.
 
2045
 
 
2046
  No other queries may be specified with the same DRIZZLE handle.
 
2047
  There shouldn't be much processing per row because DRIZZLE server shouldn't
 
2048
  have to wait for the client (and will not wait more than 30 sec/packet).
 
2049
**************************************************************************/
 
2050
 
 
2051
static DRIZZLE_RES * cli_use_result(DRIZZLE *drizzle)
 
2052
{
 
2053
  DRIZZLE_RES *result;
 
2054
 
 
2055
  if (!drizzle->fields)
 
2056
    return(0);
 
2057
  if (drizzle->status != DRIZZLE_STATUS_GET_RESULT)
 
2058
  {
 
2059
    set_drizzle_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
 
2060
    return(0);
 
2061
  }
 
2062
  if (!(result=(DRIZZLE_RES*) my_malloc(sizeof(*result)+
 
2063
              sizeof(ulong)*drizzle->field_count,
 
2064
              MYF(MY_WME | MY_ZEROFILL))))
 
2065
    return(0);
 
2066
  result->lengths=(uint32_t*) (result+1);
 
2067
  result->methods= drizzle->methods;
 
2068
  if (!(result->row=(DRIZZLE_ROW)
 
2069
  my_malloc(sizeof(result->row[0])*(drizzle->field_count+1), MYF(MY_WME))))
 
2070
  {          /* Ptrs: to one row */
 
2071
    my_free((uchar*) result,MYF(0));
 
2072
    return(0);
 
2073
  }
 
2074
  result->fields=  drizzle->fields;
 
2075
  result->field_alloc=  drizzle->field_alloc;
 
2076
  result->field_count=  drizzle->field_count;
 
2077
  result->current_field=0;
 
2078
  result->handle=  drizzle;
 
2079
  result->current_row=  0;
 
2080
  drizzle->fields=0;      /* fields is now in result */
 
2081
  clear_alloc_root(&drizzle->field_alloc);
 
2082
  drizzle->status=DRIZZLE_STATUS_USE_RESULT;
 
2083
  drizzle->unbuffered_fetch_owner= &result->unbuffered_fetch_cancelled;
 
2084
  return(result);      /* Data is read to be fetched */
 
2085
}
 
2086
 
 
2087
 
428
2088
/**************************************************************************
429
2089
  Return next row of the query results
430
2090
**************************************************************************/
431
2091
 
432
 
DRIZZLE_ROW
 
2092
DRIZZLE_ROW STDCALL
433
2093
drizzle_fetch_row(DRIZZLE_RES *res)
434
2094
{
435
2095
  if (!res->data)
439
2099
      DRIZZLE *drizzle= res->handle;
440
2100
      if (drizzle->status != DRIZZLE_STATUS_USE_RESULT)
441
2101
      {
442
 
        drizzle_set_error(drizzle,
443
 
                          res->unbuffered_fetch_cancelled ?
444
 
                          CR_FETCH_CANCELED : CR_COMMANDS_OUT_OF_SYNC,
445
 
                          sqlstate_get_unknown());
 
2102
        set_drizzle_error(drizzle,
 
2103
                        res->unbuffered_fetch_cancelled ?
 
2104
                        CR_FETCH_CANCELED : CR_COMMANDS_OUT_OF_SYNC,
 
2105
                        unknown_sqlstate);
446
2106
      }
447
2107
      else if (!(read_one_row(drizzle, res->field_count, res->row, res->lengths)))
448
2108
      {
481
2141
  else the lengths are calculated from the offset between pointers.
482
2142
**************************************************************************/
483
2143
 
484
 
uint32_t *
 
2144
uint32_t * STDCALL
485
2145
drizzle_fetch_lengths(DRIZZLE_RES *res)
486
2146
{
487
2147
  DRIZZLE_ROW column;
494
2154
}
495
2155
 
496
2156
 
497
 
int
 
2157
int STDCALL
498
2158
drizzle_options(DRIZZLE *drizzle,enum drizzle_option option, const void *arg)
499
2159
{
500
2160
  switch (option) {
501
2161
  case DRIZZLE_OPT_CONNECT_TIMEOUT:
502
 
    drizzle->options.connect_timeout= *(uint32_t*) arg;
 
2162
    drizzle->options.connect_timeout= *(uint*) arg;
503
2163
    break;
504
2164
  case DRIZZLE_OPT_READ_TIMEOUT:
505
 
    drizzle->options.read_timeout= *(uint32_t*) arg;
 
2165
    drizzle->options.read_timeout= *(uint*) arg;
506
2166
    break;
507
2167
  case DRIZZLE_OPT_WRITE_TIMEOUT:
508
 
    drizzle->options.write_timeout= *(uint32_t*) arg;
 
2168
    drizzle->options.write_timeout= *(uint*) arg;
509
2169
    break;
510
2170
  case DRIZZLE_OPT_COMPRESS:
511
2171
    drizzle->options.compress= 1;      /* Remember for connect */
512
2172
    drizzle->options.client_flag|= CLIENT_COMPRESS;
513
2173
    break;
 
2174
  case DRIZZLE_OPT_NAMED_PIPE:      /* This option is depricated */
 
2175
    drizzle->options.protocol=DRIZZLE_PROTOCOL_PIPE; /* Force named pipe */
 
2176
    break;
514
2177
  case DRIZZLE_OPT_LOCAL_INFILE:      /* Allow LOAD DATA LOCAL ?*/
515
 
    if (!arg || (*(uint32_t*) arg) ? 1 : 0)
 
2178
    if (!arg || test(*(uint*) arg))
516
2179
      drizzle->options.client_flag|= CLIENT_LOCAL_FILES;
517
2180
    else
518
2181
      drizzle->options.client_flag&= ~CLIENT_LOCAL_FILES;
519
2182
    break;
 
2183
  case DRIZZLE_INIT_COMMAND:
 
2184
    add_init_command(&drizzle->options,arg);
 
2185
    break;
520
2186
  case DRIZZLE_READ_DEFAULT_FILE:
521
 
    if (drizzle->options.my_cnf_file != NULL)
522
 
      free(drizzle->options.my_cnf_file);
523
 
    drizzle->options.my_cnf_file=strdup(arg);
 
2187
    my_free(drizzle->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
 
2188
    drizzle->options.my_cnf_file=my_strdup(arg,MYF(MY_WME));
524
2189
    break;
525
2190
  case DRIZZLE_READ_DEFAULT_GROUP:
526
 
    if (drizzle->options.my_cnf_group != NULL)
527
 
      free(drizzle->options.my_cnf_group);
528
 
    drizzle->options.my_cnf_group=strdup(arg);
 
2191
    my_free(drizzle->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
 
2192
    drizzle->options.my_cnf_group=my_strdup(arg,MYF(MY_WME));
 
2193
    break;
 
2194
  case DRIZZLE_SET_CHARSET_DIR:
 
2195
    my_free(drizzle->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR));
 
2196
    drizzle->options.charset_dir=my_strdup(arg,MYF(MY_WME));
 
2197
    break;
 
2198
  case DRIZZLE_SET_CHARSET_NAME:
 
2199
    my_free(drizzle->options.charset_name,MYF(MY_ALLOW_ZERO_PTR));
 
2200
    drizzle->options.charset_name=my_strdup(arg,MYF(MY_WME));
529
2201
    break;
530
2202
  case DRIZZLE_OPT_PROTOCOL:
 
2203
    drizzle->options.protocol= *(uint*) arg;
 
2204
    break;
 
2205
  case DRIZZLE_SHARED_MEMORY_BASE_NAME:
 
2206
#ifdef HAVE_SMEM
 
2207
    if (drizzle->options.shared_memory_base_name != def_shared_memory_base_name)
 
2208
      my_free(drizzle->options.shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
 
2209
    drizzle->options.shared_memory_base_name=my_strdup(arg,MYF(MY_WME));
 
2210
#endif
531
2211
    break;
532
2212
  case DRIZZLE_OPT_USE_REMOTE_CONNECTION:
 
2213
  case DRIZZLE_OPT_USE_EMBEDDED_CONNECTION:
533
2214
  case DRIZZLE_OPT_GUESS_CONNECTION:
534
2215
    drizzle->options.methods_to_use= option;
535
2216
    break;
536
2217
  case DRIZZLE_SET_CLIENT_IP:
537
 
    drizzle->options.client_ip= strdup(arg);
 
2218
    drizzle->options.client_ip= my_strdup(arg, MYF(MY_WME));
538
2219
    break;
539
2220
  case DRIZZLE_SECURE_AUTH:
540
 
    drizzle->options.secure_auth= *(const bool *) arg;
 
2221
    drizzle->options.secure_auth= *(my_bool *) arg;
541
2222
    break;
542
2223
  case DRIZZLE_REPORT_DATA_TRUNCATION:
543
 
    drizzle->options.report_data_truncation= (*(const bool *) arg) ? 1 : 0;
 
2224
    drizzle->options.report_data_truncation= test(*(my_bool *) arg);
544
2225
    break;
545
2226
  case DRIZZLE_OPT_RECONNECT:
546
 
    drizzle->reconnect= *(const bool *) arg;
 
2227
    drizzle->reconnect= *(my_bool *) arg;
547
2228
    break;
548
2229
  case DRIZZLE_OPT_SSL_VERIFY_SERVER_CERT:
549
 
    if (*(const bool*) arg)
 
2230
    if (*(my_bool*) arg)
550
2231
      drizzle->options.client_flag|= CLIENT_SSL_VERIFY_SERVER_CERT;
551
2232
    else
552
2233
      drizzle->options.client_flag&= ~CLIENT_SSL_VERIFY_SERVER_CERT;
564
2245
****************************************************************************/
565
2246
 
566
2247
/* DRIZZLE_RES */
567
 
uint64_t drizzle_num_rows(const DRIZZLE_RES *res)
 
2248
uint64_t STDCALL drizzle_num_rows(DRIZZLE_RES *res)
568
2249
{
569
2250
  return res->row_count;
570
2251
}
571
2252
 
572
 
unsigned int drizzle_num_fields(const DRIZZLE_RES *res)
 
2253
unsigned int STDCALL drizzle_num_fields(DRIZZLE_RES *res)
573
2254
{
574
2255
  return res->field_count;
575
2256
}
576
2257
 
 
2258
uint STDCALL drizzle_errno(DRIZZLE *drizzle)
 
2259
{
 
2260
  return drizzle ? drizzle->net.last_errno : drizzle_server_last_errno;
 
2261
}
 
2262
 
 
2263
 
 
2264
const char * STDCALL drizzle_error(DRIZZLE *drizzle)
 
2265
{
 
2266
  return drizzle ? drizzle->net.last_error : drizzle_server_last_error;
 
2267
}
 
2268
 
577
2269
 
578
2270
/*
579
2271
  Get version number for server in a form easy to test on
584
2276
 
585
2277
  EXAMPLE
586
2278
    4.1.0-alfa ->  40100
587
 
 
 
2279
 
588
2280
  NOTES
589
2281
    We will ensure that a newer server always has a bigger number.
590
2282
 
592
2284
   Signed number > 323000
593
2285
*/
594
2286
 
595
 
uint32_t
596
 
drizzle_get_server_version(const DRIZZLE *drizzle)
 
2287
uint32_t STDCALL
 
2288
drizzle_get_server_version(DRIZZLE *drizzle)
597
2289
{
598
 
  uint32_t major, minor, version;
 
2290
  uint major, minor, version;
599
2291
  char *pos= drizzle->server_version, *end_pos;
600
 
  major=   (uint32_t) strtoul(pos, &end_pos, 10);  pos=end_pos+1;
601
 
  minor=   (uint32_t) strtoul(pos, &end_pos, 10);  pos=end_pos+1;
602
 
  version= (uint32_t) strtoul(pos, &end_pos, 10);
603
 
  return (uint32_t) major*10000L+(uint32_t) (minor*100+version);
604
 
}
 
2292
  major=   (uint) strtoul(pos, &end_pos, 10);  pos=end_pos+1;
 
2293
  minor=   (uint) strtoul(pos, &end_pos, 10);  pos=end_pos+1;
 
2294
  version= (uint) strtoul(pos, &end_pos, 10);
 
2295
  return (ulong) major*10000L+(ulong) (minor*100+version);
 
2296
}
 
2297
 
 
2298
 
 
2299
/*
 
2300
   drizzle_set_character_set function sends SET NAMES cs_name to
 
2301
   the server (which changes character_set_client, character_set_result
 
2302
   and character_set_connection) and updates drizzle->charset so other
 
2303
   functions like drizzle_real_escape will work correctly.
 
2304
*/
 
2305
int STDCALL drizzle_set_character_set(DRIZZLE *drizzle, const char *cs_name)
 
2306
{
 
2307
  struct charset_info_st *cs;
 
2308
  const char *save_csdir= charsets_dir;
 
2309
 
 
2310
  if (drizzle->options.charset_dir)
 
2311
    charsets_dir= drizzle->options.charset_dir;
 
2312
 
 
2313
  if (strlen(cs_name) < MY_CS_NAME_SIZE &&
 
2314
     (cs= get_charset_by_csname(cs_name, MY_CS_PRIMARY, MYF(0))))
 
2315
  {
 
2316
    char buff[MY_CS_NAME_SIZE + 10];
 
2317
    charsets_dir= save_csdir;
 
2318
    /* Skip execution of "SET NAMES" for pre-4.1 servers */
 
2319
    if (drizzle_get_server_version(drizzle) < 40100)
 
2320
      return 0;
 
2321
    sprintf(buff, "SET NAMES %s", cs_name);
 
2322
    if (!drizzle_real_query(drizzle, buff, strlen(buff)))
 
2323
    {
 
2324
      drizzle->charset= cs;
 
2325
    }
 
2326
  }
 
2327
  else
 
2328
  {
 
2329
    char cs_dir_name[FN_REFLEN];
 
2330
    get_charsets_dir(cs_dir_name);
 
2331
    set_drizzle_extended_error(drizzle, CR_CANT_READ_CHARSET, unknown_sqlstate,
 
2332
                             ER(CR_CANT_READ_CHARSET), cs_name, cs_dir_name);
 
2333
  }
 
2334
  charsets_dir= save_csdir;
 
2335
  return drizzle->net.last_errno;
 
2336
}
 
2337
 
605
2338