~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzle/libdrizzle.c

Removed/replaced DBUG symbols and standardized TRUE/FALSE

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems, Inc.
5
 
 *
6
 
 *  This program is free software; you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation; version 2 of the License.
9
 
 *
10
 
 *  This program is distributed in the hope that it will be useful,
11
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 *  GNU General Public License for more details.
14
 
 *
15
 
 *  You should have received a copy of the GNU General Public License
16
 
 *  along with this program; if not, write to the Free Software
17
 
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 
 */
19
 
 
20
 
#include "libdrizzle.h"
21
 
#include "libdrizzle_priv.h"
 
1
/* Copyright (C) 2000-2004 MySQL AB
 
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.
 
6
 
 
7
   There are special exceptions to the terms and conditions of the GPL as it
 
8
   is applied to this software. View the full text of the exception in file
 
9
   EXCEPTIONS-CLIENT in the directory of this software distribution.
 
10
 
 
11
   This program is distributed in the hope that it will be useful,
 
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
   GNU General Public License for more details.
 
15
 
 
16
   You should have received a copy of the GNU General Public License
 
17
   along with this program; if not, write to the Free Software
 
18
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
19
 
 
20
#include <my_global.h>
 
21
#include <my_sys.h>
 
22
#include <my_time.h>
 
23
#include <mysys_err.h>
 
24
#include <m_string.h>
 
25
#include <m_ctype.h>
 
26
#include "drizzle.h"
 
27
#include "drizzle_version.h"
 
28
#include "mysqld_error.h"
22
29
#include "errmsg.h"
 
30
#include <violite.h>
23
31
#include <sys/stat.h>
24
32
#include <signal.h>
25
33
#include <time.h>
26
 
#ifdef   HAVE_PWD_H
 
34
#ifdef   HAVE_PWD_H
27
35
#include <pwd.h>
28
36
#endif
29
37
 
44
52
#ifdef HAVE_SYS_UN_H
45
53
#include <sys/un.h>
46
54
#endif
 
55
#include <my_pthread.h>                         /* because of signal()  */
47
56
#ifndef INADDR_NONE
48
 
#define INADDR_NONE  -1
 
57
#define INADDR_NONE     -1
49
58
#endif
50
59
 
51
 
#include <stdlib.h>
52
 
#include <string.h>
53
 
 
54
60
#include <sql_common.h>
55
 
#include <drizzled/version.h>
56
 
 
57
 
/* Borrowed from libicu header */
58
 
 
59
 
#define U8_IS_SINGLE(c) (((c)&0x80)==0)
60
 
#define U8_LENGTH(c) \
61
 
    ((uint32_t)(c)<=0x7f ? 1 : \
62
 
        ((uint32_t)(c)<=0x7ff ? 2 : \
63
 
            ((uint32_t)(c)<=0xd7ff ? 3 : \
64
 
                ((uint32_t)(c)<=0xdfff || (uint32_t)(c)>0x10ffff ? 0 : \
65
 
                    ((uint32_t)(c)<=0xffff ? 3 : 4)\
66
 
                ) \
67
 
            ) \
68
 
        ) \
69
 
    )
70
 
 
 
61
#include "client_settings.h"
71
62
 
72
63
#undef net_buffer_length
73
64
#undef max_allowed_packet
74
65
 
75
 
uint32_t     net_buffer_length= 8192;
76
 
uint32_t    max_allowed_packet= 1024L*1024L*1024L;
77
 
 
78
 
unsigned int drizzle_port=0;
 
66
ulong           net_buffer_length=8192;
 
67
ulong           max_allowed_packet= 1024L*1024L*1024L;
79
68
 
80
69
#include <errno.h>
81
70
#define SOCKET_ERROR -1
87
76
#define MAX_LONG_DATA_LENGTH 8192
88
77
#define unsigned_field(A) ((A)->flags & UNSIGNED_FLAG)
89
78
 
90
 
 
91
 
static DRIZZLE_PARAMETERS drizzle_internal_parameters=
 
79
static void append_wild(char *to,char *end,const char *wild);
 
80
 
 
81
static my_bool mysql_client_init= 0;
 
82
static my_bool org_my_init_done= 0;
 
83
 
 
84
 
 
85
/*
 
86
  Initialize the MySQL client library
 
87
 
 
88
  SYNOPSIS
 
89
    mysql_server_init()
 
90
 
 
91
  NOTES
 
92
    Should be called before doing any other calls to the MySQL
 
93
    client library to initialize thread specific variables etc.
 
94
    It's called by mysql_init() to ensure that things will work for
 
95
    old not threaded applications that doesn't call mysql_server_init()
 
96
    directly.
 
97
 
 
98
  RETURN
 
99
    0  ok
 
100
    1  could not initialize environment (out of memory or thread keys)
 
101
*/
 
102
 
 
103
int STDCALL mysql_server_init(int argc __attribute__((unused)),
 
104
                              char **argv __attribute__((unused)),
 
105
                              char **groups __attribute__((unused)))
 
106
{
 
107
  int result= 0;
 
108
  if (!mysql_client_init)
 
109
  {
 
110
    mysql_client_init=1;
 
111
    org_my_init_done=my_init_done;
 
112
    if (my_init())                              /* Will init threads */
 
113
      return 1;
 
114
    init_client_errs();
 
115
    if (!mysql_port)
 
116
    {
 
117
      mysql_port = MYSQL_PORT;
 
118
      {
 
119
        struct servent *serv_ptr;
 
120
        char    *env;
 
121
 
 
122
        /*
 
123
          if builder specifically requested a default port, use that
 
124
          (even if it coincides with our factory default).
 
125
          only if they didn't do we check /etc/services (and, failing
 
126
          on that, fall back to the factory default of 3306).
 
127
          either default can be overridden by the environment variable
 
128
          MYSQL_TCP_PORT, which in turn can be overridden with command
 
129
          line options.
 
130
        */
 
131
 
 
132
#if MYSQL_PORT_DEFAULT == 0
 
133
        if ((serv_ptr = getservbyname("mysql", "tcp")))
 
134
          mysql_port = (uint) ntohs((ushort) serv_ptr->s_port);
 
135
#endif
 
136
        if ((env = getenv("MYSQL_TCP_PORT")))
 
137
          mysql_port =(uint) atoi(env);
 
138
      }
 
139
    }
 
140
    if (!mysql_unix_port)
 
141
    {
 
142
      char *env;
 
143
      mysql_unix_port = (char*) MYSQL_UNIX_ADDR;
 
144
      if ((env = getenv("MYSQL_UNIX_PORT")))
 
145
        mysql_unix_port = env;
 
146
    }
 
147
    mysql_debug(NullS);
 
148
#if defined(SIGPIPE)
 
149
    (void) signal(SIGPIPE, SIG_IGN);
 
150
#endif
 
151
  }
 
152
  else
 
153
    result= (int)my_thread_init();         /* Init if new thread */
 
154
  return result;
 
155
}
 
156
 
 
157
 
 
158
/*
 
159
  Free all memory and resources used by the client library
 
160
 
 
161
  NOTES
 
162
    When calling this there should not be any other threads using
 
163
    the library.
 
164
 
 
165
    To make things simpler when used with windows dll's (which calls this
 
166
    function automaticly), it's safe to call this function multiple times.
 
167
*/
 
168
 
 
169
 
 
170
void STDCALL mysql_server_end()
 
171
{
 
172
  if (!mysql_client_init)
 
173
    return;
 
174
 
 
175
  finish_client_errs();
 
176
  vio_end();
 
177
 
 
178
  /* If library called my_init(), free memory allocated by it */
 
179
  if (!org_my_init_done)
 
180
  {
 
181
    my_end(MY_DONT_FREE_DBUG);
 
182
    /* Remove TRACING, if enabled by mysql_debug() */
 
183
    DBUG_POP();
 
184
  }
 
185
  else
 
186
  {
 
187
    free_charsets();
 
188
    mysql_thread_end();
 
189
  }
 
190
 
 
191
  mysql_client_init= org_my_init_done= 0;
 
192
#ifdef EMBEDDED_SERVER
 
193
  if (stderror_file)
 
194
  {
 
195
    fclose(stderror_file);
 
196
    stderror_file= 0;
 
197
  }
 
198
#endif
 
199
}
 
200
 
 
201
static MYSQL_PARAMETERS mysql_internal_parameters=
92
202
{&max_allowed_packet, &net_buffer_length, 0};
93
203
 
94
 
const DRIZZLE_PARAMETERS * drizzle_get_parameters(void)
95
 
