~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzle/libdrizzle.c

  • Committer: Brian Aker
  • Date: 2008-09-04 19:31:00 UTC
  • Revision ID: brian@tangent.org-20080904193100-l849hgghfy4urj43
Changing default character set from this point on.

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 <config.h>
21
 
#include "libdrizzle_priv.h"
22
 
 
23
 
#include <libdrizzle/libdrizzle.h>
24
 
#include <libdrizzle/pack.h>
25
 
#include <libdrizzle/errmsg.h>
 
1
/* Copyright (C) 2000-2004 DRIZZLE 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 <drizzled/global.h>
 
21
#include <mysys/my_sys.h>
 
22
#include "my_time.h"
 
23
#include "drizzle.h"
 
24
#include "errmsg.h"
26
25
#include <sys/stat.h>
27
26
#include <signal.h>
28
27
#include <time.h>
51
50
#define INADDR_NONE  -1
52
51
#endif
53
52
 
54
 
#include <stdlib.h>
55
 
#include <string.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
 
 
 
53
#include <sql_common.h>
 
54
#include "client_settings.h"
 
55
#include <drizzled/version.h>
71
56
 
72
57
#undef net_buffer_length
73
58
#undef max_allowed_packet
75
60
uint32_t     net_buffer_length= 8192;
76
61
uint32_t    max_allowed_packet= 1024L*1024L*1024L;
77
62
 
78
 
unsigned int drizzle_port=0;
79
 
 
80
63
#include <errno.h>
 
64
#define SOCKET_ERROR -1
 
65
 
 
66
/*
 
67
  If allowed through some configuration, then this needs to
 
68
  be changed
 
69
*/
 
70
#define MAX_LONG_DATA_LENGTH 8192
 
71
#define unsigned_field(A) ((A)->flags & UNSIGNED_FLAG)
81
72
 
82
73
 
83
74
static DRIZZLE_PARAMETERS drizzle_internal_parameters=
88
79
  return &drizzle_internal_parameters;
89
80
}
90
81
 
91
 
unsigned int drizzle_get_default_port(void)
92
 
{
93
 
  return drizzle_port;
94
 
}
95
 
 
96
 
void drizzle_set_default_port(unsigned int port)
97
 
{
98
 
  drizzle_port= port;
99
 
}
 
82
bool drizzle_thread_init()
 
83
{
 
84
  return my_thread_init();
 
85
}
 
86
 
 
87
void drizzle_thread_end()
 
88
{
 
89
  my_thread_end();
 
90
}
 
91
 
100
92
 
101
93
/*
102
94
  Expand wildcard to a sql string
125
117
}
126
118
 
127
119
/**************************************************************************
 
120
  Ignore SIGPIPE handler
 
121
   ARGSUSED
 
122
**************************************************************************/
 
123
 
 
124
sig_handler
 
125
my_pipe_sig_handler(int sig __attribute__((unused)))
 
126
{
 
127
#ifdef DONT_REMEMBER_SIGNAL
 
128
  (void) signal(SIGPIPE, my_pipe_sig_handler);
 
129
#endif
 
130
}
 
131
 
 
132
 
 
133
/**************************************************************************
128
134
  Change user and database
129
135
**************************************************************************/
130
136
 
146
152
  char buff[USERNAME_LENGTH+SCRAMBLED_PASSWORD_CHAR_LENGTH+NAME_LEN+2];
147
153
  char *end= buff;
148
154
  int rc;
 
155
  const CHARSET_INFO *saved_cs= drizzle->charset;
 
156
 
 
157
  /* Get the connection-default character set. */
 
158
 
 
159
  if (drizzle_init_character_set(drizzle))
 
160
  {
 
161
    drizzle->charset= saved_cs;
 
162
    return(true);
 
163
  }
149
164
 
150
165
  /* Use an empty string instead of NULL. */
151
166
 
171
186
  end= strncpy(end, db ? db : "", NAME_LEN) + NAME_LEN + 1;
172
187
 
173
188
  /* Add character set number. */
 
189
 
174
190
  if (drizzle->server_capabilities & CLIENT_SECURE_CONNECTION)
175
191
  {
176
 
    int2store(end, (uint16_t) 45); // utf8mb4 number from mystrings/ctype-utf8.c
 
192
    int2store(end, (ushort) drizzle->charset->number);
177
193
    end+= 2;
178
194
  }
179
195
 
180
196
  /* Write authentication package */
181
 
  (void)simple_command(drizzle,COM_CHANGE_USER, (unsigned char*) buff, (uint32_t) (end-buff), 1);
 
