~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzle.cc

  • Committer: jay
  • Date: 2008-12-23 00:18:10 UTC
  • Revision ID: jay@piggy.tangent.org-20081223001810-026ibij22q2842k1
Had a --regex-replace by accident. Should have been --replace_column call.  Only showed up in make test, not running single test, because InnoDB key numbers were different with multiple test running.

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
 *
34
34
 **/
35
35
 
36
 
#include "config.h"
37
 
 
 
36
#include "client_priv.h"
38
37
#include <string>
39
 
 
40
 
#include "client_priv.h"
 
38
#include CMATH_H
 
39
#include <algorithm>
41
40
#include <mystrings/m_ctype.h>
42
41
#include <stdarg.h>
43
 
#ifndef __GNU_LIBRARY__
44
 
#define __GNU_LIBRARY__          // Skip warnings in getopt.h
45
 
#endif
46
 
#include <readline/history.h>
47
42
#include "my_readline.h"
48
43
#include <signal.h>
49
44
#include <sys/ioctl.h>
 
45
#include <drizzled/configmake.h>
50
46
 
51
47
 
52
48
#if defined(HAVE_LOCALE_H)
53
49
#include <locale.h>
54
50
#endif
55
51
 
56
 
#include <libdrizzle/gettext.h>
 
52
#include <drizzled/gettext.h>
 
53
 
 
54
#if defined(CMATH_NAMESPACE)
 
55
  using namespace CMATH_NAMESPACE;
 
56
#endif
57
57
 
58
58
const char *VER= "14.14";
59
59
 
63
63
/* Buffer to hold 'version' and 'version_comment' */
64
64
#define MAX_SERVER_VERSION_LENGTH     128
65
65
 
66
 
/* Array of options to pass to libdrizzled */
67
 
#define MAX_SERVER_ARGS               64
68
 
 
69
66
void* sql_alloc(unsigned size);       // Don't use drizzled alloc for these
70
67
void sql_element_free(void *ptr);
71
68
 
152
149
typedef enum enum_info_type INFO_TYPE;
153
150
 
154
151
static DRIZZLE drizzle;      /* The connection */
155
 
static bool ignore_errors=0,quick=0,
156
 
  connected=0,opt_raw_data=0,unbuffered=0,output_tables=0,
157
 
  opt_rehash=1,skip_updates=0,safe_updates=0,one_database=0,
158
 
  opt_compress=0, using_opt_local_infile=0,
159
 
  vertical=0, line_numbers=1, column_names=1,
160
 
  opt_nopager=1, opt_outfile=0, named_cmds= 0,
161
 
  tty_password= 0, opt_nobeep=0, opt_reconnect=1,
162
 
  default_charset_used= 0, opt_secure_auth= 0,
163
 
  default_pager_set= 0, opt_sigint_ignore= 0,
164
 
  auto_vertical_output= 0,
165
 
  show_warnings= 0, executing_query= 0, interrupted_query= 0;
 
152
static bool ignore_errors= false, quick= false,
 
153
  connected= false, opt_raw_data= false, unbuffered= false,
 
154
  output_tables= false, opt_rehash= true, skip_updates= false,
 
155
  safe_updates= false, one_database= false,
 
156
  opt_compress= false, using_opt_local_infile= false,
 
157
  vertical= false, line_numbers= true, column_names= true,
 
158
  opt_nopager= true, opt_outfile= false, named_cmds= false,
 
159
  tty_password= false, opt_nobeep= false, opt_reconnect= true,
 
160
  default_charset_used= false, opt_secure_auth= false,
 
161
  default_pager_set= false, opt_sigint_ignore= false,
 
162
  auto_vertical_output= false,
 
163
  show_warnings= false, executing_query= false, interrupted_query= false;
 
164
static uint32_t  show_progress_size= 0;
166
165
static bool debug_info_flag, debug_check_flag;
167
166
static bool column_types_flag;
168
 
static bool preserve_comments= 0;
169
 
static uint32_t opt_max_allowed_packet, opt_net_buffer_length;
170
 
static int verbose=0,opt_silent=0,opt_drizzle_port=0, opt_local_infile=0;
 
167
static bool preserve_comments= false;
 
168
static uint32_t opt_max_allowed_packet, opt_net_buffer_length,
 
169
  opt_drizzle_port= 0;
 
170
static int verbose= 0, opt_silent= 0, opt_local_infile= 0;
171
171
static uint my_end_arg;
172
 
static char * opt_drizzle_unix_port=0;
173
 
static int connect_flag=CLIENT_INTERACTIVE;
174
 
static char *current_host,*current_db,*current_user=0,*opt_password=0,
175
 
  *delimiter_str= 0,* current_prompt= 0;
 
172
static char * opt_drizzle_unix_port= NULL;
 
173
static int connect_flag= CLIENT_INTERACTIVE;
 
174
static char *current_host, *current_db, *current_user= NULL,
 
175
  *opt_password= NULL, *delimiter_str= NULL, *current_prompt= NULL;
176
176
static char *histfile;
177
177
static char *histfile_tmp;
178
178
static string *glob_buffer;
179
179
static string *processed_prompt= NULL;
180
180
static char *default_prompt= NULL;
181
 
static char *full_username=0,*part_username=0;
 
181
static char *full_username= NULL,*part_username= NULL;
182
182
static STATUS status;
183
183
static uint32_t select_limit;
184
184
static uint32_t max_join_size;
185
185
static uint32_t opt_connect_timeout= 0;
186
186
static char drizzle_charsets_dir[FN_REFLEN+1];
187
187
// TODO: Need to i18n these
188
 