{
96
 
  return &drizzle_internal_parameters;
97
 
}
98
 
 
99
 
unsigned int drizzle_get_default_port(void)
100
 
{
101
 
  return drizzle_port;
102
 
}
103
 
 
104
 
void drizzle_set_default_port(unsigned int port)
105
 
{
106
 
  drizzle_port= port;
107
 
}
 
204
MYSQL_PARAMETERS *STDCALL mysql_get_parameters(void)
 
205
{
 
206
  return &mysql_internal_parameters;
 
207
}
 
208
 
 
209
my_bool STDCALL mysql_thread_init()
 
210
{
 
211
  return my_thread_init();
 
212
}
 
213
 
 
214
void STDCALL mysql_thread_end()
 
215
{
 
216
  my_thread_end();
 
217
}
 
218
 
108
219
 
109
220
/*
110
221
  Expand wildcard to a sql string
113
224
static void
114
225
append_wild(char *to, char *end, const char *wild)
115
226
{
116
 
  end-=5;          /* Some extra */
 
227
  end-=5;                                       /* Some extra */
117
228
  if (wild && wild[0])
118
229
  {
119
 
    to= strcpy(to," like '");
120
 
    to+= 7; /* strlen(" like '"); */
121
 
 
 
230
    to=strmov(to," like '");
122
231
    while (*wild && to < end)
123
232
    {
124
233
      if (*wild == '\\' || *wild == '\'')
125
 
  *to++='\\';
 
234
        *to++='\\';
126
235
      *to++= *wild++;
127
236
    }
128
 
    if (*wild)          /* Too small buffer */
129
 
      *to++='%';        /* Nicer this way */
 
237
    if (*wild)                                  /* Too small buffer */
 
238
      *to++='%';                                /* Nicer this way */
130
239
    to[0]='\'';
131
240
    to[1]=0;
132
241
  }
133
242
}
134
243
 
 
244
 
 
245
/**************************************************************************
 
246
  Init debugging if MYSQL_DEBUG environment variable is found
 
247
**************************************************************************/
 
248
 
 
249
void STDCALL
 
250
mysql_debug(const char *debug __attribute__((unused)))
 
251
{
 
252
#ifndef DBUG_OFF
 
253
  char  *env;
 
254
  if (debug)
 
255
  {
 
256
    DBUG_PUSH(debug);
 
257
  }
 
258
  else if ((env = getenv("MYSQL_DEBUG")))
 
259
  {
 
260
    DBUG_PUSH(env);
 
261
#if !defined(_WINVER) && !defined(WINVER)
 
262
    puts("\n-------------------------------------------------------");
 
263
    puts("MYSQL_DEBUG found. libmysql started with the following:");
 
264
    puts(env);
 
265
    puts("-------------------------------------------------------\n");
 
266
#else
 
267
    {
 
268
      char buff[80];
 
269
      buff[sizeof(buff)-1]= 0;
 
270
      strxnmov(buff,sizeof(buff)-1,"libmysql: ", env, NullS);
 
271
      MessageBox((HWND) 0,"Debugging variable MYSQL_DEBUG used",buff,MB_OK);
 
272
    }
 
273
#endif
 
274
  }
 
275
#endif
 
276
}
 
277
 
 
278
 
 
279
/**************************************************************************
 
280
  Ignore SIGPIPE handler
 
281
   ARGSUSED
 
282
**************************************************************************/
 
283
 
 
284
sig_handler
 
285
my_pipe_sig_handler(int sig __attribute__((unused)))
 
286
{
 
287
  DBUG_PRINT("info",("Hit by signal %d",sig));
 
288
#ifdef DONT_REMEMBER_SIGNAL
 
289
  (void) signal(SIGPIPE, my_pipe_sig_handler);
 
290
#endif
 
291
}
 
292
 
 
293
 
 
294
/**************************************************************************
 
295
  Connect to sql server
 
296
  If host == 0 then use localhost
 
297
**************************************************************************/
 
298
 
 
299
#ifdef USE_OLD_FUNCTIONS
 
300
MYSQL * STDCALL
 
301
mysql_connect(MYSQL *mysql,const char *host,
 
302
              const char *user, const char *passwd)
 
303
{
 
304
  MYSQL *res;
 
305
  mysql=mysql_init(mysql);                      /* Make it thread safe */
 
306
  {
 
307
    DBUG_ENTER("mysql_connect");
 
308
    if (!(res=mysql_real_connect(mysql,host,user,passwd,NullS,0,NullS,0)))
 
309
    {
 
310
      if (mysql->free_me)
 
311
        my_free((uchar*) mysql,MYF(0));
 
312
    }
 
313
    mysql->reconnect= 1;
 
314
    DBUG_RETURN(res);
 
315
  }
 
316
}
 
317
#endif
 
318
 
 
319
 
135
320
/**************************************************************************
136
321
  Change user and database
137
322
**************************************************************************/
138
323
 
139
 
int cli_read_change_user_result(DRIZZLE *drizzle)
 
324
int cli_read_change_user_result(MYSQL *mysql, char *buff, const char *passwd)
140
325
{
141
 
  uint32_t pkt_length;
 
326
  NET *net= &mysql->net;
 
327
  ulong pkt_length;
142
328
 
143
 
  pkt_length= cli_safe_read(drizzle);
 
329
  pkt_length= cli_safe_read(mysql);
144
330
  
145
331
  if (pkt_length == packet_error)
146
332
    return 1;
147
333
 
 
334
  if (pkt_length == 1 && net->read_pos[0] == 254 &&
 
335
      mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
 
336
  {
 
337
    /*
 
338
      By sending this very specific reply server asks us to send scrambled
 
339
      password in old format. The reply contains scramble_323.
 
340
    */
 
341
    scramble_323(buff, mysql->scramble, passwd);
 
342
    if (my_net_write(net, (uchar*) buff, SCRAMBLE_LENGTH_323 + 1) ||
 
343
        net_flush(net))
 
344
    {
 
345
      set_mysql_error(mysql, CR_SERVER_LOST, unknown_sqlstate);
 
346
      return 1;
 
347
    }
 
348
    /* Read what server thinks about out new auth message report */
 
349
    if (cli_safe_read(mysql) == packet_error)
 
350
      return 1;
 
351
  }
148
352
  return 0;
149
353
}
150
354
 
151
 
bool drizzle_change_user(DRIZZLE *drizzle, const char *user,
152
 
                                 const char *passwd, const char *db)
 
355
my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
 
356
                                  const char *passwd, const char *db)
153
357
{
154
358
  char buff[USERNAME_LENGTH+SCRAMBLED_PASSWORD_CHAR_LENGTH+NAME_LEN+2];
155
359
  char *end= buff;
156
360
  int rc;
 
361
  CHARSET_INFO *saved_cs= mysql->charset;
 
362
 
 
363
  DBUG_ENTER("mysql_change_user");
 
364
 
 
365
  /* Get the connection-default character set. */
 
366
 
 
367
  if (mysql_init_character_set(mysql))
 
368
  {
 
369
    mysql->charset= saved_cs;
 
370
    DBUG_RETURN(TRUE);
 
371
  }
157
372
 
158
373
  /* Use an empty string instead of NULL. */
159
374
 
163
378
    passwd="";
164
379
 
165
380
  /* Store user into the buffer */
166
 
  end= strncpy(end, user, USERNAME_LENGTH) + USERNAME_LENGTH + 1;
 
381
  end= strmake(end, user, USERNAME_LENGTH) + 1;
167
382
 
168
383
  /* write scrambled password according to server capabilities */
169
384
  if (passwd[0])
170
385
  {
 
386
    if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
171
387
    {
172
388
      *end++= SCRAMBLE_LENGTH;
 
389
      scramble(end, mysql->scramble, passwd);
173
390
      end+= SCRAMBLE_LENGTH;
174
391
    }
 
392
    else
 
393
    {
 
394
      scramble_323(end, mysql->scramble, passwd);
 
395
      end+= SCRAMBLE_LENGTH_323 + 1;
 
396
    }
175
397
  }
176
398
  else
177
399
    *end++= '\0';                               /* empty password */
178
400
  /* Add database if needed */
179
 
  end= strncpy(end, db ? db : "", NAME_LEN) + NAME_LEN + 1;
 
401
  end= strmake(end, db ? db : "", NAME_LEN) + 1;
180
402
 
181
403
  /* Add character set number. */
182
 
  if (drizzle->server_capabilities & CLIENT_SECURE_CONNECTION)
 
404
 
 
405
  if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
183
406
  {
184
 
    int2store(end, (uint16_t) 45); // utf8mb4 number from mystrings/ctype-utf8.c
 
407
    int2store(end, (ushort) mysql->charset->number);
185
408
    end+= 2;
186
409
  }
187
410
 
188
411
  /* Write authentication package */
189
 
  (void)simple_command(drizzle,COM_CHANGE_USER, (unsigned char*) buff, (uint32_t) (end-buff), 1);
 
412
  simple_command(mysql,COM_CHANGE_USER, (uchar*) buff, (ulong) (end-buff), 1);
190
413
 
191
 
  rc= (*drizzle->methods->read_change_user_result)(drizzle);
 
414
  rc= (*mysql->methods->read_change_user_result)(mysql, buff, passwd);
192
415
 
193
416
  if (rc == 0)
194
417
  {
195
418
    /* Free old connect information */
196
 
    if(drizzle->user)
197
 
      free(drizzle->user);
198
 
    if(drizzle->passwd)
199
 
      free(drizzle->passwd);
200
 
    if(drizzle->db)
201
 
      free(drizzle->db);
 
419
    my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR));
 