197
  (void)simple_command(drizzle,COM_CHANGE_USER, (uchar*) buff, (uint32_t) (end-buff), 1);
182
198
 
183
199
  rc= (*drizzle->methods->read_change_user_result)(drizzle);
184
200
 
197
213
    drizzle->passwd= strdup(passwd);
198
214
    drizzle->db= db ? strdup(db) : 0;
199
215
  }
 
216
  else
 
217
  {
 
218
    drizzle->charset= saved_cs;
 
219
  }
200
220
 
201
221
  return(rc);
202
222
}
214
234
int
215
235
drizzle_query(DRIZZLE *drizzle, const char *query)
216
236
{
217
 
  return drizzle_real_query(drizzle,query, (uint32_t) strlen(query));
 
237
  return drizzle_real_query(drizzle,query, (uint) strlen(query));
218
238
}
219
239
 
220
240
 
296
316
  if (!(query= cli_read_rows(drizzle,(DRIZZLE_FIELD*) 0, 8)))
297
317
    return NULL;
298
318
 
299
 
  drizzle->field_count= (uint32_t) query->rows;
300
 
  return unpack_fields(query, drizzle->field_count, 1);
 
319
  drizzle->field_count= (uint) query->rows;
 
320
  return unpack_fields(query,&drizzle->field_alloc, drizzle->field_count, 1);
301
321
}
302
322
 
303
323
 
319
339
  end= strncpy(end+1, wild ? wild : "", 128) + 128;
320
340
 
321
341
  free_old_query(drizzle);
