~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzle/client.c

  • Committer: Brian Aker
  • Date: 2008-08-18 04:35:40 UTC
  • mfrom: (342 codestyle)
  • mto: This revision was merged to the branch mainline in revision 352.
  • Revision ID: brian@tangent.org-20080818043540-numg7vydi7b0bzcd
Mering Monty's work

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
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; either version 2 of the License, or
9
 
 *  (at your option) any later version.
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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
 
 */
20
 
 
 
1
/* Copyright (C) 2008 Drizzle Open Source Project
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
21
15
 
22
16
/*
23
17
  This file is included by both libdrizzle.c (the DRIZZLE client C API)
30
24
    drizzle_connect()
31
25
  - Support for reading local file with LOAD DATA LOCAL
32
26
  - SHARED memory handling
 
27
  - Protection against sigpipe
33
28
  - Prepared statements
34
29
 
35
30
  - Things that only works for the server
39
34
  server.
40
35
*/
41
36
 
42
 
#include <stdarg.h>
43
 
 
44
37
#include <drizzled/global.h>
45
38
 
46
 
#include "libdrizzle.h"
 
39
#include "drizzle.h"
47
40
 
48
41
#include <sys/poll.h>
49
42
#include <sys/ioctl.h>
56
49
 
57
50
#define CLI_DRIZZLE_CONNECT drizzle_connect
58
51
 
59
 
#include <libdrizzle/errmsg.h>
 
52
#include <mysys/my_sys.h>
 
53
#include <mystrings/m_string.h>
 
54
#include <mystrings/m_ctype.h>
 
55
#include <drizzled/error.h>
 
56
#include "errmsg.h"
60
57
#include <vio/violite.h>
61
58
 
62
59
#include <sys/stat.h>
84
81
 
85
82
#define CONNECT_TIMEOUT 0
86
83
 
 
84
#include "client_settings.h"
87
85
#include <drizzled/version.h>
88
86
#include <libdrizzle/sql_common.h>
89
87
#include <libdrizzle/gettext.h>
90
 
#include "local_infile.h"
91
 
 
92
 
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG |  \
93
 
                             CLIENT_TRANSACTIONS |                      \
94
 
                             CLIENT_SECURE_CONNECTION)
95
88
 
96
89
uint    drizzle_port=0;
 
90
char    *drizzle_unix_port= 0;
97
91
const char  *unknown_sqlstate= "HY000";
98
92
const char  *not_error_sqlstate= "00000";
99
93
const char  *cant_connect_sqlstate= "08001";
107
101
static int wait_for_data(int fd, int32_t timeout);
108
102
int connect_with_timeout(int fd, const struct sockaddr *name, uint namelen, int32_t timeout);
109
103
 
 
104
CHARSET_INFO *default_client_charset_info = &my_charset_latin1;
 
105
 
110
106
/* Server error code and message */
111
107
unsigned int drizzle_server_last_errno;
112
108
char drizzle_server_last_error[DRIZZLE_ERRMSG_SIZE];
292
288
{
293
289
  NET *net= &drizzle->net;
294
290
  uint32_t len=0;
 
291
  init_sigpipe_variables
295
292
 
 
293
  /* Don't give sigpipe errors if the client doesn't want them */
 
294
  set_sigpipe(drizzle);
296
295
  if (net->vio != 0)
297
296
    len=my_net_read(net);
 
297
  reset_sigpipe(drizzle);
298
298
 
299
299
  if (len == packet_error || len == 0)
300
300
  {
303
303
      return (packet_error);
304
304
#endif /*DRIZZLE_SERVER*/
305
305
    end_server(drizzle);
306
 
    set_drizzle_error(drizzle, net->last_errno == CR_NET_PACKET_TOO_LARGE ?
307
 
                      CR_NET_PACKET_TOO_LARGE : CR_SERVER_LOST,
308
 
                      unknown_sqlstate);
 
306
    set_drizzle_error(drizzle, net->last_errno == ER_NET_PACKET_TOO_LARGE ?
 
307
                    CR_NET_PACKET_TOO_LARGE: CR_SERVER_LOST, unknown_sqlstate);
309
308
    return (packet_error);
310
309
  }
311
310
  if (net->read_pos[0] == 255)
356
355
{
357
356
  if (cur)
358
357
  {
359
 
    if (cur->data != NULL)
360
 
    {
361
 
      struct st_drizzle_rows * row= cur->data;
362
 
      uint64_t x;
363
 
      for (x= 0; x< cur->rows; x++)
364
 
      {
365
 
        struct st_drizzle_rows * next_row= row->next;
366
 
        free(row);
367
 
        row= next_row;
368
 
      }
369
 
    }
370
 
    free((uchar*) cur);
 
358
    free_root(&cur->alloc,MYF(0));
 
359
    my_free((uchar*) cur,MYF(0));
371
360
  }
372
361
}
373
362
 
378
367
{
379
368
  NET *net= &drizzle->net;
380
369
  bool result= 1;
 
370
  init_sigpipe_variables
381
371
  bool stmt_skip= false;
382
372
 
 
373
  /* Don't give sigpipe errors if the client doesn't want them */
 
374
  set_sigpipe(drizzle);
 
375
 
383
376
  if (drizzle->net.vio == 0)
384
377
  {            /* Do reconnect if possible */
385
378
    if (drizzle_reconnect(drizzle) || stmt_skip)
405
398
  if (net_write_command(net,(uchar) command, header, header_length,
406
399
      arg, arg_length))
407
400
  {
408
 
    if (net->last_errno == CR_NET_PACKET_TOO_LARGE)
 
401
    if (net->last_errno == ER_NET_PACKET_TOO_LARGE)
409
402
    {
410
403
      set_drizzle_error(drizzle, CR_NET_PACKET_TOO_LARGE, unknown_sqlstate);
411
404
      goto end;
425
418
    result= ((drizzle->packet_length=cli_safe_read(drizzle)) == packet_error ?
426
419
       1 : 0);
427
420
end:
 
421
  reset_sigpipe(drizzle);
428
422
  return(result);
429
423
}
430
424
 
431
425
void free_old_query(DRIZZLE *drizzle)
432
426
{
433
427
  if (drizzle->fields)
434
 
  {
435
 
    /* TODO - we need to de-alloc field storage */
436
 
    free(drizzle->fields->catalog);
437
 
    free(drizzle->fields->db);
438
 
    free(drizzle->fields->table);
439
 
    free(drizzle->fields->org_table);
440
 
    free(drizzle->fields->name);
441
 
    free(drizzle->fields->org_name);
442
 
    free(drizzle->fields->def);
443
 
    free(drizzle->fields);
444
 
 
445
 
  }
446
 
  /* init_alloc_root(&drizzle->field_alloc,8192,0); */ /* Assume rowlength < 8192 */
 
428
    free_root(&drizzle->field_alloc,MYF(0));
 
429
  init_alloc_root(&drizzle->field_alloc,8192,0); /* Assume rowlength < 8192 */
447
430
  drizzle->fields= 0;
448
431
  drizzle->field_count= 0;      /* For API */
449
432
  drizzle->warning_count= 0;
485
468
  int save_errno= errno;
486
469
  if (drizzle->net.vio != 0)
487
470
  {
 
471
    init_sigpipe_variables
 
472
    set_sigpipe(drizzle);
488
473
    vio_delete(drizzle->net.vio);
 
474
    reset_sigpipe(drizzle);
489
475
    drizzle->net.vio= 0;          /* Marker */
490
476
  }
491
477
  net_end(&drizzle->net);
513
499
      }
514
500
    }
515
501
    free_rows(result->data);
516
 
    /* TODO: free result->fields */
 
502
    if (result->fields)
 
503
      free_root(&result->field_alloc,MYF(0));
517
504
    if (result->row)
518
 
      free((uchar*) result->row);
519
 
    free((uchar*) result);
520
 
  }
 
505
      my_free((uchar*) result->row,MYF(0));
 
506
    my_free((uchar*) result,MYF(0));
 
507
  }
 
508
}
 