420
    my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR));
 
421
    my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
202
422
 
203
423
    /* alloc new connect information */
204
 
    drizzle->user= strdup(user);
205
 
    drizzle->passwd= strdup(passwd);
206
 
    drizzle->db= db ? strdup(db) : 0;
 
424
    mysql->user=  my_strdup(user,MYF(MY_WME));
 
425
    mysql->passwd=my_strdup(passwd,MYF(MY_WME));
 
426
    mysql->db=    db ? my_strdup(db,MYF(MY_WME)) : 0;
 
427
  }
 
428
  else
 
429
  {
 
430
    mysql->charset= saved_cs;
207
431
  }
208
432
 
209
 
  return(rc);
 
433
  DBUG_RETURN(rc);
210
434
}
211
435
 
212
436
#if defined(HAVE_GETPWUID) && defined(NO_GETPWUID_DECL)
214
438
char* getlogin(void);
215
439
#endif
216
440
 
 
441
void read_user_name(char *name)
 
442
{
 
443
  DBUG_ENTER("read_user_name");
 
444
  if (geteuid() == 0)
 
445
    (void) strmov(name,"root");         /* allow use of surun */
 
446
  else
 
447
  {
 
448
#ifdef HAVE_GETPWUID
 
449
    struct passwd *skr;
 
450
    const char *str;
 
451
    if ((str=getlogin()) == NULL)
 
452
    {
 
453
      if ((skr=getpwuid(geteuid())) != NULL)
 
454
        str=skr->pw_name;
 
455
      else if (!(str=getenv("USER")) && !(str=getenv("LOGNAME")) &&
 
456
               !(str=getenv("LOGIN")))
 
457
        str="UNKNOWN_USER";
 
458
    }
 
459
    (void) strmake(name,str,USERNAME_LENGTH);
 
460
#elif HAVE_CUSERID
 
461
    (void) cuserid(name);
 
462
#else
 
463
    strmov(name,"UNKNOWN_USER");
 
464
#endif
 
465
  }
 
466
  DBUG_VOID_RETURN;
 
467
}
 
468
 
 
469
my_bool handle_local_infile(MYSQL *mysql, const char *net_filename)
 
470
{
 
471
  my_bool result= 1;
 
472
  uint packet_length=MY_ALIGN(mysql->net.max_packet-16,IO_SIZE);
 
473
  NET *net= &mysql->net;
 
474
  int readcount;
 
475
  void *li_ptr;          /* pass state to local_infile functions */
 
476
  char *buf;            /* buffer to be filled by local_infile_read */
 
477
  struct st_mysql_options *options= &mysql->options;
 
478
  DBUG_ENTER("handle_local_infile");
 
479
 
 
480
  /* check that we've got valid callback functions */
 
481
  if (!(options->local_infile_init &&
 
482
        options->local_infile_read &&
 
483
        options->local_infile_end &&
 
484
        options->local_infile_error))
 
485
  {
 
486
    /* if any of the functions is invalid, set the default */
 
487
    mysql_set_local_infile_default(mysql);
 
488
  }
 
489
 
 
490
  /* copy filename into local memory and allocate read buffer */
 
491
  if (!(buf=my_malloc(packet_length, MYF(0))))
 
492
  {
 
493
    set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
 
494
    DBUG_RETURN(1);
 
495
  }
 
496
 
 
497
  /* initialize local infile (open file, usually) */
 
498
  if ((*options->local_infile_init)(&li_ptr, net_filename,
 
499
    options->local_infile_userdata))
 
500
  {
 
501
    VOID(my_net_write(net,(const uchar*) "",0)); /* Server needs one packet */
 
502
    net_flush(net);
 
503
    strmov(net->sqlstate, unknown_sqlstate);
 
504
    net->last_errno=
 
505
      (*options->local_infile_error)(li_ptr,
 
506
                                     net->last_error,
 
507
                                     sizeof(net->last_error)-1);
 
508
    goto err;
 
509
  }
 
510
 
 
511
  /* read blocks of data from local infile callback */
 
512
  while ((readcount =
 
513
          (*options->local_infile_read)(li_ptr, buf,
 
514
                                        packet_length)) > 0)
 
515
  {
 
516
    if (my_net_write(net, (uchar*) buf, readcount))
 
517
    {
 
518
      DBUG_PRINT("error",
 
519
                 ("Lost connection to MySQL server during LOAD DATA of local file"));
 
520
      set_mysql_error(mysql, CR_SERVER_LOST, unknown_sqlstate);
 
521
      goto err;
 
522
    }
 
523
  }
 
524
 
 
525
  /* Send empty packet to mark end of file */
 
526
  if (my_net_write(net, (const uchar*) "", 0) || net_flush(net))
 
527
  {
 
528
    set_mysql_error(mysql, CR_SERVER_LOST, unknown_sqlstate);
 
529
    goto err;
 
530
  }
 
531
 
 
532
  if (readcount < 0)
 
533
  {
 
534
    net->last_errno=
 
535
      (*options->local_infile_error)(li_ptr,
 
536
                                     net->last_error,
 
537
                                     sizeof(net->last_error)-1);
 
538
    goto err;
 
539
  }
 
540
 
 
541
  result=0;                                     /* Ok */
 
542
 
 
543
err:
 
544
  /* free up memory allocated with _init, usually */
 
545
  (*options->local_infile_end)(li_ptr);
 
546
  my_free(buf, MYF(0));
 
547
  DBUG_RETURN(result);
 
548
}
 
549
 
 
550
 
 
551
/****************************************************************************
 
552
  Default handlers for LOAD LOCAL INFILE
 
553
****************************************************************************/
 
554
 
 
555
typedef struct st_default_local_infile
 
556
{
 
557
  int fd;
 
558
  int error_num;
 
559
  const char *filename;
 
560
  char error_msg[LOCAL_INFILE_ERROR_LEN];
 
561
} default_local_infile_data;
 
562
 
 
563
 
 
564
/*
 
565
  Open file for LOAD LOCAL INFILE
 
566
 
 
567
  SYNOPSIS
 
568
    default_local_infile_init()
 
569
    ptr                 Store pointer to internal data here
 
570
    filename            File name to open. This may be in unix format !
 
571
 
 
572
 
 
573
  NOTES
 
574
    Even if this function returns an error, the load data interface
 
575
    guarantees that default_local_infile_end() is called.
 
576
 
 
577
  RETURN
 
578
    0   ok
 
579
    1   error
 
580
*/
 
581
 
 
582
static int default_local_infile_init(void **ptr, const char *filename,
 
583
             void *userdata __attribute__ ((unused)))
 
584
{
 
585
  default_local_infile_data *data;
 
586
  char tmp_name[FN_REFLEN];
 
587
 
 
588
  if (!(*ptr= data= ((default_local_infile_data *)
 
589
                     my_malloc(sizeof(default_local_infile_data),  MYF(0)))))
 
590
    return 1; /* out of memory */
 
591
 
 
592
  data->error_msg[0]= 0;
 
593
  data->error_num=    0;
 
594
  data->filename= filename;
 
595
 
 
596
  fn_format(tmp_name, filename, "", "", MY_UNPACK_FILENAME);
 
597
  if ((data->fd = my_open(tmp_name, O_RDONLY, MYF(0))) < 0)
 
598
  {
 
599
    data->error_num= my_errno;
 
600
    snprintf(data->error_msg, sizeof(data->error_msg)-1,
 
601
             EE(EE_FILENOTFOUND), tmp_name, data->error_num);
 
602
    return 1;
 
603
  }
 
604
  return 0; /* ok */
 
605
}
 
