~drizzle-trunk/drizzle/development

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