509
 
 
510
/****************************************************************************
 
511
  Get options from my.cnf
 
512
****************************************************************************/
 
513
 
 
514
static const char *default_options[]=
 
515
{
 
516
  "port","socket","compress","password","pipe", "timeout", "user",
 
517
  "init-command", "host", "database", "return-found-rows",
 
518
  "ssl-key" ,"ssl-cert" ,"ssl-ca" ,"ssl-capath",
 
519
  "character-sets-dir", "default-character-set", "interactive-timeout",
 
520
  "connect-timeout", "local-infile", "disable-local-infile",
 
521
  "ssl-cipher", "max-allowed-packet", "protocol", "shared-memory-base-name",
 
522
  "multi-results", "multi-statements", "multi-queries", "secure-auth",
 
523
  "report-data-truncation",
 
524
  NullS
 
525
};
 
526
 
 
527
static TYPELIB option_types={array_elements(default_options)-1,
 
528
           "options",default_options, NULL};
 
529
 
 
530
const char *sql_protocol_names_lib[] =
 
531
{ "TCP", "SOCKET", "PIPE", "MEMORY", NullS };
 
532
TYPELIB sql_protocol_typelib = {array_elements(sql_protocol_names_lib)-1,"",
 
533
        sql_protocol_names_lib, NULL};
 
534
 
 
535
static int add_init_command(struct st_drizzle_options *options, const char *cmd)
 
536
{
 
537
  char *tmp;
 
538
 
 
539
  if (!options->init_commands)
 
540
  {
 
541
    options->init_commands= (DYNAMIC_ARRAY*)my_malloc(sizeof(DYNAMIC_ARRAY),
 
542
                  MYF(MY_WME));
 
543
    init_dynamic_array(options->init_commands,sizeof(char*),0,5 CALLER_INFO);
 
544
  }
 
545
 
 
546
  if (!(tmp= my_strdup(cmd,MYF(MY_WME))) ||
 
547
      insert_dynamic(options->init_commands, (uchar*)&tmp))
 
548
  {
 
549
    my_free(tmp, MYF(MY_ALLOW_ZERO_PTR));
 
550
    return 1;
 
551
  }
 
552
 
 
553
  return 0;
 
554
}
 
555
 
 
556
void drizzle_read_default_options(struct st_drizzle_options *options,
 
557
        const char *filename,const char *group)
 