606
 
 
607
 
 
608
/*
 
609
  Read data for LOAD LOCAL INFILE
 
610
 
 
611
  SYNOPSIS
 
612
    default_local_infile_read()
 
613
    ptr                 Points to handle allocated by _init
 
614
    buf                 Read data here
 
615
    buf_len             Ammount of data to read
 
616
 
 
617
  RETURN
 
618
    > 0         number of bytes read
 
619
    == 0        End of data
 
620
    < 0         Error
 
621
*/
 
622
 
 
623
static int default_local_infile_read(void *ptr, char *buf, uint buf_len)
 
624
{
 
625
  int count;
 
626
  default_local_infile_data*data = (default_local_infile_data *) ptr;
 
627
 
 
628
  if ((count= (int) my_read(data->fd, (uchar *) buf, buf_len, MYF(0))) < 0)
 
629
  {
 
630
    data->error_num= EE_READ; /* the errmsg for not entire file read */
 
631
    snprintf(data->error_msg, sizeof(data->error_msg)-1,
 
632
             EE(EE_READ),
 
633
             data->filename, my_errno);
 
634
  }
 
635
  return count;
 
636
}
 
637
 
 
638
 
 
639
/*
 
640
  Read data for LOAD LOCAL INFILE
 
641
 
 
642
  SYNOPSIS
 
643
    default_local_infile_end()
 
644
    ptr                 Points to handle allocated by _init
 
645
                        May be NULL if _init failed!
 
646
 
 
647
  RETURN
 
648
*/
 
649
 
 
650
static void default_local_infile_end(void *ptr)
 
651
{
 
652
  default_local_infile_data *data= (default_local_infile_data *) ptr;
 
653
  if (data)                                     /* If not error on open */
 
654
  {
 
655
    if (data->fd >= 0)
 
656
      my_close(data->fd, MYF(MY_WME));
 
657
    my_free(ptr, MYF(MY_WME));
 
658
  }
 
659
}
 
660
 
 
661
 
 
662
/*
 
663
  Return error from LOAD LOCAL INFILE
 
664
 
 
665
  SYNOPSIS
 
666
    default_local_infile_end()
 
667
    ptr                 Points to handle allocated by _init
 
668
                        May be NULL if _init failed!
 
669
    error_msg           Store error text here
 
670
    error_msg_len       Max lenght of error_msg
 
671
 
 
672
  RETURN
 
673
    error message number
 
674
*/
 
675
 
 
676
static int
 
677
default_local_infile_error(void *ptr, char *error_msg, uint error_msg_len)
 
678
{
 
679
  default_local_infile_data *data = (default_local_infile_data *) ptr;
 
680
  if (data)                                     /* If not error on open */
 
681
  {
 
682
    strmake(error_msg, data->error_msg, error_msg_len);
 
683
    return data->error_num;
 
684
  }
 
685
  /* This can only happen if we got error on malloc of handle */
 
686
  strmov(error_msg, ER(CR_OUT_OF_MEMORY));
 
687
  return CR_OUT_OF_MEMORY;
 
688
}
 
689
 
 
690
 
 
691
void
 
692
mysql_set_local_infile_handler(MYSQL *mysql,
 
693
                               int (*local_infile_init)(void **, const char *,
 
694
                               void *),
 
695
                               int (*local_infile_read)(void *, char *, uint),
 
696
                               void (*local_infile_end)(void *),
 
697
                               int (*local_infile_error)(void *, char *, uint),
 
698
                               void *userdata)
 
699
{
 
700
  mysql->options.local_infile_init=  local_infile_init;
 
701
  mysql->options.local_infile_read=  local_infile_read;
 
702
  mysql->options.local_infile_end=   local_infile_end;
 
703
  mysql->options.local_infile_error= local_infile_error;
 
704
  mysql->options.local_infile_userdata = userdata;
 
705
}
 
706
 
 
707
 
 
708
void mysql_set_local_infile_default(MYSQL *mysql)
 
709
{
 
710
  mysql->options.local_infile_init=  default_local_infile_init;
 
711
  mysql->options.local_infile_read=  default_local_infile_read;
 
712
  mysql->options.local_infile_end=   default_local_infile_end;
 
713
  mysql->options.local_infile_error= default_local_infile_error;
 
714
}
 
715
 
 
716
 
217
717
/**************************************************************************
218
718
  Do a query. If query returned rows, free old rows.
219
 
  Read data by drizzle_store_result or by repeat call of drizzle_fetch_row
 
719
  Read data by mysql_store_result or by repeat call of mysql_fetch_row
220
720
**************************************************************************/
221
721
 
222
 
int
223
 
drizzle_query(DRIZZLE *drizzle, const char *query)
 
722
int STDCALL
 
723
mysql_query(MYSQL *mysql, const char *query)
224
724
{
225
 
  return drizzle_real_query(drizzle,query, (uint32_t) strlen(query));
 
725
  return mysql_real_query(mysql,query, (uint) strlen(query));
226
726
}
227
727
 
228
728
 
230
730
  Return next field of the query results
231
731
**************************************************************************/
232
732
 
233
 
DRIZZLE_FIELD *
234
 
drizzle_fetch_field(DRIZZLE_RES *result)
 
733
MYSQL_FIELD * STDCALL
 
734
mysql_fetch_field(MYSQL_RES *result)
235
735
{
236
736
  if (result->current_field >= result->field_count)
237
737
    return(NULL);
243
743
  Move to a specific row and column
244
744
**************************************************************************/
245
745
 
246
 
void
247
 
drizzle_data_seek(DRIZZLE_RES *result, uint64_t row)
 
746
void STDCALL
 
747
mysql_data_seek(MYSQL_RES *result, my_ulonglong row)
248
748
{
249
 
  DRIZZLE_ROWS  *tmp=0;
 
749
  MYSQL_ROWS    *tmp=0;
 
750
  DBUG_PRINT("info",("mysql_data_seek(%ld)",(long) row));
250
751
  if (result->data)
251
752
    for (tmp=result->data->data; row-- && tmp ; tmp = tmp->next) ;
252
753
  result->current_row=0;
255
756
 
256
757
 
257
758
/*************************************************************************
258
 
  put the row or field cursor one a position one got from DRIZZLE_ROW_tell()
259
 
  This doesn't restore any data. The next drizzle_fetch_row or
260
 
  drizzle_fetch_field will return the next row or field after the last used
 
759
  put the row or field cursor one a position one got from mysql_row_tell()
 
760
  This doesn't restore any data. The next mysql_fetch_row or
 
761
  mysql_fetch_field will return the next row or field after the last used
261
762
*************************************************************************/
262
763
 
263
 
DRIZZLE_ROW_OFFSET
264
 
drizzle_row_seek(DRIZZLE_RES *result, DRIZZLE_ROW_OFFSET row)
 
764
MYSQL_ROW_OFFSET STDCALL
 
765
mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET row)
265
766
{
266
 
  DRIZZLE_ROW_OFFSET return_value=result->data_cursor;
 
767
  MYSQL_ROW_OFFSET return_value=result->data_cursor;
267
768
  result->current_row= 0;
268
769
  result->data_cursor= row;
269
770
  return return_value;
270
771
}
271
772
 
272
773
 
273
 
DRIZZLE_FIELD_OFFSET
274
 
drizzle_field_seek(DRIZZLE_RES *result, DRIZZLE_FIELD_OFFSET field_offset)
 
774
MYSQL_FIELD_OFFSET STDCALL
 
775
mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET field_offset)
275
776
{
276
 
  DRIZZLE_FIELD_OFFSET return_value=result->current_field;
 
777
  MYSQL_FIELD_OFFSET return_value=result->current_field;
277
778
  result->current_field=field_offset;
278
779
  return return_value;
279
780
}
280
781
 
281
782
 
282
783
/*****************************************************************************
 
784
  List all databases
 
785
*****************************************************************************/
 
786
 
 
787
MYSQL_RES * STDCALL
 
788
mysql_list_dbs(MYSQL *mysql, const char *wild)
 
789
{
 
790
  char buff[255];
 
791
  DBUG_ENTER("mysql_list_dbs");
 
792
 
 
793
  append_wild(strmov(buff,"show databases"),buff+sizeof(buff),wild);
 
794
  if (mysql_query(mysql,buff))
 
795
    DBUG_RETURN(0);
 
796
  DBUG_RETURN (mysql_store_result(mysql));
 
797
}
 