322
 
  if (simple_command(drizzle, COM_FIELD_LIST, (unsigned char*) buff,
 
342
  if (simple_command(drizzle, COM_FIELD_LIST, (uchar*) buff,
323
343
                     (uint32_t) (end-buff), 1) ||
324
344
      !(fields= (*drizzle->methods->list_fields)(drizzle)))
325
345
    return(NULL);
330
350
  memset(result, 0, sizeof(DRIZZLE_RES));
331
351
 
332
352
  result->methods= drizzle->methods;
 
353
  result->field_alloc=drizzle->field_alloc;
333
354
  drizzle->fields=0;
334
355
  result->field_count = drizzle->field_count;
335
356
  result->fields= fields;
343
364
drizzle_list_processes(DRIZZLE *drizzle)
344
365
{
345
366
  DRIZZLE_DATA *fields;
346
 
  uint32_t field_count;
347
 
  unsigned char *pos;
 
367
  uint field_count;
 
368
  uchar *pos;
348
369
 
349
370
  if (simple_command(drizzle,COM_PROCESS_INFO,0,0,0))
350
371
    return(0);
351
372
  free_old_query(drizzle);
352
 
  pos=(unsigned char*) drizzle->net.read_pos;
353
 
  field_count=(uint32_t) net_field_length(&pos);
 
373
  pos=(uchar*) drizzle->net.read_pos;
 
374
  field_count=(uint) net_field_length(&pos);
354
375
  if (!(fields = (*drizzle->methods->read_rows)(drizzle,(DRIZZLE_FIELD*) 0, 7)))
355
376
    return(NULL);
356
 
  if (!(drizzle->fields=unpack_fields(fields, field_count, 0)))
 
377
  if (!(drizzle->fields=unpack_fields(fields,&drizzle->field_alloc,field_count,0)))
357
378
    return(0);
358
379
  drizzle->status=DRIZZLE_STATUS_GET_RESULT;
359
380
  drizzle->field_count=field_count;
362
383
 
363
384
 
364
385
int
365
 
drizzle_shutdown(DRIZZLE *drizzle)
 
386
drizzle_shutdown(DRIZZLE *drizzle, enum drizzle_enum_shutdown_level shutdown_level)
366
387
{
367
 
  return(simple_command(drizzle, COM_SHUTDOWN, 0, 0, 0));
 
388
  uchar level[1];
 
389
  level[0]= (uchar) shutdown_level;
 
390
  return(simple_command(drizzle, COM_SHUTDOWN, level, 1, 0));
368
391
}
369
392
 
370
393
 
371
394
int
372
 
drizzle_refresh(DRIZZLE *drizzle, uint32_t options)
 
395
drizzle_refresh(DRIZZLE *drizzle,uint options)
373
396
{
374
 
  unsigned char bits[1];
375
 
  bits[0]= (unsigned char) options;
 
397
  uchar bits[1];
 
398
  bits[0]= (uchar) options;
376
399
  return(simple_command(drizzle, COM_REFRESH, bits, 1, 0));
377
400
}
378
401
 
380
403
int32_t
381
404
drizzle_kill(DRIZZLE *drizzle, uint32_t pid)
382
405
{
383
 
  unsigned char buff[4];
 
406
  uchar buff[4];
384
407
  int4store(buff,pid);
385
408
  return(simple_command(drizzle,COM_PROCESS_KILL,buff,sizeof(buff),0));
386
409
}
389
412
int
390
413
drizzle_set_server_option(DRIZZLE *drizzle, enum enum_drizzle_set_option option)
391
414
{
392
 
  unsigned char buff[2];
393
 
  int2store(buff, (uint32_t) option);
 
415
  uchar buff[2];
 
416
  int2store(buff, (uint) option);
394
417
  return(simple_command(drizzle, COM_SET_OPTION, buff, sizeof(buff), 0));
395
418
}
396
419
 
400
423
  drizzle->net.read_pos[drizzle->packet_length]=0;  /* End of stat string */
401
424
  if (!drizzle->net.read_pos[0])
402
425
  {
403
 
    drizzle_set_error(drizzle, CR_WRONG_HOST_INFO, sqlstate_get_unknown());
 
426
    set_drizzle_error(drizzle, CR_WRONG_HOST_INFO, unknown_sqlstate);
404
427
    return drizzle->net.last_error;
405
428
  }
406
429
  return (char*) drizzle->net.read_pos;
432
455
}
433
456
 
434
457
 
435
 
uint32_t
 
458
uint
436
459
drizzle_get_proto_info(const DRIZZLE *drizzle)
437
460
{
438
461
  return (drizzle->protocol_version);
441
464
const char *
442
465
drizzle_get_client_info(void)
443
466
{
444
 
  return (char*) VERSION;
 
467
  return (char*) DRIZZLE_SERVER_VERSION;
445
468
}
446
469
 
447
470
uint32_t drizzle_get_client_version(void)
493
516
 
494
517
const char * drizzle_sqlstate(const DRIZZLE *drizzle)
495
518
{
496
 
  return drizzle ? drizzle->net.sqlstate : sqlstate_get_cant_connect();
 
519
  return drizzle ? drizzle->net.sqlstate : cant_connect_sqlstate;
497
520
}
498
521
 
499
522
uint32_t drizzle_warning_count(const DRIZZLE *drizzle)
511
534
  return drizzle->thread_id;
512
535
}
513
536
 
 
537
const char * drizzle_character_set_name(const DRIZZLE *drizzle)
 
538
{
 
539
  return drizzle->charset->csname;
 
540
}
 
541
 
 
542
void drizzle_get_character_set_info(const DRIZZLE *drizzle, MY_CHARSET_INFO *csinfo)
 
543
{
 
544
  csinfo->number   = drizzle->charset->number;
 
545
  csinfo->state    = drizzle->charset->state;
 
546
  csinfo->csname   = drizzle->charset->csname;
 
547
  csinfo->name     = drizzle->charset->name;
 
548
  csinfo->comment  = drizzle->charset->comment;
 
549
  csinfo->mbminlen = drizzle->charset->mbminlen;
 
550
  csinfo->mbmaxlen = drizzle->charset->mbmaxlen;
 
551
 
 
552
  if (drizzle->options.charset_dir)
 
553
    csinfo->dir = drizzle->options.charset_dir;
 
554
  else
 
555
    csinfo->dir = charsets_dir;
 
556
}
 
557
 
 
558
uint drizzle_thread_safe(void)
 
559
{
 
560
  return 1;
 
561
}
 
562
 
 
563
 
 
564
bool drizzle_embedded(void)
 
565
{
 
566
#ifdef EMBEDDED_LIBRARY
 
567
  return true;
 
568
#else
 
569
  return false;
 
570
#endif
 
571
}
 
572
 
514
573
/****************************************************************************
515
574
  Some support functions
516
575
****************************************************************************/
521
580
 
522
581
void my_net_local_init(NET *net)
523
582
{
524
 
  net->max_packet=   (uint32_t) net_buffer_length;
 
583
  net->max_packet=   (uint) net_buffer_length;
525
584
  my_net_set_read_timeout(net, CLIENT_NET_READ_TIMEOUT);
526
585
  my_net_set_write_timeout(net, CLIENT_NET_WRITE_TIMEOUT);
527
586
  net->retry_count=  1;
528
 
  net->max_packet_size= (net_buffer_length > max_allowed_packet) ?
529
 
    net_buffer_length : max_allowed_packet;
 
587
  net->max_packet_size= max(net_buffer_length, max_allowed_packet);
530
588
}
531
589
 
532
590
/*
543
601
  Each character needs two bytes, and you need room for the terminating
544
602
  null byte. When drizzle_hex_string() returns, the contents of "to" will
545
603
  be a null-terminated string. The return value is the length of the
546
 
  encoded string, not including the terminating null character.  The return value does not contain any leading 0x or a leading X' and
 
604
  encoded string, not including the terminating null character.
 
605
 
 
606
  The return value does not contain any leading 0x or a leading X' and
547
607
  trailing '. The caller must supply whichever of those is desired.
548
608
*/
549
609
 
571
631
uint32_t
572
632
drizzle_escape_string(char *to,const char *from, uint32_t length)
573
633
{
574
 
  const char *to_start= to;
575
 
  const char *end, *to_end=to_start + 2*length;
576
 
  bool overflow= false;
577
 
  for (end= from + length; from < end; from++)
 
634
  return escape_string_for_drizzle(default_charset_info, to, 0, from, length);
 
635
}
 
636
 
 
637
uint32_t
 
638
drizzle_real_escape_string(DRIZZLE *drizzle, char *to,const char *from,
 
639
       uint32_t length)
 
640
{
 
641
  if (drizzle->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES)
 
642
    return escape_quotes_for_drizzle(drizzle->charset, to, 0, from, length);
 
643
  return escape_string_for_drizzle(drizzle->charset, to, 0, from, length);
 
644
}
 
645
 
 
646
void
 
647
myodbc_remove_escape(const DRIZZLE *drizzle, char *name)
 
648
{
 
649
  char *to;
 
650
#ifdef USE_MB
 
651
  bool use_mb_flag= use_mb(drizzle->charset);
 
652
  char *end=NULL;
 
653
  if (use_mb_flag)
 
654
    for (end=name; *end ; end++) ;
 
655
#endif
 
656
 
 
657
  for (to=name ; *name ; name++)
578
658
  {
579
 
    uint32_t tmp_length;
580
 
    char escape= 0;
581
 
    if (!U8_IS_SINGLE(*from))
 
659
#ifdef USE_MB
 
660
    int l;
 
661
    if (use_mb_flag && (l = my_ismbchar( drizzle->charset, name , end ) ) )
582
662
    {
583
 
      tmp_length= U8_LENGTH(*from);
584
 
      if (to + tmp_length > to_end)
585
 
      {
586
 
        overflow= true;
587
 
        break;
588
 
      }
589
 
      while (tmp_length--)
590
 
        *to++= *from++;
591
 
      from--;
 
663
      while (l--)
 
664
        *to++ = *name++;
 
665
      name--;
592
666
      continue;
593
667
    }
594
 
    switch (*from) {
595
 
    case 0:                             /* Must be escaped for 'mysql' */
596
 
      escape= '0';
597
 
      break;
598
 
    case '\n':                          /* Must be escaped for logs */
599
 
      escape= 'n';
600
 
      break;
601
 
    case '\r':
602
 
      escape= 'r';
603
 
      break;
604
 
    case '\\':
605
 
      escape= '\\';
606
 
      break;
607
 
    case '\'':
608
 
      escape= '\'';
609
 
      break;
610
 
    case '"':                           /* Better safe than sorry */
611
 
      escape= '"';
612
 
      break;
613
 
    case '\032':                        /* This gives problems on Win32 */
614
 
      escape= 'Z';
615
 
      break;
616
 
    }
617
 
    if (escape)
618
 
    {
619
 
      if (to + 2 > to_end)
620
 
      {
621
 
        overflow= true;
622
 
        break;
623
 
      }
624
 
      *to++= '\\';
625
 
      *to++= escape;
626
 
    }
627
 
    else
628
 
    {
629
 
      if (to + 1 > to_end)
630
 
      {
631
 
        overflow= true;
632
 
        break;
633
 
      }
634
 
      *to++= *from;
635
 
    }
 
668
#endif
 
669
    if (*name == '\\' && name[1])
 
670
      name++;
 
671
    *to++= *name;
636
672
  }
637
 
  *to= 0;
638
 
  return overflow ? (size_t) -1 : (size_t) (to - to_start);
 
673
  *to=0;
639
674
}
640
675
 
641
676
int cli_unbuffered_fetch(DRIZZLE *drizzle, char **row)
705
740
{
706
741
  if (drizzle->status != DRIZZLE_STATUS_READY)
707
742
  {
708
 
    drizzle_set_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, sqlstate_get_unknown());
 
743
    set_drizzle_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
709
744
    return(1);
710
745
  }
711
746