558
{
 
559
  int argc;
 
560
  char *argv_buff[1],**argv;
 
561
  const char *groups[3];
 
562
 
 
563
  argc=1; argv=argv_buff; argv_buff[0]= (char*) "client";
 
564
  groups[0]= (char*) "client"; groups[1]= (char*) group; groups[2]=0;
 
565
 
 
566
  load_defaults(filename, groups, &argc, &argv);
 
567
  if (argc != 1)        /* If some default option */
 
568
  {
 
569
    char **option=argv;
 
570
    while (*++option)
 
571
    {
 
572
      if (option[0][0] == '-' && option[0][1] == '-')
 
573
      {
 
574
        char *end=strrchr(*option,'=');
 
575
        char *opt_arg=0;
 
576
        if (end != NULL)
 
577
        {
 
578
          opt_arg=end+1;
 
579
          *end=0;        /* Remove '=' */
 
580
        }
 
581
        /* Change all '_' in variable name to '-' */
 
582
        for (end= *option ; *(end= strrchr(end,'_')) ; )
 
583
          *end= '-';
 
584
        switch (find_type(*option+2,&option_types,2)) {
 
585
        case 1:        /* port */
 
586
          if (opt_arg)
 
587
            options->port=atoi(opt_arg);
 
588
          break;
 
589
        case 2:        /* socket */
 
590
          if (opt_arg)
 
591
          {
 
592
            my_free(options->unix_socket,MYF(MY_ALLOW_ZERO_PTR));
 
593
            options->unix_socket=my_strdup(opt_arg,MYF(MY_WME));
 
594
          }
 
595
          break;
 
596
        case 3:        /* compress */
 
597
          options->compress=1;
 
598
          options->client_flag|= CLIENT_COMPRESS;
 
599
          break;
 
600
        case 4:        /* password */
 
601
          if (opt_arg)
 
602
          {
 
603
            my_free(options->password,MYF(MY_ALLOW_ZERO_PTR));
 
604
            options->password=my_strdup(opt_arg,MYF(MY_WME));
 
605
          }
 
606
          break;
 
607
        case 20:      /* connect_timeout */
 
608
        case 6:        /* timeout */
 
609
          if (opt_arg)
 
610
            options->connect_timeout=atoi(opt_arg);
 
611
          break;
 
612
        case 7:        /* user */
 
613
          if (opt_arg)
 
614
          {
 
615
            my_free(options->user,MYF(MY_ALLOW_ZERO_PTR));
 
616
            options->user=my_strdup(opt_arg,MYF(MY_WME));
 
617
          }
 
618
          break;
 
619
        case 8:        /* init-command */
 
620
          add_init_command(options,opt_arg);
 
621
          break;
 
622
        case 9:        /* host */
 
623
          if (opt_arg)
 
624
          {
 
625
            my_free(options->host,MYF(MY_ALLOW_ZERO_PTR));
 
626
            options->host=my_strdup(opt_arg,MYF(MY_WME));
 
627
          }
 
628
          break;
 
629
        case 10:      /* database */
 
630
          if (opt_arg)
 
631
          {
 
632
            my_free(options->db,MYF(MY_ALLOW_ZERO_PTR));
 
633
            options->db=my_strdup(opt_arg,MYF(MY_WME));
 
634
          }
 
635
          break;
 
636
        case 12:      /* return-found-rows */
 
637
          options->client_flag|=CLIENT_FOUND_ROWS;
 
638
          break;
 
639
        case 13:        /* Ignore SSL options */
 
640
        case 14:
 
641
        case 15:
 
642
        case 16:
 
643
        case 23:
 
644
          break;
 
645
        case 17:      /* charset-lib */
 
646
          my_free(options->charset_dir,MYF(MY_ALLOW_ZERO_PTR));
 
647
          options->charset_dir = my_strdup(opt_arg, MYF(MY_WME));
 
648
          break;
 
649
        case 18:
 
650
          my_free(options->charset_name,MYF(MY_ALLOW_ZERO_PTR));
 
651
          options->charset_name = my_strdup(opt_arg, MYF(MY_WME));
 
652
          break;
 
653
        case 19:        /* Interactive-timeout */
 
654
          options->client_flag|= CLIENT_INTERACTIVE;
 
655
          break;
 
656
        case 21:
 
657
          if (!opt_arg || atoi(opt_arg) != 0)
 
658
            options->client_flag|= CLIENT_LOCAL_FILES;
 
659
          else
 
660
            options->client_flag&= ~CLIENT_LOCAL_FILES;
 
661
          break;
 
662
        case 22:
 
663
          options->client_flag&= ~CLIENT_LOCAL_FILES;
 
664
          break;
 
665
        case 24: /* max-allowed-packet */
 
666
          if (opt_arg)
 
667
            options->max_allowed_packet= atoi(opt_arg);
 
668
          break;
 
669
        case 25: /* protocol */
 
670
          if ((options->protocol= find_type(opt_arg,
 
671
                                            &sql_protocol_typelib,0)) <= 0)
 
672
          {
 
673
            fprintf(stderr, _("Unknown option to protocol: %s\n"), opt_arg);
 
674
            exit(1);
 
675
          }
 
676
          break;
 
677
        case 27: /* multi-results */
 
678
          options->client_flag|= CLIENT_MULTI_RESULTS;
 
679
          break;
 
680
        case 28: /* multi-statements */
 
681
        case 29: /* multi-queries */
 
682
          options->client_flag|= CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS;
 
683
          break;
 
684
        case 30: /* secure-auth */
 
685
          options->secure_auth= true;
 
686
          break;
 
687
        case 31: /* report-data-truncation */
 
688
          options->report_data_truncation= opt_arg ? test(atoi(opt_arg)) : 1;
 
689
          break;
 
690
        default:
 
691
          break;
 
692
        }
 
693
      }
 
694
    }
 
695
  }
 
696
  free_defaults(argv);
 
697
  return;
521
698
}
522
699
 
523
700
 
553
730
***************************************************************************/
554
731
 
555
732
DRIZZLE_FIELD *
556
 