798
 
 
799
 
 
800
/*****************************************************************************
283
801
  List all tables in a database
284
802
  If wild is given then only the tables matching wild is returned
285
803
*****************************************************************************/
286
804
 
287
 
DRIZZLE_RES *
288
 
drizzle_list_tables(DRIZZLE *drizzle, const char *wild)
 
805
MYSQL_RES * STDCALL
 
806
mysql_list_tables(MYSQL *mysql, const char *wild)
289
807
{
290
808
  char buff[255];
291
 
  char *ptr= strcpy(buff, "show tables");
292
 
  ptr+= 11; /* strlen("show tables"); */
 
809
  DBUG_ENTER("mysql_list_tables");
293
810
 
294
 
  append_wild(ptr,buff+sizeof(buff),wild);
295
 
  if (drizzle_query(drizzle,buff))
296
 
    return(0);
297
 
  return (drizzle_store_result(drizzle));
 
811
  append_wild(strmov(buff,"show tables"),buff+sizeof(buff),wild);
 
812
  if (mysql_query(mysql,buff))
 
813
    DBUG_RETURN(0);
 
814
  DBUG_RETURN (mysql_store_result(mysql));
298
815
}
299
816
 
300
817
 
301
 
DRIZZLE_FIELD *cli_list_fields(DRIZZLE *drizzle)
 
818
MYSQL_FIELD *cli_list_fields(MYSQL *mysql)
302
819
{
303
 
  DRIZZLE_DATA *query;
304
 
  if (!(query= cli_read_rows(drizzle,(DRIZZLE_FIELD*) 0, 8)))
 
820
  MYSQL_DATA *query;
 
821
  if (!(query= cli_read_rows(mysql,(MYSQL_FIELD*) 0, 
 
822
                             protocol_41(mysql) ? 8 : 6)))
305
823
    return NULL;
306
824
 
307
 
  drizzle->field_count= (uint32_t) query->rows;
308
 
  return unpack_fields(query, drizzle->field_count, 1);
 
825
  mysql->field_count= (uint) query->rows;
 
826
  return unpack_fields(query,&mysql->field_alloc,
 
827
                       mysql->field_count, 1, mysql->server_capabilities);
309
828
}
310
829
 
311
830
 
316
835
  show fields in 'table' like "wild"
317
836
**************************************************************************/
318
837
 
319
 
DRIZZLE_RES *
320
 
drizzle_list_fields(DRIZZLE *drizzle, const char *table, const char *wild)
 
838
MYSQL_RES * STDCALL
 
839
mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)
321
840
{
322
 
  DRIZZLE_RES   *result;
323
 
  DRIZZLE_FIELD *fields;
324
 
  char buff[257], *end;
325
 
 
326
 
  end= strncpy(buff, table, 128) + 128;
327
 
  end= strncpy(end+1, wild ? wild : "", 128) + 128;
328
 
 
329
 
  free_old_query(drizzle);
330
 
  if (simple_command(drizzle, COM_FIELD_LIST, (unsigned char*) buff,
331
 
                     (uint32_t) (end-buff), 1) ||
332
 
      !(fields= (*drizzle->methods->list_fields)(drizzle)))
333
 
    return(NULL);
334
 
 
335
 
  if (!(result = (DRIZZLE_RES *) malloc(sizeof(DRIZZLE_RES))))
336
 
    return(NULL);
337
 
 
338
 
  memset(result, 0, sizeof(DRIZZLE_RES));
339
 
 
340
 
  result->methods= drizzle->methods;
341
 
  drizzle->fields=0;
342
 
  result->field_count = drizzle->field_count;
 
841
  MYSQL_RES   *result;
 
842
  MYSQL_FIELD *fields;
 
843
  char       buff[257],*end;
 
844
  DBUG_ENTER("mysql_list_fields");
 
845
  DBUG_PRINT("enter",("table: '%s'  wild: '%s'",table,wild ? wild : ""));
 
846
 
 
847
  end=strmake(strmake(buff, table,128)+1,wild ? wild : "",128);
 
848
  free_old_query(mysql);
 
849
  if (simple_command(mysql, COM_FIELD_LIST, (uchar*) buff,
 
850
                     (ulong) (end-buff), 1) ||
 
851
      !(fields= (*mysql->methods->list_fields)(mysql)))
 
852
    DBUG_RETURN(NULL);
 
853
 
 
854
  if (!(result = (MYSQL_RES *) my_malloc(sizeof(MYSQL_RES),
 
855
                                         MYF(MY_WME | MY_ZEROFILL))))
 
856
    DBUG_RETURN(NULL);
 
857
 
 
858
  result->methods= mysql->methods;
 
859
  result->field_alloc=mysql->field_alloc;
 
860
  mysql->fields=0;
 
861
  result->field_count = mysql->field_count;
343
862
  result->fields= fields;
344
863
  result->eof=1;
345
 
  return(result);
 
864
  DBUG_RETURN(result);
346
865
}
347
866
 
348
867
/* List all running processes (threads) in server */
349
868
 
350
 
DRIZZLE_RES *
351
 
drizzle_list_processes(DRIZZLE *drizzle)
352
 
{
353
 
  DRIZZLE_DATA *fields;
354
 
  uint32_t field_count;
355
 
  unsigned char *pos;
356
 
 
357
 
  if (simple_command(drizzle,COM_PROCESS_INFO,0,0,0))
358
 
    return(0);
359
 
  free_old_query(drizzle);
360
 
  pos=(unsigned char*) drizzle->net.read_pos;
361
 
  field_count=(uint32_t) net_field_length(&pos);
362
 
  if (!(fields = (*drizzle->methods->read_rows)(drizzle,(DRIZZLE_FIELD*) 0, 7)))
363
 
    return(NULL);
364
 
  if (!(drizzle->fields=unpack_fields(fields, field_count, 0)))
365
 
    return(0);
366
 
  drizzle->status=DRIZZLE_STATUS_GET_RESULT;
367
 
  drizzle->field_count=field_count;
368
 
  return(drizzle_store_result(drizzle));
369
 
}
370
 
 
371
 
 
372
 
int
373
 
drizzle_shutdown(DRIZZLE *drizzle)
374
 
{
375
 
  return(simple_command(drizzle, COM_SHUTDOWN, 0, 0, 0));
376
 
}
377
 
 
378
 
 
379
 
int
380
 
drizzle_refresh(DRIZZLE *drizzle, uint32_t options)
381
 
{
382
 
  unsigned char bits[1];
383
 
  bits[0]= (unsigned char) options;
384
 
  return(simple_command(drizzle, COM_REFRESH, bits, 1, 0));
385
 
}
386
 
 
387
 
 
388
 
int32_t
389
 
drizzle_kill(DRIZZLE *drizzle, uint32_t pid)
390
 
{
391
 
  unsigned char buff[4];
 
869
MYSQL_RES * STDCALL
 
870
mysql_list_processes(MYSQL *mysql)
 
871
{
 
872
  MYSQL_DATA *fields;
 
873
  uint field_count;
 
874
  uchar *pos;
 
875
  DBUG_ENTER("mysql_list_processes");
 
876
 
 
877
  if (simple_command(mysql,COM_PROCESS_INFO,0,0,0))
 
878
    DBUG_RETURN(0);
 
879
  free_old_query(mysql);
 
880
  pos=(uchar*) mysql->net.read_pos;
 
881
  field_count=(uint) net_field_length(&pos);
 
882
  if (!(fields = (*mysql->methods->read_rows)(mysql,(MYSQL_FIELD*) 0,
 
883
                                              protocol_41(mysql) ? 7 : 5)))
 
884
    DBUG_RETURN(NULL);
 
885
  if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,field_count,0,
 
886
                                    mysql->server_capabilities)))
 
887
    DBUG_RETURN(0);
 
888
  mysql->status=MYSQL_STATUS_GET_RESULT;
 
889
  mysql->field_count=field_count;
 
890
  DBUG_RETURN(mysql_store_result(mysql));
 
891
}
 
892
 
 
893
 
 
894
#ifdef USE_OLD_FUNCTIONS
 
895
int  STDCALL
 
896
mysql_create_db(MYSQL *mysql, const char *db)
 
897
{
 
898
  DBUG_ENTER("mysql_createdb");
 
899
  DBUG_PRINT("enter",("db: %s",db));
 
900
  DBUG_RETURN(simple_command(mysql,COM_CREATE_DB,db, (ulong) strlen(db),0));
 
901
}
 