static const char *day_names[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
189
 
static const char *month_names[]={"Jan","Feb","Mar","Apr","May","Jun","Jul",
 
188
static const char *day_names[]= {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
 
189
static const char *month_names[]= {"Jan","Feb","Mar","Apr","May","Jun","Jul",
190
190
                                  "Aug","Sep","Oct","Nov","Dec"};
191
191
static char default_pager[FN_REFLEN];
192
192
static char pager[FN_REFLEN], outfile[FN_REFLEN];
210
210
static void tee_print_sized_data(const char *, unsigned int, unsigned int, bool);
211
211
/* The names of functions that actually do the manipulation. */
212
212
static int get_options(int argc,char **argv);
213
 
bool get_one_option(int optid, const struct my_option *opt,
214
 
                    char *argument);
 
213
extern "C" bool get_one_option(int optid, const struct my_option *opt,
 
214
                               char *argument);
215
215
static int com_quit(string *str,const char*),
216
216
  com_go(string *str,const char*), com_ego(string *str,const char*),
217
217
  com_print(string *str,const char*),
610
610
  { "QUARTER", 0, 0, 0, ""},
611
611
  { "QUERY", 0, 0, 0, ""},
612
612
  { "QUICK", 0, 0, 0, ""},
613
 
  { "RAID0", 0, 0, 0, ""},
614
 
  { "RAID_CHUNKS", 0, 0, 0, ""},
615
 
  { "RAID_CHUNKSIZE", 0, 0, 0, ""},
616
 
  { "RAID_TYPE", 0, 0, 0, ""},
617
613
  { "READ", 0, 0, 0, ""},
618
614
  { "READS", 0, 0, 0, ""},
619
615
  { "REAL", 0, 0, 0, ""},
1015
1011
static void end_timer(uint32_t start_time,char *buff);
1016
1012
static void drizzle_end_timer(uint32_t start_time,char *buff);
1017
1013
static void nice_time(double sec,char *buff,bool part_second);
1018
 
extern RETSIGTYPE drizzle_end(int sig);
1019
 
extern RETSIGTYPE handle_sigint(int sig);
 
1014
extern "C" RETSIGTYPE drizzle_end(int sig);
 
1015
extern "C" RETSIGTYPE handle_sigint(int sig);
1020
1016
#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
1021
1017
static RETSIGTYPE window_resize(int sig);
1022
1018
#endif
1035
1031
 
1036
1032
  MY_INIT(argv[0]);
1037
1033
  delimiter_str= delimiter;
1038
 
  default_prompt= my_strdup(getenv("DRIZZLE_PS1") ?
1039
 
                            getenv("DRIZZLE_PS1") :
1040
 
                            "drizzle>> ", MYF(0));
1041
 
  current_prompt= my_strdup(default_prompt, MYF(0));
 
1034
  default_prompt= strdup(getenv("DRIZZLE_PS1") ?
 
1035
                         getenv("DRIZZLE_PS1") :
 
1036
                         "drizzle> ");
 
1037
  
 
1038
  if (default_prompt == NULL)
 
1039
  {
 
1040
    fprintf(stderr, _("Memory allocation error while constructing initial "
 
1041
                      "prompt. Aborting.\n"));
 
1042
    exit(ENOMEM);
 
1043
  }
 
1044
  current_prompt= strdup(default_prompt);
 
1045
  if (current_prompt == NULL)
 
1046
  {
 
1047
    fprintf(stderr, _("Memory allocation error while constructing initial "
 
1048
                      "prompt. Aborting.\n"));
 
1049
    exit(ENOMEM);
 
1050
  }
1042
1051
  processed_prompt= new string();
1043
1052
  processed_prompt->reserve(32);
1044
1053
 
1045
1054
  prompt_counter=0;
1046
1055
 
1047
1056
  outfile[0]=0;      // no (default) outfile
1048
 
  my_stpcpy(pager, "stdout");  // the default, if --pager wasn't given
 
1057
  strcpy(pager, "stdout");  // the default, if --pager wasn't given
1049
1058
  {
1050
1059
    char *tmp=getenv("PAGER");
1051
1060
    if (tmp && strlen(tmp))
1052
1061
    {
1053
1062
      default_pager_set= 1;
1054
 
      my_stpcpy(default_pager, tmp);
 
1063
      strcpy(default_pager, tmp);
1055
1064
    }
1056
1065
  }
1057
1066
  if (!isatty(0) || !isatty(1))
1077
1086
      close(stdout_fileno_copy);             /* Clean up dup(). */
1078
1087
  }
1079
1088
 
1080
 
  load_defaults("my",load_default_groups,&argc,&argv);
 
1089
  load_defaults("drizzle",load_default_groups,&argc,&argv);
1081
1090
  defaults_argv=argv;
1082
1091
  if (get_options(argc, (char **) argv))
1083
1092
  {
1123
1132
 
1124
1133
  glob_buffer= new string();
1125
1134
  glob_buffer->reserve(512);
1126
 
  
 
1135
 
1127
1136
  char * output_buff= (char *)malloc(512);
1128
1137
  memset(output_buff, '\0', 512);
1129
1138
 
1141
1150
      histfile= strdup(getenv("DRIZZLE_HISTFILE"));
1142
1151
    else if (getenv("HOME"))
1143
1152
    {
1144
 
      histfile=(char*) my_malloc((uint) strlen(getenv("HOME"))
1145
 
                                 + (uint) strlen("/.drizzle_history")+2,
1146
 
                                 MYF(MY_WME));
 
1153
      histfile=(char*) malloc(strlen(getenv("HOME")) + strlen("/.drizzle_history") + 2);
1147
1154
      if (histfile)
1148
1155
        sprintf(histfile,"%s/.drizzle_history",getenv("HOME"));
1149
1156
      char link_name[FN_REFLEN];
1160
1167
      if (verbose)
1161
1168
        tee_fprintf(stdout, _("Reading history-file %s\n"),histfile);
1162
1169
      read_history(histfile);
1163
 
      if (!(histfile_tmp= (char*) my_malloc((uint) strlen(histfile) + 5,
1164
 
                                            MYF(MY_WME))))
 
1170
      if (!(histfile_tmp= (char*) malloc((uint) strlen(histfile) + 5)))
1165
1171
      {
1166
1172
        fprintf(stderr, _("Couldn't allocate memory for temp histfile!\n"));
1167
1173
        exit(1);
1224
1230
  If query is in process, kill query
1225
1231
  no query in process, terminate like previous behavior
1226
1232
*/
 
1233
extern "C"
1227
1234
RETSIGTYPE handle_sigint(int sig)
1228
1235
{
1229
1236
  char kill_buffer[40];
1257
1264
 
1258
1265
 
1259
1266
#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
1260
 
RETSIGTYPE window_resize(int sig __attribute__((unused)))
 
1267
RETSIGTYPE window_resize(int)
1261
1268
{
1262
1269
  struct winsize window_size;
1263
1270
 
1360
1367
  {"no-pager", OPT_NOPAGER,
1361
1368
   N_("Disable pager and print to stdout. See interactive help (\\h) also. WARNING: option deprecated; use --disable-pager instead."),
1362
1369
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1363
 
  {"password", 'p',
 
1370
  {"password", 'P',
1364
1371
   N_("Password to use when connecting to server. If password is not given it's asked from the tty."),
1365
1372
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
1366
 
  {"port", 'P', N_("Port number to use for connection or 0 for default to, in order of preference, my.cnf, $DRIZZLE_TCP_PORT, ")
 
1373
  {"port", 'p', N_("Port number to use for connection or 0 for default to, in order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, ")
1367
1374
   N_("built-in default") " (" STRINGIFY_ARG(DRIZZLE_PORT) ").",
1368
 
   (char**) &opt_drizzle_port,
1369
 
   (char**) &opt_drizzle_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,  0},
 
1375
   0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1370
1376
  {"prompt", OPT_PROMPT, N_("Set the drizzle prompt to this value."),
1371
1377
   (char**) &current_prompt, (char**) &current_prompt, 0, GET_STR_ALLOC,
1372
1378
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1373
 
  {"protocol", OPT_DRIZZLE_PROTOCOL, N_("The protocol of connection (tcp,socket,pipe,memory)."),
1374
 
   0, 0, 0, GET_STR,  REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1375
1379
  {"quick", 'q',
1376
1380
   N_("Don't cache result, print it row by row. This may slow down the server if the output is suspended. Doesn't use history file."),
1377
1381
   (char**) &quick, (char**) &quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1437
1441
  {"show-warnings", OPT_SHOW_WARNINGS, N_("Show warnings after every statement."),
1438
1442
   (char**) &show_warnings, (char**) &show_warnings, 0, GET_BOOL, NO_ARG,
1439
1443
   0, 0, 0, 0, 0, 0},
 
1444
  {"show-progress-size", OPT_SHOW_PROGRESS_SIZE, N_("Number of lines before each import progress report."),
 
1445
   (char**) &show_progress_size, (char**) &show_progress_size, 0, GET_ULONG, REQUIRED_ARG,
 
1446
   0, 0, 0, 0, 0, 0},
1440
1447
  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
1441
1448
};
1442
1449
 
1452
1459
 
1453
1460
  if (version)
1454
1461
    return;
1455
 
  printf(_("\
1456
 
Copyright (C) 2000-2008 MySQL AB\n                                      \
1457
 
This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n \
1458
 
and you are welcome to modify and redistribute it under the GPL license\n"));
 
1462
  printf(_("Copyright (C) 2008 Sun Microsystems\n"
 
1463
           "This software comes with ABSOLUTELY NO WARRANTY. "
 
1464
           "This is free software,\n"
 
1465
           "and you are welcome to modify and redistribute it "
 
1466
           "under the GPL license\n"));
1459
1467
  printf(_("Usage: %s [OPTIONS] [database]\n"), my_progname);
1460
1468
  my_print_help(my_long_options);
1461
 
  print_defaults("my", load_default_groups);
 
1469
  print_defaults("drizzle", load_default_groups);
1462
1470
  my_print_variables(my_long_options);
1463
1471
}
1464
1472
 
1465
1473
 
1466
 
bool
1467
 
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
1468
 
               char *argument)
 
1474
extern "C" bool
 
1475
get_one_option(int optid, const struct my_option *, char *argument)
1469
1476
{
 
1477
  char *endchar= NULL;
 
1478
  uint64_t temp_drizzle_port= 0;
 
1479
 
1470
1480
  switch(optid) {
1471
1481
  case OPT_CHARSETS_DIR:
1472
 
    strmake(drizzle_charsets_dir, argument, sizeof(drizzle_charsets_dir) - 1);
 
1482
    strncpy(drizzle_charsets_dir, argument, sizeof(drizzle_charsets_dir) - 1);
1473
1483
    charsets_dir = drizzle_charsets_dir;
1474
1484
    break;
1475
1485
  case  OPT_DEFAULT_CHARSET:
1478
1488
  case OPT_DELIMITER:
1479
1489
    if (argument == disabled_my_option)
1480
1490
    {
1481
 
      my_stpcpy(delimiter, DEFAULT_DELIMITER);
 
1491
      strcpy(delimiter, DEFAULT_DELIMITER);
1482
1492
    }
1483
1493
    else
1484
1494
    {
1485
1495
      /* Check that delimiter does not contain a backslash */
1486
1496
      if (!strstr(argument, "\\"))
1487
1497
      {
1488
 
        strmake(delimiter, argument, sizeof(delimiter) - 1);
 
1498
        strncpy(delimiter, argument, sizeof(delimiter) - 1);
1489
1499
      }
1490
1500
      else
1491
1501
      {
1492
1502
        put_info(_("DELIMITER cannot contain a backslash character"),
1493
1503
                 INFO_ERROR,0,0);
1494
 
        return 0;
 
1504
        return false;
1495
1505
      }
1496
1506
    }
1497
1507
    delimiter_length= (uint)strlen(delimiter);
1498
1508
    delimiter_str= delimiter;
1499
1509
    break;
1500
1510
  case OPT_LOCAL_INFILE:
1501
 
    using_opt_local_infile=1;
 
1511
    using_opt_local_infile= 1;
1502
1512
    break;
1503
1513
  case OPT_TEE:
1504
1514
    if (argument == disabled_my_option)
1523
1533
      if (argument && strlen(argument))
1524
1534
      {
1525
1535
        default_pager_set= 1;
1526
 
        strmake(pager, argument, sizeof(pager) - 1);
1527
 
        my_stpcpy(default_pager, pager);
 
1536
        strncpy(pager, argument, sizeof(pager) - 1);
 
1537
        strcpy(default_pager, pager);
1528
1538
      }
1529
1539
      else if (default_pager_set)
1530
 
        my_stpcpy(pager, default_pager);
 
1540
        strcpy(pager, default_pager);
1531
1541
      else
1532
1542
        opt_nopager= 1;
1533
1543
    }
1560
1570
      one_database= skip_updates= 1;
1561
1571
    break;
1562
1572
  case 'p':
 
1573
    temp_drizzle_port= (uint64_t) strtoul(argument, &endchar, 10);
 
1574
    /* if there is an alpha character this is not a valid port */
 
1575
    if (strlen(endchar) != 0)
 
1576
    {
 
1577
      put_info(_("Non-integer value supplied for port.  If you are trying to enter a password please use --password instead."), INFO_ERROR, 0, 0);
 
1578
      return false;
 
1579
    }
 
1580
    /* If the port number is > 65535 it is not a valid port
 
1581
       This also helps with potential data loss casting unsigned long to a
 
1582
       uint32_t. */
 
1583
    if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
 
1584
    {
 
1585
      put_info(_("Value supplied for port is not valid."), INFO_ERROR, 0, 0);
 
1586
      return false;
 
1587
    }
 
1588
    else
 
1589
    {
 
1590
      opt_drizzle_port= (uint32_t) temp_drizzle_port;
 
1591
    }
 
1592
    break;
 
1593
  case 'P':
 
1594
    /* Don't require password */
1563
1595
    if (argument == disabled_my_option)
1564
 
      argument= (char*) "";      // Don't require password
 
1596
    {
 
1597
      argument= (char*) "";
 
1598
    }
1565
1599
    if (argument)
1566
1600
    {
1567
1601
      char *start= argument;
1568
1602
      free(opt_password);
1569
1603
      opt_password= strdup(argument);
1570
 
      while (*argument) *argument++= 'x';        // Destroy argument
 
1604
      while (*argument)
 
1605
      {
 
1606
        /* Overwriting password with 'x' */
 
1607
        *argument++= 'x';
 
1608
      }
1571
1609
      if (*start)
1572
 
        start[1]=0 ;
 
1610
      {
 
1611
        start[1]= 0;
 
1612
      }
1573
1613
      tty_password= 0;
1574
1614
    }
1575
1615
    else
 
1616
    {
1576
1617
      tty_password= 1;
 
1618
    }
1577
1619
    break;
1578
1620
  case 's':
1579
1621
    if (argument == disabled_my_option)
1592
1634
    status.add_to_history= 0;
1593
1635
    set_if_bigger(opt_silent,1);                         // more silent
1594
1636
    break;
1595
 
    break;
1596
1637
  case 'V':
1597
1638
    usage(1);
1598
1639
    exit(0);
1618
1659
  pagpoint= getenv("PAGER");
1619
1660
  if (!((char*) (pagpoint)))
1620
1661
  {
1621
 
    my_stpcpy(pager, "stdout");
 
1662
    strcpy(pager, "stdout");
1622
1663
    opt_nopager= 1;
1623
1664
  }
1624
1665
  else
1625
 
    my_stpcpy(pager, pagpoint);
1626
 
  my_stpcpy(default_pager, pager);
 
1666
    strcpy(pager, pagpoint);
 
1667
  strcpy(default_pager, pager);
1627
1668
 
1628
1669
  opt_max_allowed_packet= *drizzle_params->p_max_allowed_packet;
1629
1670
  opt_net_buffer_length= *drizzle_params->p_net_buffer_length;
1636
1677
 
1637
1678
  if (status.batch) /* disable pager and outfile in this case */
1638
1679
  {
1639
 
    my_stpcpy(default_pager, "stdout");
1640
 
    my_stpcpy(pager, "stdout");
 
1680
    strcpy(default_pager, "stdout");
 
1681
    strcpy(pager, "stdout");
1641
1682
    opt_nopager= 1;
1642
1683
    default_pager_set= 0;
1643
1684
    opt_outfile= 0;
1691
1732
          (unsigned char) line[2] == 0xBF)
1692
1733
        line+= 3;
1693
1734
      line_number++;
 
1735
      if (show_progress_size > 0)
 
1736
      {
 
1737
        if ((line_number % show_progress_size) == 0)
 
1738
          fprintf(stderr, _("Processing line: %"PRIu32"\n"), line_number);
 
1739
      }
1694
1740
      if (!glob_buffer->empty())
1695
1741
        status.query_start_line=line_number;
1696
1742
    }
2081
2127
 
2082
2128
 
2083
2129
static char **mysql_completion (const char *text, int start, int end);
2084
 
static char *new_command_generator(const char *text, int);
 
2130
extern "C" char *new_command_generator(const char *text, int);
2085
2131
 
2086
2132
/*
2087
2133
  Tell the GNU Readline library how to complete.  We want to try to complete
2088
2134
  on command names if this is the first word in the line, or on filenames
2089
2135
  if not.
2090
2136
*/
2091
 
static char *no_completion(const char * a __attribute__((unused)),
2092
 
                           int b __attribute__((unused)))
 
2137
static char *no_completion(const char *, int)
2093
2138
{
2094
2139
  /* No filename completion */
2095
2140
  return 0;
2184
2229
  entire line in case we want to do some simple parsing.  Return the
2185
2230
  array of matches, or NULL if there aren't any.
2186
2231
*/
2187
 
char **mysql_completion (const char *text,
2188
 
                        int start __attribute__((unused)),
2189
 
                        int end __attribute__((unused)))
 
2232
char **mysql_completion (const char *text, int, int)
2190
2233
{
2191
2234
  if (!status.batch && !quick)
2192
2235
    return rl_completion_matches(text, new_command_generator);
2194
2237
    return (char**) 0;
2195
2238
}
2196
2239
 
2197
 
 
2198
 
static char *new_command_generator(const char *text,int state)
 
2240
extern "C"
 
2241
char *new_command_generator(const char *text,int state)
2199
2242
{
2200
2243
  static int textlen;
2201
2244
  char *ptr;
2499
2542
}
2500
2543
 
2501
2544
 
2502
 
static int com_server_help(string *buffer,
2503
 
                           const char *line __attribute__((unused)),
2504
 
                           char *help_arg)
 
2545
static int com_server_help(string *buffer, const char *, const char *help_arg)
2505
2546
{
2506
2547
  DRIZZLE_ROW cur;
2507
2548
  const char *server_cmd= buffer->c_str();
2508
 
  char cmd_buf[100];
 
2549
  string cmd_buf;
2509
2550
  DRIZZLE_RES *result;
2510
2551
  int error;
2511
2552
 
 
2553
  cmd_buf.reserve(100);
2512
2554
  if (help_arg[0] != '\'')
2513
2555
  {
2514
 
    char *end_arg= strchr(help_arg, '\0');
 
2556
    const char *end_arg= strchr(help_arg, '\0');
2515
2557
    if(--end_arg)
2516
2558
    {
2517
2559
      while (my_isspace(charset_info,*end_arg))
2518
2560
        end_arg--;
2519
 
      *++end_arg= '\0';
2520
2561
    }
2521
 
    (void) strxnmov(cmd_buf, sizeof(cmd_buf), "help '", help_arg, "'", NULL);
2522
 
    server_cmd= cmd_buf;
 
2562
    cmd_buf.append("help '");
 
2563
    cmd_buf.append(help_arg, end_arg-help_arg);
 
2564
    cmd_buf.append("'");
 
2565
 
 
2566
    server_cmd= cmd_buf.c_str();
2523
2567
  }
2524
2568
 
2525
2569
  if (!connected && reconnect())
2591
2635
}
2592
2636
 
2593
2637
static int
2594
 
com_help(string *buffer __attribute__((unused)),
2595
 
         const char *line __attribute__((unused)))
 
2638
com_help(string *buffer, const char *line)
2596
2639
{
2597
2640
  register int i, j;
2598
 
  char * help_arg= strchr(line,' '), buff[32], *end;
 
2641
  const char *help_arg= strchr(line,' ');
 
2642
  char buff[32], *end;
2599
2643
  if (help_arg)
2600
2644
  {
2601
2645
    while (my_isspace(charset_info,*help_arg))
2608
2652
    put_info(_("Note that all text commands must be first on line and end with ';'"),INFO_INFO,0,0);
2609
2653
  for (i = 0; commands[i].name; i++)
2610
2654
  {
2611
 
    end= my_stpcpy(buff, commands[i].name);
 
2655
    end= strcpy(buff, commands[i].name);
 
2656
    end+= strlen(commands[i].name);
2612
2657
    for (j= (int)strlen(commands[i].name); j < 10; j++)
2613
 
      end= my_stpcpy(end, " ");
 
2658
      end= strcpy(end, " ")+1;
2614
2659
    if (commands[i].func)
2615
2660
      tee_fprintf(stdout, "%s(\\%c) %s\n", buff,
2616
2661
                  commands[i].cmd_char, _(commands[i].doc));
2622
2667
 
2623
2668
 
2624
2669
static int
2625
 
com_clear(string *buffer,
2626
 
          const char *line __attribute__((unused)))
 
2670
com_clear(string *buffer, const char *)
2627
2671
{
2628
2672
  if (status.add_to_history)
2629
2673
    fix_history(buffer);
2639
2683
  1  if fatal error
2640
2684
*/
2641
2685
static int
2642
 
com_go(string *buffer,
2643
 
       const char *line __attribute__((unused)))
 
2686
com_go(string *buffer, const char *)
2644
2687
{
2645
2688
  char          buff[200]; /* about 110 chars used so far */
2646
2689
  char          time_buff[52+3+1]; /* time max + space&parens + NUL */
2723
2766
    {
2724
2767
      if (!drizzle_num_rows(result) && ! quick && !column_types_flag)
2725
2768
      {
2726
 
        my_stpcpy(buff, _("Empty set"));
 
2769
        strcpy(buff, _("Empty set"));
2727
2770
      }
2728
2771
      else
2729
2772
      {
2745
2788
      }
2746
2789
    }
2747
2790
    else if (drizzle_affected_rows(&drizzle) == ~(uint64_t) 0)
2748
 
      my_stpcpy(buff,_("Query OK"));
 
2791
      strcpy(buff,_("Query OK"));
2749
2792
    else
2750
2793
      sprintf(buff, ngettext("Query OK, %ld row affected",
2751
2794
                             "Query OK, %ld rows affected",
2757
2800
    {
2758
2801
      *pos++= ',';
2759
2802
      *pos++= ' ';
2760
 
      pos=int10_to_str(warnings, pos, 10);
2761
 
      pos=my_stpcpy(pos, " warning");
 
2803
      pos= int10_to_str(warnings, pos, 10);
 
2804
      pos= strcpy(pos, " warning")+8;
2762
2805
      if (warnings != 1)
2763
2806
        *pos++= 's';
2764
2807
    }
2765
 
    my_stpcpy(pos, time_buff);
 
2808
    strcpy(pos, time_buff);
2766
2809
    put_info(buff,INFO_RESULT,0,0);
2767
2810
    if (drizzle_info(&drizzle))
2768
2811
      put_info(drizzle_info(&drizzle),INFO_RESULT,0,0);
2824
2867
    return;
2825
2868
  }
2826
2869
  OUTFILE = new_outfile;
2827
 
  strmake(outfile, file_name, FN_REFLEN-1);
 
2870
  strncpy(outfile, file_name, FN_REFLEN-1);
2828
2871
  tee_fprintf(stdout, "Logging to file '%s'\n", file_name);
2829
2872
  opt_outfile= 1;
2830
2873
  return;
2856
2899
{
2857
2900
  switch (type) {
2858
2901
    case DRIZZLE_TYPE_BLOB:        return "BLOB";
2859
 
    case DRIZZLE_TYPE_NEWDATE:        return "DATE";
 
2902
    case DRIZZLE_TYPE_DATE:        return "DATE";
2860
2903
    case DRIZZLE_TYPE_DATETIME:    return "DATETIME";
2861
2904
    case DRIZZLE_TYPE_NEWDECIMAL:  return "DECIMAL";
2862
2905
    case DRIZZLE_TYPE_DOUBLE:      return "DOUBLE";
2867
2910
    case DRIZZLE_TYPE_TIME:        return "TIME";
2868
2911
    case DRIZZLE_TYPE_TIMESTAMP:   return "TIMESTAMP";
2869
2912
    case DRIZZLE_TYPE_TINY:        return "TINY";
 
2913
    case DRIZZLE_TYPE_VIRTUAL:     return "VIRTUAL";
2870
2914
    default:                     return "?-unknown-?";
2871
2915
  }
2872
2916
}
2876
2920
  char *s=buf;
2877
2921
  *s=0;
2878
2922
#define ff2s_check_flag(X)                                              \
2879
 
  if (f & X ## _FLAG) { s=my_stpcpy(s, # X " "); f &= ~ X ## _FLAG; }
 
2923
  if (f & X ## _FLAG) { s=strcpy(s, # X " ")+strlen(# X " "); \
 
2924
                        f &= ~ X ## _FLAG; }
2880
2925
  ff2s_check_flag(NOT_NULL);
2881
2926
  ff2s_check_flag(PRI_KEY);
2882
2927
  ff2s_check_flag(UNIQUE_KEY);
2938
2983
  DRIZZLE_FIELD   *field;
2939
2984
  bool          *num_flag;
2940
2985
  string separator;
2941
 
  
 
2986
 
2942
2987
  separator.reserve(256);
2943
2988
 
2944
 
  num_flag=(bool*) my_malloc(sizeof(bool)*drizzle_num_fields(result),
2945
 
                             MYF(MY_WME));
 
2989
  num_flag=(bool*) malloc(sizeof(bool)*drizzle_num_fields(result));
2946
2990
  if (column_types_flag)
2947
2991
  {
2948
2992
    print_field_types(result);
2983
3027
      tee_fprintf(PAGER, " %-*s |",(int) min(display_length,
2984
3028
                                             MAX_COLUMN_LENGTH),
2985
3029
                  field->name);
2986
 
      num_flag[off]= ((field->type <= DRIZZLE_TYPE_LONGLONG) || 
 
3030
      num_flag[off]= ((field->type <= DRIZZLE_TYPE_LONGLONG) ||
2987
3031
                      (field->type == DRIZZLE_TYPE_NEWDECIMAL));
2988
3032
    }
2989
3033
    (void) tee_fputs("\n", PAGER);
3066
3110
*/
3067
3111
static int get_field_disp_length(DRIZZLE_FIELD *field)
3068
3112
{
3069
 
  uint length= column_names ? field->name_length : 0;
 
3113
  uint32_t length= column_names ? field->name_length : 0;
3070
3114
 
3071
3115
  if (quick)
3072
3116
    length= max(length, field->length);
3175
3219
  DRIZZLE_RES    *result;
3176
3220
  DRIZZLE_ROW    cur;
3177
3221
  uint64_t num_rows;
3178
 
 
 
3222
 
3179
3223
  /* Save current error before calling "show warnings" */
3180
3224
  uint error= drizzle_errno(&drizzle);
3181
3225
 
3281
3325
}
3282
3326
 
3283
3327
static int
3284
 
com_tee(string *buffer __attribute__((unused)), const char *line )
 
3328
com_tee(string *, const char *line )
3285
3329
{
3286
 
  char file_name[FN_REFLEN], *end, *param;
 
3330
  char file_name[FN_REFLEN], *end;
 
3331
  const char *param;
3287
3332
 
3288
3333
  if (status.batch)
3289
3334
    return 0;
3308
3353
  /* eliminate the spaces before the parameters */
3309
3354
  while (my_isspace(charset_info,*param))
3310
3355
    param++;
3311
 
  end= strmake(file_name, param, sizeof(file_name) - 1);
 
3356
  strncpy(file_name, param, sizeof(file_name) - 1);
 
3357
  end= file_name + strlen(file_name);
3312
3358
  /* remove end space from command line */
3313
3359
  while (end > file_name && (my_isspace(charset_info,end[-1]) ||
3314
3360
                             my_iscntrl(charset_info,end[-1])))
3325
3371
 
3326
3372
 
3327
3373
static int
3328
 
com_notee(string *buffer __attribute__((unused)),
3329
 
          const char *line __attribute__((unused)))
 
3374
com_notee(string *, const char *)
3330
3375
{
3331
3376
  if (opt_outfile)
3332
3377
    end_tee();
3339
3384
*/
3340
3385
 
3341
3386
static int
3342
 
com_pager(string *buffer __attribute__((unused)),
3343
 
          const char *line __attribute__((unused)))
 
3387
com_pager(string *, const char *line)
3344
3388
{
3345
 
  char pager_name[FN_REFLEN], *end, *param;
 
3389
  char pager_name[FN_REFLEN], *end;
 
3390
  const char *param;
3346
3391
 
3347
3392
  if (status.batch)
3348
3393
    return 0;
3360
3405
    {
3361
3406
      tee_fprintf(stdout, "Default pager wasn't set, using stdout.\n");
3362
3407
      opt_nopager=1;
3363
 
      my_stpcpy(pager, "stdout");
 
3408
      strcpy(pager, "stdout");
3364
3409
      PAGER= stdout;
3365
3410
      return 0;
3366
3411
    }
3367
 
    my_stpcpy(pager, default_pager);
 
3412
    strcpy(pager, default_pager);
3368
3413
  }
3369
3414
  else
3370
3415
  {
3371
 
    end= strmake(pager_name, param, sizeof(pager_name)-1);
 
3416
    end= strncpy(pager_name, param, sizeof(pager_name)-1);
 
3417
    end+= strlen(pager_name);
3372
3418
    while (end > pager_name && (my_isspace(charset_info,end[-1]) ||
3373
3419
                                my_iscntrl(charset_info,end[-1])))
3374
3420
      end--;
3375
3421
    end[0]=0;
3376
 
    my_stpcpy(pager, pager_name);
3377
 
    my_stpcpy(default_pager, pager_name);
 
3422
    strcpy(pager, pager_name);
 
3423
    strcpy(default_pager, pager_name);
3378
3424
  }
3379
3425
  opt_nopager=0;
3380
3426
  tee_fprintf(stdout, "PAGER set to '%s'\n", pager);
3383
3429
 
3384
3430
 
3385
3431
static int
3386
 
com_nopager(string *buffer __attribute__((unused)),
3387
 
            const char *line __attribute__((unused)))
 
3432
com_nopager(string *, const char *)
3388
3433
{
3389
 
  my_stpcpy(pager, "stdout");
 
3434
  strcpy(pager, "stdout");
3390
3435
  opt_nopager=1;
3391
3436
  PAGER= stdout;
3392
3437
  tee_fprintf(stdout, "PAGER set to stdout\n");
3396
3441
/* If arg is given, exit without errors. This happens on command 'quit' */
3397
3442
 
3398
3443
static int
3399
 
com_quit(string *buffer __attribute__((unused)),
3400
 
         const char *line __attribute__((unused)))
 
3444
com_quit(string *, const char *)
3401
3445
{
3402
3446
  /* let the screen auto close on a normal shutdown */
3403
3447
  status.exit_status=0;
3405
3449
}
3406
3450
 
3407
3451
static int
3408
 
com_rehash(string *buffer __attribute__((unused)),
3409
 
           const char *line __attribute__((unused)))
 
3452
com_rehash(string *, const char *)
3410
3453
{
3411
3454
  build_completion_hash(1, 0);
3412
3455
  return 0;
3415
3458
 
3416
3459
 
3417
3460
static int
3418
 
com_print(string *buffer,const char *line __attribute__((unused)))
 
3461
com_print(string *buffer,const char *)
3419
3462
{
3420
3463
  tee_puts("--------------", stdout);
3421
3464
  (void) tee_fputs(buffer->c_str(), stdout);
3442
3485
      Two null bytes are needed in the end of buff to allow
3443
3486
      get_arg to find end of string the second time it's called.
3444
3487
    */
3445
 
    tmp= strmake(buff, line, sizeof(buff)-2);
 
3488
    tmp= strncpy(buff, line, sizeof(buff)-2);
3446
3489
#ifdef EXTRA_DEBUG
3447
3490
    tmp[1]= 0;
3448
3491
#endif
3484
3527
}
3485
3528
 
3486
3529
 
3487
 
static int com_source(string *buffer __attribute__((unused)), const char *line)
 
3530
static int com_source(string *, const char *line)
3488
3531
{
3489
 
  char source_name[FN_REFLEN], *end, *param;
 
3532
  char source_name[FN_REFLEN], *end;
 
3533
  const char *param;
3490
3534
  LINE_BUFFER *line_buff;
3491
3535
  int error;
3492
3536
  STATUS old_status;
3500
3544
                    INFO_ERROR, 0,0);
3501
3545
  while (my_isspace(charset_info,*param))
3502
3546
    param++;
3503
 
  end=strmake(source_name,param,sizeof(source_name)-1);
 
3547
  end= strncpy(source_name,param,sizeof(source_name)-1);
 
3548
  end+= strlen(source_name);
3504
3549
  while (end > source_name && (my_isspace(charset_info,end[-1]) ||
3505
3550
                               my_iscntrl(charset_info,end[-1])))
3506
3551
    end--;
3507
3552
  end[0]=0;
3508
3553
  unpack_filename(source_name,source_name);
3509
3554
  /* open file name */
3510
 
  if (!(sql_file = my_fopen(source_name, O_RDONLY | O_BINARY,MYF(0))))
 
3555
  if (!(sql_file = my_fopen(source_name, O_RDONLY,MYF(0))))
3511
3556
  {
3512
3557
    char buff[FN_REFLEN+60];
3513
3558
    sprintf(buff,"Failed to open file '%s', error: %d", source_name,errno);
3542
3587
 
3543
3588
/* ARGSUSED */
3544
3589
static int
3545
 
com_delimiter(string *buffer __attribute__((unused)), const char *line)
 
3590
com_delimiter(string *, const char *line)
3546
3591
{
3547
3592
  char buff[256], *tmp;
3548
3593
 
3549
 
  strmake(buff, line, sizeof(buff) - 1);
 
3594
  strncpy(buff, line, sizeof(buff) - 1);
3550
3595
  tmp= get_arg(buff, 0);
3551
3596
 
3552
3597
  if (!tmp || !*tmp)
3564
3609
      return 0;
3565
3610
    }
3566
3611
  }
3567
 
  strmake(delimiter, tmp, sizeof(delimiter) - 1);
 
3612
  strncpy(delimiter, tmp, sizeof(delimiter) - 1);
3568
3613
  delimiter_length= (int)strlen(delimiter);
3569
3614
  delimiter_str= delimiter;
3570
3615
  return 0;
3572
3617
 
3573
3618
/* ARGSUSED */
3574
3619
static int
3575
 
com_use(string *buffer __attribute__((unused)), const char *line)
 
3620
com_use(string *, const char *line)
3576
3621
{
3577
3622
  char *tmp, buff[FN_REFLEN + 1];
3578
3623
  int select_db;
3579
3624
 
3580
3625
  memset(buff, 0, sizeof(buff));
3581
 
  strmake(buff, line, sizeof(buff) - 1);
 
3626
  strncpy(buff, line, sizeof(buff) - 1);
3582
3627
  tmp= get_arg(buff, 0);
3583
3628
  if (!tmp || !*tmp)
3584
3629
  {
3644
3689
}
3645
3690
 
3646
3691
static int
3647
 
com_warnings(string *buffer __attribute__((unused)),
3648
 
             const char *line __attribute__((unused)))
 
3692
com_warnings(string *, const char *)
3649
3693
{
3650
3694
  show_warnings = 1;
3651
3695
  put_info("Show warnings enabled.",INFO_INFO, 0, 0);
3653
3697
}
3654
3698
 
3655
3699
static int
3656
 
com_nowarnings(string *buffer __attribute__((unused)),
3657
 
               const char *line __attribute__((unused)))
 
3700
com_nowarnings(string *, const char *)
3658
3701
{
3659
3702
  show_warnings = 0;
3660
3703
  put_info("Show warnings disabled.",INFO_INFO, 0, 0);
3710
3753
    if (*ptr == '\\' && ptr[1]) // escaped character
3711
3754
    {
3712
3755
      // Remove the backslash
3713
 
      my_stpcpy(ptr, ptr+1);
 
3756
      strcpy(ptr, ptr+1);
3714
3757
    }
3715
3758
    else if ((!quoted && *ptr == ' ') || (quoted && *ptr == qtype))
3716
3759
    {
3750
3793
    char init_command[100];
3751
3794
    sprintf(init_command,
3752
3795
            "SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=%"PRIu32
3753
 
            ",SQL_MAX_JOIN_SIZE=%"PRIu32,
 
3796
            ",MAX_JOIN_SIZE=%"PRIu32,
3754
3797
            select_limit, max_join_size);
3755
3798
    drizzle_options(&drizzle, DRIZZLE_INIT_COMMAND, init_command);
3756
3799
  }
3776
3819
 
3777
3820
 
3778
3821
static int
3779
 
com_status(string *buffer __attribute__((unused)),
3780
 
           const char *line __attribute__((unused)))
 
3822
com_status(string *, const char *)
3781
3823
{
3782
3824
  char buff[40];
3783
3825
  uint64_t id;
3868
3910
static const char *
3869
3911
server_version_string(DRIZZLE *con)
3870
3912
{
3871
 
  static char buf[MAX_SERVER_VERSION_LENGTH] = "";
 
3913
  static string buf("");
 
3914
  static bool server_version_string_reserved= false;
3872
3915
 
 
3916
  if (!server_version_string_reserved)
 
3917
  {
 
3918
    buf.reserve(MAX_SERVER_VERSION_LENGTH);
 
3919
    server_version_string_reserved= true;
 
3920
  }
3873
3921
  /* Only one thread calls this, so no synchronization is needed */
3874
3922
  if (buf[0] == '\0')
3875
3923
  {
3876
 
    char *bufp = buf;
3877
3924
    DRIZZLE_RES *result;
3878
3925
 
3879
 
    bufp= my_stpncpy(buf, drizzle_get_server_info(con), sizeof buf);
 
3926
    buf.append(drizzle_get_server_info(con));
3880
3927
 
3881
3928
    /* "limit 1" is protection against SQL_SELECT_LIMIT=0 */
3882
3929
    if (!drizzle_query(con, "select @@version_comment limit 1") &&
3885
3932
      DRIZZLE_ROW cur = drizzle_fetch_row(result);
3886
3933
      if (cur && cur[0])
3887
3934
      {
3888
 
        bufp = strxnmov(bufp, sizeof buf - (bufp - buf), " ", cur[0], NULL);
 
3935
        buf.append(" ");
 
3936
        buf.append(cur[0]);
3889
3937
      }
3890
3938
      drizzle_free_result(result);
3891
3939
    }
3892
 
 
3893
 
    /* str*nmov doesn't guarantee NUL-termination */
3894
 
    if (bufp == buf + sizeof buf)
3895
 
      buf[sizeof buf - 1] = '\0';
3896
3940
  }
3897
3941
 
3898
 
  return buf;
 
3942
  return buf.c_str();
3899
3943
}
3900
3944
 
3901
3945
static int
4058
4102
  if (sec >= 3600.0*24)
4059
4103
  {
4060
4104
    tmp=(uint32_t) floor(sec/(3600.0*24));
4061
 
    sec-=3600.0*24*tmp;
4062
 
    buff=int10_to_str((long) tmp, buff, 10);
4063
 
    buff=my_stpcpy(buff,tmp > 1 ? " days " : " day ");
 
4105
    sec-= 3600.0*24*tmp;
 
4106
    buff= int10_to_str((long) tmp, buff, 10);
 
4107
 
 
4108
    if (tmp > 1)
 
4109
      buff= strcpy(buff," days ")+6;
 
4110
    else
 
4111
      buff= strcpy(buff," day ")+5;
 
4112
 
4064
4113
  }
4065
4114
  if (sec >= 3600.0)
4066
4115
  {
4067
4116
    tmp=(uint32_t) floor(sec/3600.0);
4068
4117
    sec-=3600.0*tmp;
4069
4118
    buff=int10_to_str((long) tmp, buff, 10);
4070
 
    buff=my_stpcpy(buff,tmp > 1 ? " hours " : " hour ");
 
4119
 
 
4120
    if (tmp > 1)
 
4121
      buff= strcpy(buff, " hours ")+7;
 
4122
    else
 
4123
      buff= strcpy(buff, " hour ")+6;
4071
4124
  }
4072
4125
  if (sec >= 60.0)
4073
4126
  {
4074
4127
    tmp=(uint32_t) floor(sec/60.0);
4075
4128
    sec-=60.0*tmp;
4076
4129
    buff=int10_to_str((long) tmp, buff, 10);
4077
 
    buff=my_stpcpy(buff," min ");
 
4130
    buff= strcpy(buff," min ")+5;
4078
4131
  }
4079
4132
  if (part_second)
4080
4133
    sprintf(buff,"%.2f sec",sec);
4095
4148
  buff[0]=' ';
4096
4149
  buff[1]='(';
4097
4150
  end_timer(start_time,buff+2);
4098
 
  my_stpcpy(strchr(buff, '\0'),")");
 
4151
  strcpy(strchr(buff, '\0'),")");
4099
4152
}
4100
4153
 
4101
4154
static const char * construct_prompt()
4188
4241
        break;
4189
4242
      case PROMPT_CHAR:
4190
4243
        {
4191
 
          char c= PROMPT_CHAR;
4192
 
          processed_prompt->append(&c, 1);
 
4244
          processed_prompt->append(PROMPT_CHAR, 1);
4193
4245
        }
4194
4246
        break;
4195
4247
      case 'n':
4196
4248
        {
4197
 
          char c= '\n';
4198
 
          processed_prompt->append(&c, 1);
 
4249
          processed_prompt->append('\n', 1);
4199
4250
        }
4200
4251
        break;
4201
4252
      case ' ':
4202
4253
      case '_':
4203
4254
        {
4204
 
          char c= ' ';
4205
 
          processed_prompt->append(&c, 1);
 
4255
          processed_prompt->append(' ', 1);
4206
4256
        }
4207
4257
        break;
4208
4258
      case 'R':
4300
4350
  }
4301
4351
}
4302
4352
 
4303
 
static int com_prompt(string *buffer __attribute__((unused)),
4304
 
                      const char *line)
 
4353
static int com_prompt(string *, const char *line)
4305
4354
{
4306
 
  char *ptr=strchr(line, ' ');
4307
 
  prompt_counter = 0;
4308
 
  free(current_prompt);
4309
 
  current_prompt= strdup(ptr ? ptr+1 : default_prompt);
4310
 
  if (!ptr)
 
4355
  const char *ptr=strchr(line, ' ');
 
4356
  if (ptr == NULL)
4311
4357
    tee_fprintf(stdout, "Returning to default PROMPT of %s\n",
4312
4358
                default_prompt);
 
4359
  prompt_counter = 0;
 
4360
  char * tmpptr= strdup(ptr ? ptr+1 : default_prompt);
 
4361
  if (tmpptr == NULL)
 
4362
    tee_fprintf(stdout, "Memory allocation error. Not changing prompt\n");
4313
4363
  else
 
4364
  {
 
4365
    free(current_prompt);
 
4366
    current_prompt= tmpptr;
4314
4367
    tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt);
 
4368
  }
4315
4369
  return 0;
4316
4370
}
4317
4371