unpack_fields(DRIZZLE_DATA *data, uint fields,
 
733
unpack_fields(DRIZZLE_DATA *data, MEM_ROOT *alloc,uint fields,
557
734
              bool default_value)
558
735
{
559
736
  DRIZZLE_ROWS  *row;
560
737
  DRIZZLE_FIELD  *field,*result;
561
738
  uint32_t lengths[9];        /* Max of fields */
562
739
 
563
 
  field= result= (DRIZZLE_FIELD*) malloc((uint) sizeof(*field)*fields);
 
740
  field= result= (DRIZZLE_FIELD*) alloc_root(alloc,
 
741
             (uint) sizeof(*field)*fields);
564
742
  if (!result)
565
743
  {
566
744
    free_rows(data);        /* Free old data */
574
752
    /* fields count may be wrong */
575
753
    assert((uint) (field - result) < fields);
576
754
    cli_fetch_lengths(&lengths[0], row->data, default_value ? 8 : 7);
577
 
    field->catalog=   strdup((char*) row->data[0]);
578
 
    field->db=        strdup((char*) row->data[1]);
579
 
    field->table=     strdup((char*) row->data[2]);
580
 
    field->org_table= strdup((char*) row->data[3]);
581
 
    field->name=      strdup((char*) row->data[4]);
582
 
    field->org_name=  strdup((char*) row->data[5]);
 
755
    field->catalog=   strmake_root(alloc,(char*) row->data[0], lengths[0]);
 
756
    field->db=        strmake_root(alloc,(char*) row->data[1], lengths[1]);
 
757
    field->table=     strmake_root(alloc,(char*) row->data[2], lengths[2]);
 
758
    field->org_table= strmake_root(alloc,(char*) row->data[3], lengths[3]);
 
759
    field->name=      strmake_root(alloc,(char*) row->data[4], lengths[4]);
 
760
    field->org_name=  strmake_root(alloc,(char*) row->data[5], lengths[5]);
583
761
 
584
762
    field->catalog_length=  lengths[0];
585
763
    field->db_length=    lengths[1];
596
774
    field->flags=  uint2korr(pos+7);
597
775
    field->decimals=  (uint) pos[9];
598
776
 
599
 
    /* Test if field is Internal Number Format */
600
 
    if (((field->type <= DRIZZLE_TYPE_LONGLONG) &&
601
 
         (field->type != DRIZZLE_TYPE_TIMESTAMP)) ||
602
 
        (field->length == 14) ||
603
 
        (field->length == 8))
 
777
    if (INTERNAL_NUM_FIELD(field))
604
778
      field->flags|= NUM_FLAG;
605
779
    if (default_value && row->data[7])
606
780
    {
607
 
      field->def= (char *)malloc(lengths[7]);
608
 
      memcpy(field->def, row->data[7], lengths[7]);
 
781
      field->def=strmake_root(alloc,(char*) row->data[7], lengths[7]);
609
782
      field->def_length= lengths[7];
610
783
    }
611
784
    else
632
805
 
633
806
  if ((pkt_len= cli_safe_read(drizzle)) == packet_error)
634
807
    return(0);
635
 
  if (!(result=(DRIZZLE_DATA*) malloc(sizeof(DRIZZLE_DATA))))
 
808
  if (!(result=(DRIZZLE_DATA*) my_malloc(sizeof(DRIZZLE_DATA),
 
809
               MYF(MY_WME | MY_ZEROFILL))))
636
810
  {
637
811
    set_drizzle_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
638
812
    return(0);
639
813
  }
640
 
  memset(result, 0, sizeof(DRIZZLE_DATA));
 
814
  init_alloc_root(&result->alloc,8192,0);  /* Assume rowlength < 8192 */
 
815
  result->alloc.min_malloc=sizeof(DRIZZLE_ROWS);
641
816
  prev_ptr= &result->data;
642
817
  result->rows=0;
643
818
  result->fields=fields;
652
827
  while (*(cp=net->read_pos) != DRIZZLE_PROTOCOL_NO_MORE_DATA || pkt_len >= 8)
653
828
  {
654
829
    result->rows++;
655
 
    if (!(cur= (DRIZZLE_ROWS*) malloc(sizeof(DRIZZLE_ROWS))) ||
656
 
        !(cur->data= ((DRIZZLE_ROW) malloc((fields+1)*sizeof(char *)+pkt_len))))
 
830
    if (!(cur= (DRIZZLE_ROWS*) alloc_root(&result->alloc,
 
831
          sizeof(DRIZZLE_ROWS))) ||
 
832
  !(cur->data= ((DRIZZLE_ROW)
 
833
          alloc_root(&result->alloc,
 
834
         (fields+1)*sizeof(char *)+pkt_len))))
657
835
    {
658
836
      free_rows(result);
659
837
      set_drizzle_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
772
950
  if (!drizzle_client_init)
773
951
  {
774
952
    drizzle_client_init=true;
 
953
    org_my_init_done=my_init_done;
 
954
 
 
955
    /* Will init threads */
 
956
    if (my_init())
 
957
      return NULL;
775
958
 
776
959
    if (!drizzle_port)
777
960
    {
802
985
    (void) signal(SIGPIPE, SIG_IGN);
803
986
#endif
804
987
  }
 
988
  else
 
989
    /* Init if new thread */
 
990
    if (my_thread_init())
 
991
      return NULL;
805
992
 
806
993
  if (ptr == NULL)
807
994
  {
821
1008
  }
822
1009
 
823
1010
  ptr->options.connect_timeout= CONNECT_TIMEOUT;
 
1011
  ptr->charset=default_client_charset_info;
824
1012
  strcpy(ptr->net.sqlstate, not_error_sqlstate);
825
1013
 
826
1014
  /*
875
1063
 
876
1064
  vio_end();
877
1065
 
 
1066
  /* If library called my_init(), free memory allocated by it */
 
1067
  if (!org_my_init_done)
 
1068
  {
 
1069
    my_end(0);
 
1070
  }
 
1071
  else
 
1072
  {
 
1073
    free_charsets();
 
1074
    drizzle_thread_end();
 
1075
  }
 
1076
 
878
1077
  drizzle_client_init= org_my_init_done= 0;
 
1078
#ifdef EMBEDDED_SERVER
 
1079
  if (stderror_file)
 
1080
  {
 
1081
    fclose(stderror_file);
 
1082
    stderror_file= 0;
 
1083
  }
 
1084
#endif
879
1085
}
880
1086
 
881
1087
 
882
1088
/*
 
1089
  Fill in SSL part of DRIZZLE structure and set 'use_ssl' flag.
 
1090
  NB! Errors are not reported until you do drizzle_connect.
 
1091
*/
 
1092
 
 
1093
#define strdup_if_not_null(A) (A) == 0 ? 0 : my_strdup((A),MYF(MY_WME))
 
1094
 
 
1095
/*
883
1096
  Note that the drizzle argument must be initialized with drizzle_init()
884
1097
  before calling drizzle_connect !
885
1098
*/
894
1107
  cli_read_rows,                               /* read_rows */
895
1108
  cli_use_result,                              /* use_result */
896
1109
  cli_fetch_lengths,                           /* fetch_lengths */
897
 
  cli_flush_use_result,                        /* flush_use_result */
898
 
  cli_list_fields,                             /* list_fields */
 
1110
  cli_flush_use_result,                         /* flush_use_result */
 
1111
#ifndef DRIZZLE_SERVER
 
1112
  cli_list_fields,                            /* list_fields */
899
1113
  cli_unbuffered_fetch,                        /* unbuffered_fetch */
900
1114
  cli_read_statistics,                         /* read_statistics */
901
1115
  cli_read_query_result,                       /* next_result */
902
1116
  cli_read_change_user_result,                 /* read_change_user_result */
 
1117
#else
 
1118
  0,0,0,0,0
 
1119
#endif
903
1120
};
904
1121
 
 
1122
C_MODE_START
 
1123
int drizzle_init_character_set(DRIZZLE *drizzle)
 
1124
{
 
1125
  const char *default_collation_name;
 
1126
 
 
1127
  /* Set character set */
 
1128
  if (!drizzle->options.charset_name)
 
1129
  {
 
1130
    default_collation_name= DRIZZLE_DEFAULT_COLLATION_NAME;
 
1131
    if (!(drizzle->options.charset_name=
 
1132
       my_strdup(DRIZZLE_DEFAULT_CHARSET_NAME,MYF(MY_WME))))
 
1133
    return 1;
 
1134
  }
 
1135
  else
 
1136
    default_collation_name= NULL;
 
1137
 
 
1138
  {
 
1139
    const char *save= charsets_dir;
 
1140
    if (drizzle->options.charset_dir)
 
1141
      charsets_dir=drizzle->options.charset_dir;
 
1142
    drizzle->charset=get_charset_by_csname(drizzle->options.charset_name,
 
1143
                                         MY_CS_PRIMARY, MYF(MY_WME));
 
1144
    if (drizzle->charset && default_collation_name)
 
1145
    {
 
1146
      const CHARSET_INFO *collation;
 
1147
      if ((collation=
 
1148
           get_charset_by_name(default_collation_name, MYF(MY_WME))))
 
1149
      {
 
1150
        if (!my_charset_same(drizzle->charset, collation))
 
1151
        {
 
1152
          my_printf_error(ER_UNKNOWN_ERROR,
 
1153
                         _("COLLATION %s is not valid for CHARACTER SET %s"),
 
1154
                         MYF(0),
 
1155
                         default_collation_name, drizzle->options.charset_name);
 
1156
          drizzle->charset= NULL;
 
1157
        }
 
1158
        else
 
1159
        {
 
1160
          drizzle->charset= collation;
 
1161
        }
 
1162
      }
 
1163
      else
 
1164
        drizzle->charset= NULL;
 
1165
    }
 
1166
    charsets_dir= save;
 
1167
  }
 
1168
 
 
1169
  if (!drizzle->charset)
 
1170
  {
 
1171
    if (drizzle->options.charset_dir)
 
1172
      set_drizzle_extended_error(drizzle, CR_CANT_READ_CHARSET, unknown_sqlstate,
 
1173
                               ER(CR_CANT_READ_CHARSET),
 
1174
                               drizzle->options.charset_name,
 
1175
                               drizzle->options.charset_dir);
 
1176
    else
 
1177
    {
 
1178
      char cs_dir_name[FN_REFLEN];
 
1179
      get_charsets_dir(cs_dir_name);
 
1180
      set_drizzle_extended_error(drizzle, CR_CANT_READ_CHARSET, unknown_sqlstate,
 
1181
                               ER(CR_CANT_READ_CHARSET),
 
1182
                               drizzle->options.charset_name,
 
1183
                               cs_dir_name);
 
1184
    }
 
1185
    return 1;
 
1186
  }
 
1187
  return 0;
 
1188
}
 
1189
C_MODE_END
 
1190
 
905
1191
 
906
1192
DRIZZLE *
907
1193
CLI_DRIZZLE_CONNECT(DRIZZLE *drizzle,const char *host, const char *user,
908
 
                    const char *passwd, const char *db,
909
 
                    uint32_t port,
910
 
                    const char * unix_port __attribute__((__unused__)),
911
 
                    uint32_t client_flag)
 
1194
                       const char *passwd, const char *db,
 
1195
                       uint32_t port, const char *unix_socket, uint32_t client_flag)
912
1196
{
913
1197
  char          buff[NAME_LEN+USERNAME_LENGTH+100];
914
1198
  char          *end,*host_info=NULL;
915
1199
  uint32_t         pkt_length;
916
1200
  NET           *net= &drizzle->net;
 
1201
  init_sigpipe_variables
917
1202
 
 
1203
  /* Don't give sigpipe errors if the client doesn't want them */
 
1204
  set_sigpipe(drizzle);
918
1205
  drizzle->methods= &client_methods;
919
1206
  net->vio = 0;        /* If something goes wrong */
920
1207
  drizzle->client_flag=0;      /* For handshake */
921
1208
 
 
1209
  /* use default options */
 
1210
  if (drizzle->options.my_cnf_file || drizzle->options.my_cnf_group)
 
1211
  {
 
1212
    drizzle_read_default_options(&drizzle->options,
 
1213
             (drizzle->options.my_cnf_file ?
 
1214
        drizzle->options.my_cnf_file : "my"),
 
1215
             drizzle->options.my_cnf_group);
 
1216
    my_free(drizzle->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
 
1217
    my_free(drizzle->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
 
1218
    drizzle->options.my_cnf_file=drizzle->options.my_cnf_group=0;
 
1219
  }
 
1220
 
922
1221
  /* Some empty-string-tests are done because of ODBC */
923
1222
  if (!host || !host[0])
924
1223
    host=drizzle->options.host;
938
1237
    db=drizzle->options.db;
939
1238
  if (!port)
940
1239
    port=drizzle->options.port;
 
1240
  if (!unix_socket)
 
1241
    unix_socket=drizzle->options.unix_socket;
941
1242
 
942
1243
  drizzle->server_status=SERVER_STATUS_AUTOCOMMIT;
943
1244
 
944
1245
  /*
945
1246
    Part 0: Grab a socket and connect it to the server
946
1247
  */
947
 
  if (!net->vio)
 
1248
  if (!net->vio &&
 
1249
      (!drizzle->options.protocol ||
 
1250
       drizzle->options.protocol == DRIZZLE_PROTOCOL_TCP))
948
1251
  {
949
1252
    struct addrinfo *res_lst, hints, *t_res;
950
1253
    int gai_errno;
951
1254
    char port_buf[NI_MAXSERV];
952
1255
 
 
1256
    unix_socket=0;        /* This is not used */
 
1257
 
953
1258
    if (!port)
954
1259
      port= drizzle_port;
955
1260
 
1058
1363
                             PROTOCOL_VERSION);
1059
1364
    goto error;
1060
1365
  }
1061
 
  end= strchr((char*) net->read_pos+1, '\0');
 
1366
  end=strend((char*) net->read_pos+1);
1062
1367
  drizzle->thread_id=uint4korr(end+1);
1063
1368
  end+=5;
1064
1369
  /*
1091
1396
    goto error;
1092
1397
  }
1093
1398
 
 
1399
  if (drizzle_init_character_set(drizzle))
 
1400
    goto error;
 
1401
 
1094
1402
  /* Save connection information */
1095
 
  if (!(drizzle->host_info= (char *)malloc(strlen(host_info)+1+strlen(host)+1
1096
 
                                           +(end - (char*) net->read_pos))) ||
1097
 
      !(drizzle->user=strdup(user)) ||
1098
 
      !(drizzle->passwd=strdup(passwd)))
 
1403
  if (!my_multi_malloc(MYF(0),
 
1404
           &drizzle->host_info, (uint) strlen(host_info)+1,
 
1405
           &drizzle->host,      (uint) strlen(host)+1,
 
1406
           &drizzle->unix_socket,unix_socket ?
 
1407
           (uint) strlen(unix_socket)+1 : (uint) 1,
 
1408
           &drizzle->server_version,
 
1409
           (uint) (end - (char*) net->read_pos),
 
1410
           NullS) ||
 
1411
      !(drizzle->user=my_strdup(user,MYF(0))) ||
 
1412
      !(drizzle->passwd=my_strdup(passwd,MYF(0))))
1099
1413
  {
1100
1414
    set_drizzle_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
1101
1415
    goto error;
1102
1416
  }
1103
 
  drizzle->host= drizzle->host_info+strlen(host_info)+1;
1104
 
  drizzle->server_version= drizzle->host+strlen(host)+1;
1105
1417
  strcpy(drizzle->host_info,host_info);
1106
1418
  strcpy(drizzle->host,host);
 
1419
  if (unix_socket)
 
1420
    strcpy(drizzle->unix_socket,unix_socket);
 
1421
  else
 
1422
    drizzle->unix_socket=0;
1107
1423
  strcpy(drizzle->server_version,(char*) net->read_pos+1);
1108
1424
  drizzle->port=port;
1109
1425
 
1110
1426
  /*
1111
1427
    Part 2: format and send client info to the server for access check
1112
1428
  */
1113
 
 
 
1429
 
1114
1430
  client_flag|=drizzle->options.client_flag;
1115
1431
  client_flag|=CLIENT_CAPABILITIES;
1116
1432
  if (client_flag & CLIENT_MULTI_STATEMENTS)
1127
1443
 
1128
1444
  int4store(buff, client_flag);
1129
1445
  int4store(buff+4, net->max_packet_size);
1130
 
  buff[8]= (char) 45; // utf8 charset number
 
1446
  buff[8]= (char) drizzle->charset->number;
1131
1447
  memset(buff+9, 0, 32-9);
1132
1448
  end= buff+32;
1133
1449
 
1140
1456
    read_user_name((char*) end);
1141
1457
 
1142
1458
  /* We have to handle different version of handshake here */
1143
 
  end= strchr(end, '\0') + 1;
 
1459
  end= strend(end) + 1;
1144
1460
  if (passwd[0])
1145
1461
  {
1146
1462
    {
1157
1473
  if (db && (drizzle->server_capabilities & CLIENT_CONNECT_WITH_DB))
1158
1474
  {
1159
1475
    end= strncpy(end, db, NAME_LEN) + NAME_LEN + 1;
1160
 
    drizzle->db= strdup(db);
 
1476
    drizzle->db= my_strdup(db,MYF(MY_WME));
1161
1477
    db= 0;
1162
1478
  }
1163
1479
  /* Write authentication package */
1196
1512
    goto error;
1197
1513
  }
1198
1514
 
1199
 
 
 
1515
  if (drizzle->options.init_commands)
 
1516
  {
 
1517
    DYNAMIC_ARRAY *init_commands= drizzle->options.init_commands;
 
1518
    char **ptr= (char**)init_commands->buffer;
 
1519
    char **end_command= ptr + init_commands->elements;
 
1520
 
 
1521
    bool reconnect=drizzle->reconnect;
 
1522
    drizzle->reconnect=0;
 
1523
 
 
1524
    for (; ptr < end_command; ptr++)
 
1525
    {
 
1526
      DRIZZLE_RES *res;
 
1527
      if (drizzle_real_query(drizzle,*ptr, (uint32_t) strlen(*ptr)))
 
1528
  goto error;
 
1529
      if (drizzle->fields)
 
1530
      {
 
1531
  if (!(res= cli_use_result(drizzle)))
 
1532
    goto error;
 
1533
  drizzle_free_result(res);
 
1534
      }
 
1535
    }
 
1536
    drizzle->reconnect=reconnect;
 
1537
  }
 
1538
 
 
1539
  reset_sigpipe(drizzle);
1200
1540
  return(drizzle);
1201
1541
 
1202
1542
error:
 
1543
  reset_sigpipe(drizzle);
1203
1544
  {
1204
1545
    /* Free alloced memory */
1205
1546
    end_server(drizzle);
1229
1570
  tmp_drizzle.options.my_cnf_file= tmp_drizzle.options.my_cnf_group= 0;
1230
1571
 
1231
1572
  if (!drizzle_connect(&tmp_drizzle,drizzle->host,drizzle->user,drizzle->passwd,
1232
 
        drizzle->db, drizzle->port, 0,
 
1573
        drizzle->db, drizzle->port, drizzle->unix_socket,
1233
1574
        drizzle->client_flag | CLIENT_REMEMBER_OPTIONS))
1234
1575
  {
1235
1576
    drizzle->net.last_errno= tmp_drizzle.net.last_errno;
1237
1578
    strcpy(drizzle->net.sqlstate, tmp_drizzle.net.sqlstate);
1238
1579
    return(1);
1239
1580
  }
 
1581
  if (drizzle_set_character_set(&tmp_drizzle, drizzle->charset->csname))
 
1582
  {
 
1583
    memset(&tmp_drizzle.options, 0, sizeof(tmp_drizzle.options));
 
1584
    drizzle_close(&tmp_drizzle);
 
1585
    drizzle->net.last_errno= tmp_drizzle.net.last_errno;
 
1586
    strcpy(drizzle->net.last_error, tmp_drizzle.net.last_error);
 
1587
    strcpy(drizzle->net.sqlstate, tmp_drizzle.net.sqlstate);
 
1588
    return(1);
 
1589
  }
1240
1590
 
1241
1591
  tmp_drizzle.reconnect= 1;
1242
1592
  tmp_drizzle.free_me= drizzle->free_me;
1264
1614
  if ((error=simple_command(drizzle,COM_INIT_DB, (const uchar*) db,
1265
1615
                            (uint32_t) strlen(db),0)))
1266
1616
    return(error);
1267
 
  if (drizzle->db != NULL)
1268
 
    free(drizzle->db);
1269
 
  drizzle->db=strdup(db);
 
1617
  my_free(drizzle->db,MYF(MY_ALLOW_ZERO_PTR));
 
1618
  drizzle->db=my_strdup(db,MYF(MY_WME));
1270
1619
  return(0);
1271
1620
}
1272
1621
 
1278
1627
 
1279
1628
static void drizzle_close_free_options(DRIZZLE *drizzle)
1280
1629
{
1281
 
  if (drizzle->options.user != NULL)
1282
 
    free(drizzle->options.user);
1283
 
  if (drizzle->options.host != NULL)
1284
 
    free(drizzle->options.host);
1285
 
  if (drizzle->options.password != NULL)
1286
 
    free(drizzle->options.password);
1287
 
  if (drizzle->options.db != NULL)
1288
 
    free(drizzle->options.db);
1289
 
  if (drizzle->options.my_cnf_file != NULL)
1290
 
    free(drizzle->options.my_cnf_file);
1291
 
  if (drizzle->options.my_cnf_group != NULL)
1292
 
    free(drizzle->options.my_cnf_group);
1293
 
  if (drizzle->options.client_ip != NULL)
1294
 
    free(drizzle->options.client_ip);
 
1630
  my_free(drizzle->options.user,MYF(MY_ALLOW_ZERO_PTR));
 
1631
  my_free(drizzle->options.host,MYF(MY_ALLOW_ZERO_PTR));
 
1632
  my_free(drizzle->options.password,MYF(MY_ALLOW_ZERO_PTR));
 
1633
  my_free(drizzle->options.unix_socket,MYF(MY_ALLOW_ZERO_PTR));
 
1634
  my_free(drizzle->options.db,MYF(MY_ALLOW_ZERO_PTR));
 
1635
  my_free(drizzle->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
 
1636
  my_free(drizzle->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
 
1637
  my_free(drizzle->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR));
 
1638
  my_free(drizzle->options.charset_name,MYF(MY_ALLOW_ZERO_PTR));
 
1639
  my_free(drizzle->options.client_ip,MYF(MY_ALLOW_ZERO_PTR));
 
1640
  if (drizzle->options.init_commands)
 
1641
  {
 
1642
    DYNAMIC_ARRAY *init_commands= drizzle->options.init_commands;
 
1643
    char **ptr= (char**)init_commands->buffer;
 
1644
    char **end= ptr + init_commands->elements;
 
1645
    for (; ptr<end; ptr++)
 
1646
      my_free(*ptr,MYF(MY_WME));
 
1647
    delete_dynamic(init_commands);
 
1648
    my_free((char*)init_commands,MYF(MY_WME));
 
1649
  }
1295
1650
  memset(&drizzle->options, 0, sizeof(drizzle->options));
1296
1651
  return;
1297
1652
}
1299
1654
 
1300
1655
static void drizzle_close_free(DRIZZLE *drizzle)
1301
1656
{
1302
 
  if (drizzle->host_info != NULL)
1303
 
    free((uchar*) drizzle->host_info);
1304
 
  if (drizzle->user != NULL)
1305
 
    free(drizzle->user);
1306
 
  if (drizzle->passwd != NULL)
1307
 
    free(drizzle->passwd);
1308
 
  if (drizzle->db != NULL)
1309
 
    free(drizzle->db);
1310
 
  if (drizzle->info_buffer != NULL)
1311
 
    free(drizzle->info_buffer);
 
1657
  my_free((uchar*) drizzle->host_info,MYF(MY_ALLOW_ZERO_PTR));
 
1658
  my_free(drizzle->user,MYF(MY_ALLOW_ZERO_PTR));
 
1659
  my_free(drizzle->passwd,MYF(MY_ALLOW_ZERO_PTR));
 
1660
  my_free(drizzle->db,MYF(MY_ALLOW_ZERO_PTR));
 
1661
  my_free(drizzle->info_buffer,MYF(MY_ALLOW_ZERO_PTR));
1312
1662
  drizzle->info_buffer= 0;
1313
1663
 
1314
1664
  /* Clear pointers for better safety */
1332
1682
    drizzle_close_free_options(drizzle);
1333
1683
    drizzle_close_free(drizzle);
1334
1684
    if (drizzle->free_me)
1335
 
      free((uchar*) drizzle);
 
1685
      my_free((uchar*) drizzle,MYF(0));
1336
1686
  }
1337
1687
  return;
1338
1688
}
1348
1698
  if ((length = cli_safe_read(drizzle)) == packet_error)
1349
1699
    return(1);
1350
1700
  free_old_query(drizzle);    /* Free old result */
 
1701
#ifdef DRIZZLE_CLIENT      /* Avoid warn of unused labels*/
1351
1702
get_info:
 
1703
#endif
1352
1704
  pos=(uchar*) drizzle->net.read_pos;
1353
1705
  if ((field_count= net_field_length(&pos)) == 0)
1354
1706
  {
1362
1714
      drizzle->info=(char*) pos;
1363
1715
    return(0);
1364
1716
  }
 
1717
#ifdef DRIZZLE_CLIENT
1365
1718
  if (field_count == NULL_LENGTH)    /* LOAD DATA LOCAL INFILE */
1366
1719
  {
1367
1720
    int error;
1377
1730
      return(1);
1378
1731
    goto get_info;        /* Get info packet */
1379
1732
  }
 
1733
#endif
1380
1734
  if (!(drizzle->server_status & SERVER_STATUS_AUTOCOMMIT))
1381
1735
    drizzle->server_status|= SERVER_STATUS_IN_TRANS;
1382
1736
 
1383
1737
  if (!(fields=cli_read_rows(drizzle,(DRIZZLE_FIELD*)0, 7)))
1384
1738
    return(1);
1385
 
  if (!(drizzle->fields= unpack_fields(fields, (uint) field_count, 0)))
 
1739
  if (!(drizzle->fields= unpack_fields(fields,&drizzle->field_alloc,
 
1740
            (uint) field_count, 0)))
1386
1741
    return(1);
1387
1742
  drizzle->status= DRIZZLE_STATUS_GET_RESULT;
1388
1743
  drizzle->field_count= (uint) field_count;
1429
1784
    return(0);
1430
1785
  }
1431
1786
  drizzle->status=DRIZZLE_STATUS_READY;    /* server is ready */
1432
 
  if (!(result=(DRIZZLE_RES*) malloc((uint) (sizeof(DRIZZLE_RES)+
 
1787
  if (!(result=(DRIZZLE_RES*) my_malloc((uint) (sizeof(DRIZZLE_RES)+
1433
1788
                sizeof(uint32_t) *
1434
 
                drizzle->field_count))))
 
1789
                drizzle->field_count),
 
1790
              MYF(MY_WME | MY_ZEROFILL))))
1435
1791
  {
1436
1792
    set_drizzle_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
1437
1793
    return(0);
1438
1794
  }
1439
 
  memset(result, 0,(sizeof(DRIZZLE_RES)+ sizeof(uint32_t) *
1440
 
                    drizzle->field_count));
1441
1795
  result->methods= drizzle->methods;
1442
1796
  result->eof= 1;        /* Marker for buffered */
1443
1797
  result->lengths= (uint32_t*) (result+1);
1444
1798
  if (!(result->data=
1445
1799
  (*drizzle->methods->read_rows)(drizzle,drizzle->fields,drizzle->field_count)))
1446
1800
  {
1447
 
    free((uchar*) result);
 
1801
    my_free((uchar*) result,MYF(0));
1448
1802
    return(0);
1449
1803
  }
1450
1804
  drizzle->affected_rows= result->row_count= result->data->rows;
1451
1805
  result->data_cursor=  result->data->data;
1452
1806
  result->fields=  drizzle->fields;
 
1807
  result->field_alloc=  drizzle->field_alloc;
1453
1808
  result->field_count=  drizzle->field_count;
1454
1809
  /* The rest of result members is zeroed in malloc */
1455
1810
  drizzle->fields=0;        /* fields is now in result */
 
1811
  clear_alloc_root(&drizzle->field_alloc);
1456
1812
  /* just in case this was mistakenly called after drizzle_stmt_execute() */
1457
1813
  drizzle->unbuffered_fetch_owner= 0;
1458
1814
  return(result);        /* Data fetched */
1480
1836
    set_drizzle_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
1481
1837
    return(0);
1482
1838
  }
1483
 
  if (!(result=(DRIZZLE_RES*) malloc(sizeof(*result)+
1484
 
                                     sizeof(uint32_t)*drizzle->field_count)))
 
1839
  if (!(result=(DRIZZLE_RES*) my_malloc(sizeof(*result)+
 
1840
              sizeof(uint32_t)*drizzle->field_count,
 
1841
              MYF(MY_WME | MY_ZEROFILL))))
1485
1842
    return(0);
1486
 
  memset(result, 0, sizeof(*result)+ sizeof(uint32_t)*drizzle->field_count);
1487
1843
  result->lengths=(uint32_t*) (result+1);
1488
1844
  result->methods= drizzle->methods;
1489
1845
  if (!(result->row=(DRIZZLE_ROW)
1490
 
        malloc(sizeof(result->row[0])*(drizzle->field_count+1))))
 
1846
  my_malloc(sizeof(result->row[0])*(drizzle->field_count+1), MYF(MY_WME))))
1491
1847
  {          /* Ptrs: to one row */
1492
 
    free((uchar*) result);
 
1848
    my_free((uchar*) result,MYF(0));
1493
1849
    return(0);
1494
1850
  }
1495
1851
  result->fields=  drizzle->fields;
 
1852
  result->field_alloc=  drizzle->field_alloc;
1496
1853
  result->field_count=  drizzle->field_count;
1497
1854
  result->current_field=0;
1498
1855
  result->handle=  drizzle;
1499
1856
  result->current_row=  0;
1500
1857
  drizzle->fields=0;      /* fields is now in result */
 
1858
  clear_alloc_root(&drizzle->field_alloc);
1501
1859
  drizzle->status=DRIZZLE_STATUS_USE_RESULT;
1502
1860
  drizzle->unbuffered_fetch_owner= &result->unbuffered_fetch_cancelled;
1503
1861
  return(result);      /* Data is read to be fetched */
1596
1954
    else
1597
1955
      drizzle->options.client_flag&= ~CLIENT_LOCAL_FILES;
1598
1956
    break;
 
1957
  case DRIZZLE_INIT_COMMAND:
 
1958
    add_init_command(&drizzle->options,arg);
 
1959
    break;
1599
1960
  case DRIZZLE_READ_DEFAULT_FILE:
1600
 
    if (drizzle->options.my_cnf_file != NULL)
1601
 
      free(drizzle->options.my_cnf_file);
1602
 
    drizzle->options.my_cnf_file=strdup(arg);
 
1961
    my_free(drizzle->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
 
1962
    drizzle->options.my_cnf_file=my_strdup(arg,MYF(MY_WME));
1603
1963
    break;
1604
1964
  case DRIZZLE_READ_DEFAULT_GROUP:
1605
 
    if (drizzle->options.my_cnf_group != NULL)
1606
 
      free(drizzle->options.my_cnf_group);
1607
 
    drizzle->options.my_cnf_group=strdup(arg);
 
1965
    my_free(drizzle->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
 
1966
    drizzle->options.my_cnf_group=my_strdup(arg,MYF(MY_WME));
 
1967
    break;
 
1968
  case DRIZZLE_SET_CHARSET_DIR:
 
1969
    my_free(drizzle->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR));
 
1970
    drizzle->options.charset_dir=my_strdup(arg,MYF(MY_WME));
 
1971
    break;
 
1972
  case DRIZZLE_SET_CHARSET_NAME:
 
1973
    my_free(drizzle->options.charset_name,MYF(MY_ALLOW_ZERO_PTR));
 
1974
    drizzle->options.charset_name=my_strdup(arg,MYF(MY_WME));
1608
1975
    break;
1609
1976
  case DRIZZLE_OPT_PROTOCOL:
 
1977
    drizzle->options.protocol= *(const uint*) arg;
1610
1978
    break;
1611
1979
  case DRIZZLE_OPT_USE_REMOTE_CONNECTION:
1612
1980
  case DRIZZLE_OPT_GUESS_CONNECTION:
1613
1981
    drizzle->options.methods_to_use= option;
1614
1982
    break;
1615
1983
  case DRIZZLE_SET_CLIENT_IP:
1616
 
    drizzle->options.client_ip= strdup(arg);
 
1984
    drizzle->options.client_ip= my_strdup(arg, MYF(MY_WME));
1617
1985
    break;
1618
1986
  case DRIZZLE_SECURE_AUTH:
1619
1987
    drizzle->options.secure_auth= *(const bool *) arg;
1693
2061
  return (uint32_t) major*10000L+(uint32_t) (minor*100+version);
1694
2062
}
1695
2063
 
 
2064
 
 
2065
/*
 
2066
   drizzle_set_character_set function sends SET NAMES cs_name to
 
2067
   the server (which changes character_set_client, character_set_result
 
2068
   and character_set_connection) and updates drizzle->charset so other
 
2069
   functions like drizzle_real_escape will work correctly.
 
2070
*/
 
2071
int drizzle_set_character_set(DRIZZLE *drizzle, const char *cs_name)
 
2072
{
 
2073
  const CHARSET_INFO *cs;
 
2074
  const char *save_csdir= charsets_dir;
 
2075
 
 
2076
  if (drizzle->options.charset_dir)
 
2077
    charsets_dir= drizzle->options.charset_dir;
 
2078
 
 
2079
  if (strlen(cs_name) < MY_CS_NAME_SIZE &&
 
2080
      (cs= get_charset_by_csname(cs_name, MY_CS_PRIMARY, MYF(0))))
 
2081
  {
 
2082
    char buff[MY_CS_NAME_SIZE + 10];
 
2083
    charsets_dir= save_csdir;
 
2084
    sprintf(buff, "SET NAMES %s", cs_name);
 
2085
    if (!drizzle_real_query(drizzle, buff, strlen(buff)))
 
2086
    {
 
2087
      drizzle->charset= cs;
 
2088
    }
 
2089
  }
 
2090
  else
 
2091
  {
 
2092
    char cs_dir_name[FN_REFLEN];
 
2093
    get_charsets_dir(cs_dir_name);
 
2094
    set_drizzle_extended_error(drizzle, CR_CANT_READ_CHARSET, unknown_sqlstate,
 
2095
                             ER(CR_CANT_READ_CHARSET), cs_name, cs_dir_name);
 
2096
  }
 
2097
  charsets_dir= save_csdir;
 
2098
  return drizzle->net.last_errno;
 
2099
}
 
2100
 
 
2101