902
 
 
903
 
 
904
int  STDCALL
 
905
mysql_drop_db(MYSQL *mysql, const char *db)
 
906
{
 
907
  DBUG_ENTER("mysql_drop_db");
 
908
  DBUG_PRINT("enter",("db: %s",db));
 
909
  DBUG_RETURN(simple_command(mysql,COM_DROP_DB,db,(ulong) strlen(db),0));
 
910
}
 
911
#endif
 
912
 
 
913
 
 
914
int STDCALL
 
915
mysql_shutdown(MYSQL *mysql, enum mysql_enum_shutdown_level shutdown_level)
 
916
{
 
917
  uchar level[1];
 
918
  DBUG_ENTER("mysql_shutdown");
 
919
  level[0]= (uchar) shutdown_level;
 
920
  DBUG_RETURN(simple_command(mysql, COM_SHUTDOWN, level, 1, 0));
 
921
}
 
922
 
 
923
 
 
924
int STDCALL
 
925
mysql_refresh(MYSQL *mysql,uint options)
 
926
{
 
927
  uchar bits[1];
 
928
  DBUG_ENTER("mysql_refresh");
 
929
  bits[0]= (uchar) options;
 
930
  DBUG_RETURN(simple_command(mysql, COM_REFRESH, bits, 1, 0));
 
931
}
 
932
 
 
933
 
 
934
int STDCALL
 
935
mysql_kill(MYSQL *mysql,ulong pid)
 
936
{
 
937
  uchar buff[4];
 
938
  DBUG_ENTER("mysql_kill");
392
939
  int4store(buff,pid);
393
 
  return(simple_command(drizzle,COM_PROCESS_KILL,buff,sizeof(buff),0));
394
 
}
395
 
 
396
 
 
397
 
int
398
 
drizzle_set_server_option(DRIZZLE *drizzle, enum enum_drizzle_set_option option)
399
 
{
400
 
  unsigned char buff[2];
401
 
  int2store(buff, (uint32_t) option);
402
 
  return(simple_command(drizzle, COM_SET_OPTION, buff, sizeof(buff), 0));
403
 
}
404
 
 
405
 
 
406
 
const char *cli_read_statistics(DRIZZLE *drizzle)
407
 
{
408
 
  drizzle->net.read_pos[drizzle->packet_length]=0;  /* End of stat string */
409
 
  if (!drizzle->net.read_pos[0])
 
940
  DBUG_RETURN(simple_command(mysql,COM_PROCESS_KILL,buff,sizeof(buff),0));
 
941
}
 
942
 
 
943
 
 
944
int STDCALL
 
945
mysql_set_server_option(MYSQL *mysql, enum enum_mysql_set_option option)
 
946
{
 
947
  uchar buff[2];
 
948
  DBUG_ENTER("mysql_set_server_option");
 
949
  int2store(buff, (uint) option);
 
950
  DBUG_RETURN(simple_command(mysql, COM_SET_OPTION, buff, sizeof(buff), 0));
 
951
}
 
952
 
 
953
 
 
954
int STDCALL
 
955
mysql_dump_debug_info(MYSQL *mysql)
 
956
{
 
957
  DBUG_ENTER("mysql_dump_debug_info");
 
958
  DBUG_RETURN(simple_command(mysql,COM_DEBUG,0,0,0));
 
959
}
 
960
 
 
961
 
 
962
const char *cli_read_statistics(MYSQL *mysql)
 
963
{
 
964
  mysql->net.read_pos[mysql->packet_length]=0;  /* End of stat string */
 
965
  if (!mysql->net.read_pos[0])
410
966
  {
411
 
    drizzle_set_error(drizzle, CR_WRONG_HOST_INFO, sqlstate_get_unknown());
412
 
    return drizzle->net.last_error;
 
967
    set_mysql_error(mysql, CR_WRONG_HOST_INFO, unknown_sqlstate);
 
968
    return mysql->net.last_error;
413
969
  }
414
 
  return (char*) drizzle->net.read_pos;
415
 
}
416
 
 
417
 
 
418
 
int
419
 
drizzle_ping(DRIZZLE *drizzle)
 
970
  return (char*) mysql->net.read_pos;
 
971
}
 
972
 
 
973
 
 
974
const char * STDCALL
 
975
mysql_stat(MYSQL *mysql)
 
976
{
 
977
  DBUG_ENTER("mysql_stat");
 
978
  if (simple_command(mysql,COM_STATISTICS,0,0,0))
 
979
    DBUG_RETURN(mysql->net.last_error);
 
980
  DBUG_RETURN((*mysql->methods->read_statistics)(mysql));
 
981
}
 
982
 
 
983
 
 
984
int STDCALL
 
985
mysql_ping(MYSQL *mysql)
420
986
{
421
987
  int res;
422
 
  res= simple_command(drizzle,COM_PING,0,0,0);
423
 
  if (res == CR_SERVER_LOST && drizzle->reconnect)
424
 
    res= simple_command(drizzle,COM_PING,0,0,0);
425
 
  return(res);
426
 
}
427
 
 
428
 
 
429
 
const char *
430
 
drizzle_get_server_info(const DRIZZLE *drizzle)
431
 
{
432
 
  return((char*) drizzle->server_version);
433
 
}
434
 
 
435
 
 
436
 
const char *
437
 
drizzle_get_host_info(const DRIZZLE *drizzle)
438
 
{
439
 
  return(drizzle->host_info);
440
 
}
441
 
 
442
 
 
443
 
uint32_t
444
 
drizzle_get_proto_info(const DRIZZLE *drizzle)
445
 
{
446
 
  return (drizzle->protocol_version);
447
 
}
448
 
 
449
 
const char *
450
 
drizzle_get_client_info(void)
451
 
{
452
 
  return (char*) DRIZZLE_SERVER_VERSION;
453
 
}
454
 
 
455
 
uint32_t drizzle_get_client_version(void)
456
 
{
457
 
  return DRIZZLE_VERSION_ID;
458
 
}
459
 
 
460
 
bool drizzle_eof(const DRIZZLE_RES *res)
 
988
  DBUG_ENTER("mysql_ping");
 
989
  res= simple_command(mysql,COM_PING,0,0,0);
 
990
  if (res == CR_SERVER_LOST && mysql->reconnect)
 
991
    res= simple_command(mysql,COM_PING,0,0,0);
 
992
  DBUG_RETURN(res);
 
993
}
 
994
 
 
995
 
 
996
const char * STDCALL
 
997
mysql_get_server_info(MYSQL *mysql)
 
998
{
 
999
  return((char*) mysql->server_version);
 
1000
}
 
1001
 
 
1002
 
 
1003
const char * STDCALL
 
1004
mysql_get_host_info(MYSQL *mysql)
 
1005
{
 
1006
  return(mysql->host_info);
 
1007
}
 
1008
 
 
1009
 
 
1010
uint STDCALL
 
1011
mysql_get_proto_info(MYSQL *mysql)
 
1012
{
 
1013
  return (mysql->protocol_version);
 
1014
}
 
1015
 
 
1016
const char * STDCALL
 
1017
mysql_get_client_info(void)
 
1018
{
 
1019
  return (char*) MYSQL_SERVER_VERSION;
 
1020
}
 
1021
 
 
1022
ulong STDCALL mysql_get_client_version(void)
 
1023
{
 
1024
  return MYSQL_VERSION_ID;
 
1025
}
 
1026
 
 
1027
my_bool STDCALL mysql_eof(MYSQL_RES *res)
461
1028
{
462
1029
  return res->eof;
463
1030
}
464
1031
 
465
 
const DRIZZLE_FIELD * drizzle_fetch_field_direct(const DRIZZLE_RES *res, unsigned int fieldnr)
 
1032
MYSQL_FIELD * STDCALL mysql_fetch_field_direct(MYSQL_RES *res,uint fieldnr)
466
1033
{
467
1034
  return &(res)->fields[fieldnr];
468
1035
}
469
1036
 
470
 
const DRIZZLE_FIELD * drizzle_fetch_fields(const DRIZZLE_RES *res)
 
1037
MYSQL_FIELD * STDCALL mysql_fetch_fields(MYSQL_RES *res)
471
1038
{
472
 
  return res->fields;
 
1039
  return (res)->fields;
473
1040
}
474
1041
 
475
 
DRIZZLE_ROW_OFFSET drizzle_row_tell(const DRIZZLE_RES *res)
 
1042
MYSQL_ROW_OFFSET STDCALL mysql_row_tell(MYSQL_RES *res)
476
1043
{
477
1044
  return res->data_cursor;
478
1045
}
479
1046
 
480
 
DRIZZLE_FIELD_OFFSET drizzle_field_tell(const DRIZZLE_RES *res)
481
 
{
482
 
  return res->current_field;
483
 
}
484
 
 
485
 
/* DRIZZLE */
486
 
 
487
 
unsigned int drizzle_field_count(const DRIZZLE *drizzle)
488
 
{
489
 
  return drizzle->field_count;
490
 
}
491
 
 
492
 
uint64_t drizzle_affected_rows(const DRIZZLE *drizzle)
493
 
{
494
 
  return drizzle->affected_rows;
495
 
}
496
 
 
497
 
uint64_t drizzle_insert_id(const DRIZZLE *drizzle)
498
 
{
499
 
  return drizzle->insert_id;
500
 
}
501
 
 
502
 
const char * drizzle_sqlstate(const DRIZZLE *drizzle)
503
 
{
504
 
  return drizzle ? drizzle->net.sqlstate : sqlstate_get_cant_connect();
505
 
}
506
 
 
507
 
uint32_t drizzle_warning_count(const DRIZZLE *drizzle)
508
 
{
509
 
  return drizzle->warning_count;
510
 
}
511
 
 
512
 
const char * drizzle_info(const DRIZZLE *drizzle)
513
 
{
514
 
  return drizzle->info;
515
 
}
516
 
 
517
 
uint32_t drizzle_thread_id(const DRIZZLE *drizzle)
518
 
{
519
 
  return drizzle->thread_id;
 
1047
MYSQL_FIELD_OFFSET STDCALL mysql_field_tell(MYSQL_RES *res)
 
1048
{
 
1049
  return (res)->current_field;
 
1050
}
 
1051
 
 
1052
/* MYSQL */
 
1053
 
 
1054
unsigned int STDCALL mysql_field_count(MYSQL *mysql)
 
1055
{
 
1056
  return mysql->field_count;
 
1057
}
 
1058
 
 
1059
my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql)
 
1060
{
 
1061
  return mysql->affected_rows;
 
1062
}
 
1063
 
 
1064
my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql)
 
1065
{
 
1066
  return mysql->insert_id;
 
1067
}
 
1068
 
 
1069
const char *STDCALL mysql_sqlstate(MYSQL *mysql)
 
1070
{
 
1071
  return mysql ? mysql->net.sqlstate : cant_connect_sqlstate;
 
1072
}
 
1073
 
 
1074
uint STDCALL mysql_warning_count(MYSQL *mysql)
 
1075
{
 
1076
  return mysql->warning_count;
 
1077
}
 
1078
 
 
1079
const char *STDCALL mysql_info(MYSQL *mysql)
 
1080
{
 
1081
  return mysql->info;
 
1082
}
 
1083
 
 
1084
ulong STDCALL mysql_thread_id(MYSQL *mysql)
 
1085
{
 
1086
  return (mysql)->thread_id;
 
1087
}
 
1088
 
 
1089
const char * STDCALL mysql_character_set_name(MYSQL *mysql)
 
1090
{
 
1091
  return mysql->charset->csname;
 
1092
}
 
1093
 
 
1094
void STDCALL mysql_get_character_set_info(MYSQL *mysql, MY_CHARSET_INFO *csinfo)
 
1095
{
 
1096
  csinfo->number   = mysql->charset->number;
 
1097
  csinfo->state    = mysql->charset->state;
 
1098
  csinfo->csname   = mysql->charset->csname;
 
1099
  csinfo->name     = mysql->charset->name;
 
1100
  csinfo->comment  = mysql->charset->comment;
 
1101
  csinfo->mbminlen = mysql->charset->mbminlen;
 
1102
  csinfo->mbmaxlen = mysql->charset->mbmaxlen;
 
1103
 
 
1104
  if (mysql->options.charset_dir)
 
1105
    csinfo->dir = mysql->options.charset_dir;
 
1106
  else
 
1107
    csinfo->dir = charsets_dir;
 
1108
}
 
1109
 
 
1110
uint STDCALL mysql_thread_safe(void)
 
1111
{
 
1112
  return 1;
 
1113
}
 
1114
 
 
1115
 
 
1116
my_bool STDCALL mysql_embedded(void)
 
1117
{
 
1118
#ifdef EMBEDDED_LIBRARY
 
1119
  return 1;
 
1120
#else
 
1121
  return 0;
 
1122
#endif
520
1123
}
521
1124
 
522
1125
/****************************************************************************
529
1132
 
530
1133
void my_net_local_init(NET *net)
531
1134
{
532
 
  net->max_packet=   (uint32_t) net_buffer_length;
 
1135
  net->max_packet=   (uint) net_buffer_length;
533
1136
  my_net_set_read_timeout(net, CLIENT_NET_READ_TIMEOUT);
534
1137
  my_net_set_write_timeout(net, CLIENT_NET_WRITE_TIMEOUT);
535
1138
  net->retry_count=  1;
536
 
  net->max_packet_size= (net_buffer_length > max_allowed_packet) ?
537
 
    net_buffer_length : max_allowed_packet;
 
1139
  net->max_packet_size= max(net_buffer_length, max_allowed_packet);
538
1140
}
539
1141
 
540
1142
/*
541
1143
  This function is used to create HEX string that you
542
1144
  can use in a SQL statement in of the either ways:
543
 
    INSERT INTO blob_column VALUES (0xAABBCC);  (any DRIZZLE version)
544
 
    INSERT INTO blob_column VALUES (X'AABBCC'); 
 
1145
    INSERT INTO blob_column VALUES (0xAABBCC);  (any MySQL version)
 
1146
    INSERT INTO blob_column VALUES (X'AABBCC'); (4.1 and higher)
545
1147
  
546
1148
  The string in "from" is encoded to a HEX string.
547
1149
  The result is placed in "to" and a terminating null byte is appended.
549
1151
  The string pointed to by "from" must be "length" bytes long.
550
1152
  You must allocate the "to" buffer to be at least length*2+1 bytes long.
551
1153
  Each character needs two bytes, and you need room for the terminating
552
 
  null byte. When drizzle_hex_string() returns, the contents of "to" will
 
1154
  null byte. When mysql_hex_string() returns, the contents of "to" will
553
1155
  be a null-terminated string. The return value is the length of the
554
 
  encoded string, not including the terminating null character.  The return value does not contain any leading 0x or a leading X' and
 
1156
  encoded string, not including the terminating null character.
 
1157
 
 
1158
  The return value does not contain any leading 0x or a leading X' and
555
1159
  trailing '. The caller must supply whichever of those is desired.
556
1160
*/
557
1161
 
558
 
uint32_t
559
 
drizzle_hex_string(char *to, const char *from, uint32_t length)
 
1162
ulong STDCALL
 
1163
mysql_hex_string(char *to, const char *from, ulong length)
560
1164
{
561
1165
  char *to0= to;
562
1166
  const char *end;
567
1171
    *to++= _dig_vec_upper[((unsigned char) *from) & 0x0F];
568
1172
  }
569
1173
  *to= '\0';
570
 
  return (uint32_t) (to-to0);
 
1174
  return (ulong) (to-to0);
571
1175
}
572
1176
 
573
1177
/*
576
1180
  Returns the length of the to string
577
1181
*/
578
1182
 
579
 
uint32_t
580
 
drizzle_escape_string(char *to,const char *from, uint32_t length)
581
 
{
582
 
  const char *to_start= to;
583
 
  const char *end, *to_end=to_start + 2*length;
584
 
  bool overflow= false;
585
 
  for (end= from + length; from < end; from++)
 
1183
ulong STDCALL
 
1184
mysql_escape_string(char *to,const char *from,ulong length)
 
1185
{
 
1186
  return escape_string_for_mysql(default_charset_info, to, 0, from, length);
 
1187
}
 
1188
 
 
1189
ulong STDCALL
 
1190
mysql_real_escape_string(MYSQL *mysql, char *to,const char *from,
 
1191
                         ulong length)
 
1192
{
 
1193
  if (mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES)
 
1194
    return escape_quotes_for_mysql(mysql->charset, to, 0, from, length);
 
1195
  return escape_string_for_mysql(mysql->charset, to, 0, from, length);
 
1196
}
 
1197
 
 
1198
void STDCALL
 
1199
myodbc_remove_escape(MYSQL *mysql,char *name)
 
1200
{
 
1201
  char *to;
 
1202
#ifdef USE_MB
 
1203
  my_bool use_mb_flag=use_mb(mysql->charset);
 
1204
  char *end;
 
1205
  if (use_mb_flag)
 
1206
    for (end=name; *end ; end++) ;
 
1207
#endif
 
1208
 
 
1209
  for (to=name ; *name ; name++)
586
1210
  {
587
 
    uint32_t tmp_length;
588
 
    char escape= 0;
589
 
    if (!U8_IS_SINGLE(*from))
 
1211
#ifdef USE_MB
 
1212
    int l;
 
1213
    if (use_mb_flag && (l = my_ismbchar( mysql->charset, name , end ) ) )
590
1214
    {
591
 
      tmp_length= U8_LENGTH(*from);
592
 
      if (to + tmp_length > to_end)
593
 
      {
594
 
        overflow= true;
595
 
        break;
596
 
      }
597
 
      while (tmp_length--)
598
 
        *to++= *from++;
599
 
      from--;
 
1215
      while (l--)
 
1216
        *to++ = *name++;
 
1217
      name--;
600
1218
      continue;
601
1219
    }
602
 
    switch (*from) {
603
 
    case 0:                             /* Must be escaped for 'mysql' */
604
 
      escape= '0';
605
 
      break;
606
 
    case '\n':                          /* Must be escaped for logs */
607
 
      escape= 'n';
608
 
      break;
609
 
    case '\r':
610
 
      escape= 'r';
611
 
      break;
612
 
    case '\\':
613
 
      escape= '\\';
614
 
      break;
615
 
    case '\'':
616
 
      escape= '\'';
617
 
      break;
618
 
    case '"':                           /* Better safe than sorry */
619
 
      escape= '"';
620
 
      break;
621
 
    case '\032':                        /* This gives problems on Win32 */
622
 
      escape= 'Z';
623
 
      break;
624
 
    }
625
 
    if (escape)
626
 
    {
627
 
      if (to + 2 > to_end)
628
 
      {
629
 
        overflow= true;
630
 
        break;
631
 
      }
632
 
      *to++= '\\';
633
 
      *to++= escape;
634
 
    }
635
 
    else
636
 
    {
637
 
      if (to + 1 > to_end)
638
 
      {
639
 
        overflow= true;
640
 
        break;
641
 
      }
642
 
      *to++= *from;
643
 
    }
 
1220
#endif
 
1221
    if (*name == '\\' && name[1])
 
1222
      name++;
 
1223
    *to++= *name;
644
1224
  }
645
 
  *to= 0;
646
 
  return overflow ? (size_t) -1 : (size_t) (to - to_start);
 
1225
  *to=0;
647
1226
}
648
1227
 
649
 
int cli_unbuffered_fetch(DRIZZLE *drizzle, char **row)
 
1228
int cli_unbuffered_fetch(MYSQL *mysql, char **row)
650
1229
{
651
 
  if (packet_error == cli_safe_read(drizzle))
 
1230
  if (packet_error == cli_safe_read(mysql))
652
1231
    return 1;
653
1232
 
654
 
  *row= ((drizzle->net.read_pos[0] == DRIZZLE_PROTOCOL_NO_MORE_DATA) ? NULL :
655
 
   (char*) (drizzle->net.read_pos+1));
 
1233
  *row= ((mysql->net.read_pos[0] == 254) ? NULL :
 
1234
         (char*) (mysql->net.read_pos+1));
656
1235
  return 0;
657
1236
}
658
1237
 
664
1243
  Commit the current transaction
665
1244
*/
666
1245
 
667
 
bool drizzle_commit(DRIZZLE *drizzle)
 
1246
my_bool STDCALL mysql_commit(MYSQL * mysql)
668
1247
{
669
 
  return((bool) drizzle_real_query(drizzle, "commit", 6));
 
1248
  DBUG_ENTER("mysql_commit");
 
1249
  DBUG_RETURN((my_bool) mysql_real_query(mysql, "commit", 6));
670
1250
}
671
1251
 
672
1252
/*
673
1253
  Rollback the current transaction
674
1254
*/
675
1255
 
676
 
bool drizzle_rollback(DRIZZLE *drizzle)
 
1256
my_bool STDCALL mysql_rollback(MYSQL * mysql)
677
1257
{
678
 
  return((bool) drizzle_real_query(drizzle, "rollback", 8));
 
1258
  DBUG_ENTER("mysql_rollback");
 
1259
  DBUG_RETURN((my_bool) mysql_real_query(mysql, "rollback", 8));
679
1260
}
680
1261
 
681
1262
 
683
1264
  Set autocommit to either true or false
684
1265
*/
685
1266
 
686
 
bool drizzle_autocommit(DRIZZLE *drizzle, bool auto_mode)
 
1267
my_bool STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode)
687
1268
{
688
 
  return((bool) drizzle_real_query(drizzle, auto_mode ?
 
1269
  DBUG_ENTER("mysql_autocommit");
 
1270
  DBUG_PRINT("enter", ("mode : %d", auto_mode));
 
1271
 
 
1272
  DBUG_RETURN((my_bool) mysql_real_query(mysql, auto_mode ?
689
1273
                                         "set autocommit=1":"set autocommit=0",
690
1274
                                         16));
691
1275
}
697
1281
 
698
1282
/*
699
1283
  Returns true/false to indicate whether any more query results exist
700
 
  to be read using drizzle_next_result()
 
1284
  to be read using mysql_next_result()
701
1285
*/
702
1286
 
703
 
bool drizzle_more_results(const DRIZZLE *drizzle)
 
1287
my_bool STDCALL mysql_more_results(MYSQL *mysql)
704
1288
{
705
 
  return (drizzle->server_status & SERVER_MORE_RESULTS_EXISTS) ? true:false;
 
1289
  my_bool res;
 
1290
  DBUG_ENTER("mysql_more_results");
 
1291
 
 
1292
  res= ((mysql->server_status & SERVER_MORE_RESULTS_EXISTS) ? 1: 0);
 
1293
  DBUG_PRINT("exit",("More results exists ? %d", res));
 
1294
  DBUG_RETURN(res);
706
1295
}
707
1296
 
708
1297
 
709
1298
/*
710
1299
  Reads and returns the next query results
711
1300
*/
712
 
int drizzle_next_result(DRIZZLE *drizzle)
 
1301
int STDCALL mysql_next_result(MYSQL *mysql)
713
1302
{
714
 
  if (drizzle->status != DRIZZLE_STATUS_READY)
 
1303
  DBUG_ENTER("mysql_next_result");
 
1304
 
 
1305
  if (mysql->status != MYSQL_STATUS_READY)
715
1306
  {
716
 
    drizzle_set_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, sqlstate_get_unknown());
717
 
    return(1);
 
1307
    set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
 
1308
    DBUG_RETURN(1);
718
1309
  }
719
1310
 
720
 
  net_clear_error(&drizzle->net);
721
 
  drizzle->affected_rows= ~(uint64_t) 0;
722
 
 
723
 
  if (drizzle->server_status & SERVER_MORE_RESULTS_EXISTS)
724
 
    return((*drizzle->methods->next_result)(drizzle));
725
 
 
726
 
  return(-1);        /* No more results */
727
 
}
728
 
 
729
 
 
730
 
DRIZZLE_RES * drizzle_use_result(DRIZZLE *drizzle)
731
 
{
732
 
  return (*drizzle->methods->use_result)(drizzle);
733
 
}
734
 
 
735
 
bool drizzle_read_query_result(DRIZZLE *drizzle)
736
 
{
737
 
  return (*drizzle->methods->read_query_result)(drizzle);
 
1311
  net_clear_error(&mysql->net);
 
1312
  mysql->affected_rows= ~(my_ulonglong) 0;
 
1313
 
 
1314
  if (mysql->server_status & SERVER_MORE_RESULTS_EXISTS)
 
1315
    DBUG_RETURN((*mysql->methods->next_result)(mysql));
 
1316
 
 
1317
  DBUG_RETURN(-1);                              /* No more results */
 
1318
}
 
1319
 
 
1320
 
 
1321
MYSQL_RES * STDCALL mysql_use_result(MYSQL *mysql)
 
1322
{
 
1323
  return (*mysql->methods->use_result)(mysql);
 
1324
}
 
1325
 
 
1326
my_bool STDCALL mysql_read_query_result(MYSQL *mysql)
 
1327
{
 
1328
  return (*mysql->methods->read_query_result)(mysql);
738
1329
}
739
1330