~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/mysql.cc

  • Committer: Monty Taylor
  • Date: 2008-07-12 19:42:00 UTC
  • mto: (77.6.1 glibclient-merge)
  • mto: This revision was merged to the branch mainline in revision 176.
  • Revision ID: monty@inaugust.com-20080712194200-egj34gi1ni29t9uf
Last change to migrate to glib from sql_string.

Show diffs side-by-side

added added

removed removed

Lines of Context:
48
48
#include <locale.h>
49
49
#endif
50
50
 
51
 
#include <glib/gstring.h>
 
51
#include <glib.h>
52
52
 
53
53
const char *VER= "14.14";
54
54
 
155
155
  *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
156
156
static char *histfile;
157
157
static char *histfile_tmp;
158
 
static GString *glob_buffer, *old_buffer;
159
 
static GString *processed_prompt;
160
 
//static GString *current_prompt= g_string_sized_new(16);
 
158
static GString *glob_buffer;
 
159
static GString *processed_prompt= g_string_sized_new(16);
161
160
static GString *default_prompt= NULL;
162
161
static char *full_username=0,*part_username=0;
163
162
static int wait_time = 5;
209
208
  com_rehash(GString *str, char*), com_tee(GString *str, char*),
210
209
  com_notee(GString *str, char*), com_charset(GString *str,char*),
211
210
  com_prompt(GString *str, char*), com_delimiter(GString *str, char*),
212
 
  com_warnings(GString *str, char*), com_nowarnings(GString *str, char*);
213
 
 
214
 
#ifdef USE_POPEN
215
 
static int com_nopager(GString *str, char*), com_pager(GString *str, char*),
216
 
  com_edit(GString *str,char*), com_shell(GString *str, char *);
217
 
#endif
 
211
  com_warnings(GString *str, char*), com_nowarnings(GString *str, char*),
 
212
  com_nopager(GString *str, char*), com_pager(GString *str, char*);
218
213
 
219
214
static int read_and_execute(bool interactive);
220
215
static int sql_connect(char *host,char *database,char *user,char *password,
254
249
    "Reconnect to the server. Optional arguments are db and host." },
255
250
  { "delimiter", 'd', com_delimiter,    1,
256
251
    "Set statement delimiter. NOTE: Takes the rest of the line as new delimiter." },
257
 
#ifdef USE_POPEN
258
 
  { "edit",   'e', com_edit,   0, "Edit command with $EDITOR."},
259
 
#endif
260
252
  { "ego",    'G', com_ego,    0,
261
253
    "Send command to mysql server, display result vertically."},
262
254
  { "exit",   'q', com_quit,   0, "Exit mysql. Same as quit."},
263
255
  { "go",     'g', com_go,     0, "Send command to mysql server." },
264
256
  { "help",   'h', com_help,   1, "Display this help." },
265
 
#ifdef USE_POPEN
266
257
  { "nopager",'n', com_nopager,0, "Disable pager, print to stdout." },
267
 
#endif
268
258
  { "notee",  't', com_notee,  0, "Don't write into outfile." },
269
 
#ifdef USE_POPEN
270
259
  { "pager",  'P', com_pager,  1,
271
260
    "Set PAGER [to_pager]. Print the query results via PAGER." },
272
 
#endif
273
261
  { "print",  'p', com_print,  0, "Print current command." },
274
262
  { "prompt", 'R', com_prompt, 1, "Change your mysql prompt."},
275
263
  { "quit",   'q', com_quit,   0, "Quit mysql." },
277
265
  { "source", '.', com_source, 1,
278
266
    "Execute an SQL script file. Takes a file name as an argument."},
279
267
  { "status", 's', com_status, 0, "Get status information from the server."},
280
 
#ifdef USE_POPEN
281
 
  { "system", '!', com_shell,  1, "Execute a system shell command."},
282
 
#endif
283
268
  { "tee",    'T', com_tee,    1,
284
269
    "Set outfile [to_outfile]. Append everything into given outfile." },
285
270
  { "use",    'u', com_use,    1,
1056
1041
  DBUG_PROCESS(argv[0]);
1057
1042
 
1058
1043
  delimiter_str= delimiter;
1059
 
  default_prompt = g_string_new(strdup(getenv("MYSQL_PS1") ?
1060
 
                                       getenv("MYSQL_PS1") :
1061
 
                                       "mysql> "));
1062
 
  current_prompt = my_strdup(default_prompt->str, MYF(MY_WME));
 
1044
  default_prompt = g_string_new(g_strdup(getenv("MYSQL_PS1") ?
 
1045
                                         getenv("MYSQL_PS1") :
 
1046
                                         "mysql> "));
 
1047
  current_prompt = g_strdup(default_prompt->str);
1063
1048
  prompt_counter=0;
1064
1049
 
1065
1050
  outfile[0]=0;                 // no (default) outfile
1151
1136
                  "Your Drizzle connection id is %lu\nServer version: %s\n",
1152
1137
                  mysql_thread_id(&mysql), server_version_string(&mysql));
1153
1138
  put_info(glob_buffer->str,INFO_INFO);
 
1139
  g_string_truncate(glob_buffer,0);
1154
1140
 
1155
1141
  initialize_readline((char*) my_progname);
1156
1142
  if (!status.batch && !quick && !opt_html && !opt_xml)
1157
1143
  {
1158
1144
    /* read-history from file, default ~/.mysql_history*/
1159
1145
    if (getenv("MYSQL_HISTFILE"))
1160
 
      histfile=my_strdup(getenv("MYSQL_HISTFILE"),MYF(MY_WME));
 
1146
      histfile=g_strdup(getenv("MYSQL_HISTFILE"));
1161
1147
    else if (getenv("HOME"))
1162
1148
    {
1163
1149
      histfile=(char*) my_malloc((uint) strlen(getenv("HOME"))
1216
1202
 
1217
1203
  if (sig >= 0)
1218
1204
    put_info(sig ? "Aborted" : "Bye", INFO_RESULT);
 
1205
  assert(glob_buffer != NULL);
1219
1206
  g_string_free(glob_buffer,true);
1220
 
  g_string_free(old_buffer,true);
 
1207
  assert(processed_prompt != NULL);
1221
1208
  g_string_free(processed_prompt,true);
 
1209
  assert(default_prompt != NULL);
 
1210
  g_string_free(default_prompt,true);
1222
1211
  my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
1223
1212
  my_free(opt_mysql_unix_port,MYF(MY_ALLOW_ZERO_PTR));
1224
1213
  my_free(histfile,MYF(MY_ALLOW_ZERO_PTR));
1228
1217
  my_free(current_user,MYF(MY_ALLOW_ZERO_PTR));
1229
1218
  my_free(full_username,MYF(MY_ALLOW_ZERO_PTR));
1230
1219
  my_free(part_username,MYF(MY_ALLOW_ZERO_PTR));
1231
 
  my_free(default_prompt,MYF(MY_ALLOW_ZERO_PTR));
1232
1220
#ifdef HAVE_SMEM
1233
1221
  my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
1234
1222
#endif
1253
1241
  MYSQL *kill_mysql= NULL;
1254
1242
 
1255
1243
  /* terminate if no query being executed, or we already tried interrupting */
1256
 
  if (!executing_query || interrupted_query)
 
1244
  if (!executing_query || interrupted_query) {
 
1245
    printf("MT: terinate?\n");
1257
1246
    goto err;
 
1247
  }
1258
1248
 
1259
1249
  kill_mysql= mysql_init(kill_mysql);
1260
1250
  if (!mysql_real_connect(kill_mysql,current_host, current_user, opt_password,
1261
1251
                          "", opt_mysql_port, opt_mysql_unix_port,0))
 
1252
  {
 
1253
    printf("MT:terminate\n");
1262
1254
    goto err;
 
1255
  }
1263
1256
 
1264
1257
  /* kill_buffer is always big enough because max length of %lu is 15 */
1265
1258
  sprintf(kill_buffer, "KILL /*!50000 QUERY */ %lu", mysql_thread_id(&mysql));
1387
1380
  {"one-database", 'o',
1388
1381
   "Only update the default database. This is useful for skipping updates to other database in the update log.",
1389
1382
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1390
 
#ifdef USE_POPEN
1391
1383
  {"pager", OPT_PAGER,
1392
1384
   "Pager to use to display results. If you don't supply an option the default pager is taken from your ENV variable PAGER. Valid pagers are less, more, cat [> filename], etc. See interactive help (\\h) also. This option does not work in batch mode. Disable with --disable-pager. This option is disabled by default.",
1393
1385
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
1394
1386
  {"no-pager", OPT_NOPAGER,
1395
1387
   "Disable pager and print to stdout. See interactive help (\\h) also. WARNING: option deprecated; use --disable-pager instead.",
1396
1388
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1397
 
#endif
1398
1389
  {"password", 'p',
1399
1390
   "Password to use when connecting to server. If password is not given it's asked from the tty.",
1400
1391
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
1599
1590
    }
1600
1591
    if (embedded_server_arg_count == MAX_SERVER_ARGS-1 ||
1601
1592
        !(embedded_server_args[embedded_server_arg_count++]=
1602
 
          my_strdup(argument, MYF(MY_FAE))))
 
1593
          g_strdup(argument)))
1603
1594
    {
1604
1595
      put_info("Can't use server argument", INFO_ERROR);
1605
1596
      return 0;
1635
1626
    {
1636
1627
      char *start= argument;
1637
1628
      my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
1638
 
      opt_password= my_strdup(argument, MYF(MY_FAE));
 
1629
      opt_password= g_strdup(argument);
1639
1630
      while (*argument) *argument++= 'x';               // Destroy argument
1640
1631
      if (*start)
1641
1632
        start[1]=0 ;
1686
1677
 
1687
1678
  tmp= (char *) getenv("MYSQL_HOST");
1688
1679
  if (tmp)
1689
 
    current_host= my_strdup(tmp, MYF(MY_WME));
 
1680
    current_host= strdup(tmp);
1690
1681
 
1691
1682
  pagpoint= getenv("PAGER");
1692
1683
  if (!((char*) (pagpoint)))
1731
1722
  {
1732
1723
    skip_updates= 0;
1733
1724
    my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
1734
 
    current_db= my_strdup(*argv, MYF(MY_WME));
 
1725
    current_db= g_strdup(*argv);
1735
1726
  }
1736
1727
  if (tty_password)
1737
1728
    opt_password= get_tty_password(NullS);
1756
1747
    if (!interactive)
1757
1748
    {
1758
1749
      line=batch_readline(status.line_buff);
 
1750
      printf("MT:*%s*",line);
1759
1751
      /*
1760
1752
        Skip UTF8 Byte Order Marker (BOM) 0xEFBBBF.
1761
1753
        Editors like "notepad" put this marker in
1768
1760
          (uchar) line[2] == 0xBF)
1769
1761
        line+= 3;
1770
1762
      line_number++;
1771
 
      if (!glob_buffer->len)
 
1763
      if (glob_buffer->len!=0)
1772
1764
        status.query_start_line=line_number;
1773
1765
    }
1774
1766
    else
1786
1778
      if (opt_outfile)
1787
1779
        fputs(prompt, OUTFILE);
1788
1780
      line= readline(prompt);
1789
 
 
 
1781
      printf("MT: readline(prompt)==*%s*\n",line);
1790
1782
      /*
1791
1783
        When Ctrl+d or Ctrl+z is pressed, the line may be NULL on some OS
1792
1784
        which may cause coredump.
1805
1797
      Check if line is a mysql command line
1806
1798
      (We want to allow help, print and clear anywhere at line start
1807
1799
    */
1808
 
    if ((named_cmds || (glob_buffer->len==0))
 
1800
    if ((named_cmds || (glob_buffer->len!=0))
1809
1801
        && !ml_comment && !in_string && (com=find_command(line,0)))
1810
1802
    {
1811
1803
      if ((*com->func)(glob_buffer,line) > 0)
1817
1809
        add_history(line);
1818
1810
      continue;
1819
1811
    }
1820
 
    if (add_line(glob_buffer,line,&in_string,&ml_comment))
 
1812
    int ret = add_line(glob_buffer,line,&in_string,&ml_comment);
 
1813
    printf("MT: ret=%d\n",ret);
 
1814
    if (ret)
1821
1815
      break;
1822
1816
  }
1823
1817
  /* if in batch mode, send last query even if it doesn't end with \g or go */
1824
1818
 
 
1819
  printf("MT: made it here %d\n", status.exit_status);
1825
1820
  if (!interactive && !status.exit_status)
1826
1821
  {
 
1822
    printf("pre remove_cntrl *%s*\n", glob_buffer->str);
1827
1823
    remove_cntrl(glob_buffer);
1828
 
    if (glob_buffer->len > 0)
 
1824
    printf("post remove_cntrl *%s*\n", glob_buffer->str);
 
1825
    if (glob_buffer->len != 0)
1829
1826
    {
1830
1827
      status.exit_status=1;
1831
1828
      if (com_go(glob_buffer,line) <= 0)
1843
1840
  char *end;
1844
1841
  DBUG_ENTER("find_command");
1845
1842
  DBUG_PRINT("enter",("name: '%s'  char: %d", name ? name : "NULL", cmd_char));
 
1843
  printf("MT: find_command name: '%s'  char: %d\n", name ? name : "NULL", cmd_char);
1846
1844
 
1847
1845
  if (!name)
1848
1846
  {
1891
1889
 
1892
1890
 
1893
1891
static bool add_line(GString *buffer,char *line,char *in_string,
1894
 
                     bool *ml_comment)
 
1892
                        bool *ml_comment)
1895
1893
{
1896
1894
  uchar inchar;
1897
1895
  char buff[80], *pos, *out;
1899
1897
  bool need_space= 0;
1900
1898
  bool ss_comment= 0;
1901
1899
  DBUG_ENTER("add_line");
 
1900
  printf("MT: In add_line: buffer:*%s*, line=*%s*, in_string=*%s*\n",
 
1901
         buffer->str, line, in_string);
1902
1902
 
 
1903
      printf("MT %d\n",__LINE__);
1903
1904
  if (!line[0] && (buffer->len==0))
1904
1905
    DBUG_RETURN(0);
 
1906
      printf("MT %d\n",__LINE__);
1905
1907
  if (status.add_to_history && line[0] && not_in_history(line))
1906
1908
    add_history(line);
1907
1909
  char *end_of_line=line+(uint) strlen(line);
1908
1910
 
 
1911
      printf("MT %d\n",__LINE__);
1909
1912
  for (pos=out=line ; (inchar= (uchar) *pos) ; pos++)
1910
1913
  {
 
1914
    printf("MT: for pos=*%s* out=*%s* line=*%s*\n",
 
1915
           pos, out, line);
1911
1916
    if (!preserve_comments)
1912
1917
    {
1913
1918
      // Skip spaces at the beggining of a statement
1933
1938
      continue;
1934
1939
    }
1935
1940
#endif
 
1941
      printf("MT %d\n",__LINE__);
1936
1942
    if (!*ml_comment && inchar == '\\' &&
1937
1943
        !(mysql.server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES))
1938
1944
    {
1998
2004
             !my_strnncoll(charset_info, (uchar*) pos, 10,
1999
2005
                           (const uchar*) "delimiter ", 10))
2000
2006
    {
 
2007
      printf("MT else if\n");
2001
2008
      // Flush previously accepted characters
2002
2009
      if (out != line)
2003
2010
      {
2005
2012
        out= line;
2006
2013
      }
2007
2014
 
 
2015
      printf("MT %d\n",__LINE__);
2008
2016
      // Flush possible comments in the buffer
2009
 
      if (buffer->len > 0)
 
2017
      if (buffer->len != 0)
2010
2018
      {
2011
2019
        if (com_go(buffer, 0) > 0) // < 0 is not fatal
2012
2020
          DBUG_RETURN(1);
 
2021
        assert(buffer!=NULL);
2013
2022
        g_string_truncate(buffer,0);
2014
2023
      }
2015
2024
 
2017
2026
        Delimiter wants the get rest of the given line as argument to
2018
2027
        allow one to change ';' to ';;' and back
2019
2028
      */
 
2029
      printf("MT: before delimiter\n");
2020
2030
      g_string_append(buffer,pos);
2021
2031
      if (com_delimiter(buffer, pos) > 0)
2022
2032
        DBUG_RETURN(1);
 
2033
      printf("MT: after delimiter\n");
2023
2034
 
2024
2035
      g_string_truncate(buffer,0);
2025
2036
      break;
2026
2037
    }
2027
2038
    else if (!*ml_comment && !*in_string && is_prefix(pos, delimiter))
2028
2039
    {
 
2040
      printf("MT %d\n",__LINE__);
2029
2041
      // Found a statement. Continue parsing after the delimiter
2030
2042
      pos+= delimiter_length;
2031
2043
 
2053
2065
 
2054
2066
      pos--;
2055
2067
 
 
2068
      printf("MT %d\n",__LINE__);
2056
2069
      if ((com= find_command(buffer->str, 0)))
2057
2070
      {
2058
2071
 
2064
2077
        if (com_go(buffer, 0) > 0)             // < 0 is not fatal
2065
2078
          DBUG_RETURN(1);
2066
2079
      }
 
2080
      printf("MT %d\n",__LINE__);
2067
2081
      g_string_truncate(buffer,0);
2068
2082
    }
2069
2083
    else if (!*ml_comment
2105
2119
    }
2106
2120
    else if (*ml_comment && !ss_comment && inchar == '*' && *(pos + 1) == '/')
2107
2121
    {
 
2122
      printf("MT %d\n",__LINE__);
2108
2123
      if (preserve_comments)
2109
2124
      {
2110
2125
        *out++= *pos++;                       // copy '*'
2124
2139
    }
2125
2140
    else
2126
2141
    {
 
2142
      printf("MT %d\n",__LINE__);
2127
2143
      // Add found char to buffer
2128
2144
      if (!*in_string && inchar == '/' && *(pos + 1) == '*' &&
2129
2145
          *(pos + 2) == '!')
2141
2157
          *out++= ' ';
2142
2158
        need_space= 0;
2143
2159
        *out++= (char) inchar;
 
2160
        printf("MT %d\n",__LINE__);
2144
2161
      }
 
2162
      printf("MT %d\n",__LINE__);
2145
2163
    }
 
2164
      printf("MT %d\n",__LINE__);
2146
2165
  }
 
2166
  printf("MT: out of loop - out *%s* line *%s* buffer->len *%d*\n",
 
2167
         out, line, (int) buffer->len);
2147
2168
  if (out != line || (buffer->len > 0))
2148
2169
  {
2149
2170
    *out++='\n';
2301
2322
 
2302
2323
    if (e)
2303
2324
    {
2304
 
      ptr= strdup(e->str);
 
2325
      ptr= g_strdup(e->str);
2305
2326
      e = e->pNext;
2306
2327
      return ptr;
2307
2328
    }
2326
2347
    while (e && !ptr)
2327
2348
    {                                   /* find valid entry in bucket */
2328
2349
      if ((uint) strlen(e->str) == b->nKeyLength)
2329
 
        ptr = strdup(e->str);
 
2350
        ptr = g_strdup(e->str);
2330
2351
      /* find the next used entry */
2331
2352
      e = e->pNext;
2332
2353
      if (!e)
2533
2554
  {
2534
2555
    MYSQL_ROW row= mysql_fetch_row(res);
2535
2556
    if (row[0])
2536
 
      current_db= my_strdup(row[0], MYF(MY_WME));
 
2557
      current_db= g_strdup(row[0]);
2537
2558
    mysql_free_result(res);
2538
2559
  }
2539
2560
}
2603
2624
    server_cmd= cmd_buf;
2604
2625
  }
2605
2626
 
2606
 
  if (!status.batch)
2607
 
  {
2608
 
    old_buffer= g_string_new(buffer->str);
2609
 
  }
2610
 
 
2611
2627
  if (!connected && reconnect())
2612
2628
    return 1;
2613
2629
 
2760
2776
  int           err= 0;
2761
2777
 
2762
2778
  interrupted_query= 0;
2763
 
  if (!status.batch)
2764
 
  {
2765
 
    // Save for edit command
2766
 
    old_buffer= g_string_new(buffer->str);
2767
 
  }
2768
2779
 
2769
2780
  /* Remove garbage for nicer messages */
2770
2781
  remove_cntrl(buffer);
2923
2934
 
2924
2935
static void init_pager()
2925
2936
{
2926
 
#ifdef USE_POPEN
2927
2937
  if (!opt_nopager)
2928
2938
  {
2929
2939
    if (!(PAGER= popen(pager, "w")))
2933
2943
    }
2934
2944
  }
2935
2945
  else
2936
 
#endif
2937
2946
    PAGER= stdout;
2938
2947
}
2939
2948
 
2940
2949
static void end_pager()
2941
2950
{
2942
 
#ifdef USE_POPEN
2943
2951
  if (!opt_nopager)
2944
2952
    pclose(PAGER);
2945
 
#endif
2946
2953
}
2947
2954
 
2948
2955
 
3585
3592
  Sorry, this command is not available in Windows.
3586
3593
*/
3587
3594
 
3588
 
#ifdef USE_POPEN
3589
3595
static int
3590
 
com_pager(GString *buffer, char *line __attribute__((unused)))
 
3596
com_pager(GString *buffer __attribute__((__unused__)),
 
3597
          char *line __attribute__((unused)))
3591
3598
{
3592
3599
  char pager_name[FN_REFLEN], *end, *param;
3593
3600
 
3639
3646
  tee_fprintf(stdout, "PAGER set to stdout\n");
3640
3647
  return 0;
3641
3648
}
3642
 
#endif
3643
 
 
3644
 
 
3645
 
/*
3646
 
  Sorry, you can't send the result to an editor in Win32
3647
 
*/
3648
 
 
3649
 
#ifdef USE_POPEN
3650
 
static int
3651
 
com_edit(GString *buffer,char *line __attribute__((unused)))
3652
 
{
3653
 
  char  filename[FN_REFLEN],buff[160];
3654
 
  int   fd,tmp;
3655
 
  const char *editor;
3656
 
 
3657
 
  if ((fd=create_temp_file(filename,NullS,"sql", O_CREAT | O_WRONLY,
3658
 
                           MYF(MY_WME))) < 0)
3659
 
    goto err;
3660
 
  if (buffer->is_empty() && !old_buffer.is_empty())
3661
 
    (void) my_write(fd,(uchar*) old_buffer.ptr(),old_buffer.length(),
3662
 
                    MYF(MY_WME));
3663
 
  else
3664
 
    (void) my_write(fd,(uchar*) buffer->ptr(),buffer->length(),MYF(MY_WME));
3665
 
  (void) my_close(fd,MYF(0));
3666
 
 
3667
 
  if (!(editor = (char *)getenv("EDITOR")) &&
3668
 
      !(editor = (char *)getenv("VISUAL")))
3669
 
    editor = "vi";
3670
 
  strxmov(buff,editor," ",filename,NullS);
3671
 
  (void) system(buff);
3672
 
 
3673
 
  struct stat stat_arg;
3674
 
  if (stat(filename,&stat_arg))
3675
 
    goto err;
3676
 
  if ((fd = my_open(filename,O_RDONLY, MYF(MY_WME))) < 0)
3677
 
    goto err;
3678
 
  (void) buffer->alloc((uint) stat_arg.st_size);
3679
 
  if ((tmp=read(fd,(char*) buffer->ptr(),buffer->alloced_length())) >= 0L)
3680
 
    buffer->length((uint) tmp);
3681
 
  else
3682
 
    buffer->length(0);
3683
 
  (void) my_close(fd,MYF(0));
3684
 
  (void) my_delete(filename,MYF(MY_WME));
3685
 
err:
3686
 
  return 0;
3687
 
}
3688
 
#endif
3689
 
 
3690
3649
 
3691
3650
/* If arg is given, exit without errors. This happens on command 'quit' */
3692
3651
 
3708
3667
}
3709
3668
 
3710
3669
 
3711
 
#ifdef USE_POPEN
3712
 
static int
3713
 
com_shell(GString *buffer, char *line __attribute__((unused)))
3714
 
{
3715
 
  char *shell_cmd;
3716
 
 
3717
 
  /* Skip space from line begin */
3718
 
  while (my_isspace(charset_info, *line))
3719
 
    line++;
3720
 
  if (!(shell_cmd = strchr(line, ' ')))
3721
 
  {
3722
 
    put_info("Usage: \\! shell-command", INFO_ERROR);
3723
 
    return -1;
3724
 
  }
3725
 
  /*
3726
 
    The output of the shell command does not
3727
 
    get directed to the pager or the outfile
3728
 
  */
3729
 
  if (system(shell_cmd) == -1)
3730
 
  {
3731
 
    put_info(strerror(errno), INFO_ERROR, errno);
3732
 
    return -1;
3733
 
  }
3734
 
  return 0;
3735
 
}
3736
 
#endif
3737
 
 
3738
3670
 
3739
3671
static int
3740
3672
com_print(GString *buffer,char *line __attribute__((unused)))
3772
3704
    if (tmp && *tmp)
3773
3705
    {
3774
3706
      my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
3775
 
      current_db= my_strdup(tmp, MYF(MY_WME));
 
3707
      current_db= g_strdup(tmp);
3776
3708
      tmp= get_arg(buff, 1);
3777
3709
      if (tmp)
3778
3710
      {
3779
3711
        my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
3780
 
        current_host=my_strdup(tmp,MYF(MY_WME));
 
3712
        current_host=g_strdup(tmp);
3781
3713
      }
3782
3714
    }
3783
3715
    else
3786
3718
      opt_rehash= 0;                            /* purecov: tested */
3787
3719
    }
3788
3720
    // command used
 
3721
    assert(buffer!=NULL);
3789
3722
    g_string_truncate(buffer, 0);
3790
3723
  }
3791
3724
  else
3850
3783
  status.line_buff=line_buff;
3851
3784
  status.file_name=source_name;
3852
3785
  // Empty command buffer
 
3786
  assert(glob_buffer!=NULL);
3853
3787
  g_string_truncate(glob_buffer, 0);
3854
3788
  error= read_and_execute(false);
3855
3789
  // Continue as before
3953
3887
        return put_error(&mysql);
3954
3888
    }
3955
3889
    my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
3956
 
    current_db=my_strdup(tmp,MYF(MY_WME));
 
3890
    current_db=g_strdup(tmp);
3957
3891
    if (select_db > 1)
3958
3892
      build_completion_hash(opt_rehash, 1);
3959
3893
  }
4180
4114
    tee_fprintf(stdout, "\nAll updates ignored to this database\n");
4181
4115
    vidattr(A_NORMAL);
4182
4116
  }
4183
 
#ifdef USE_POPEN
4184
4117
  tee_fprintf(stdout, "Current pager:\t\t%s\n", pager);
4185
4118
  tee_fprintf(stdout, "Using outfile:\t\t'%s'\n", opt_outfile ? outfile : "");
4186
 
#endif
4187
4119
  tee_fprintf(stdout, "Using delimiter:\t%s\n", delimiter);
4188
4120
  tee_fprintf(stdout, "Server version:\t\t%s\n", server_version_string(&mysql));
4189
4121
  tee_fprintf(stdout, "Protocol version:\t%d\n", mysql_get_proto_info(&mysql));
4371
4303
  char *end= start + (buffer->len);
4372
4304
  while (start < end && !my_isgraph(charset_info,end[-1]))
4373
4305
    end--;
4374
 
  // TODO: Verify we're not tuncating one too many chars here...
4375
 
  g_string_truncate(buffer, (buffer->len - (end-start)));
 
4306
  uint chars_to_truncate = end-start;
 
4307
  if (buffer->len > chars_to_truncate)
 
4308
    g_string_truncate(buffer, chars_to_truncate);
4376
4309
}
4377
4310
 
4378
4311
 
4486
4419
static const char * construct_prompt()
4487
4420
{
4488
4421
  // Erase the old prompt
 
4422
  assert(processed_prompt!=NULL);
4489
4423
  g_string_truncate(processed_prompt, 0);
4490
4424
 
4491
4425
  // Get the date struct
4493
4427
  struct tm *t = localtime(&lclock);
4494
4428
 
4495
4429
  /* parse thru the settings for the prompt */
4496
 
  char *c= NULL;
4497
 
  for (c= current_prompt; *c; *c++)
 
4430
  for (char *c= current_prompt; *c; *c++)
4498
4431
  {
4499
4432
    if (*c != PROMPT_CHAR)
4500
4433
    {
4501
 
      g_string_append(processed_prompt, c);
 
4434
      g_string_append_c(processed_prompt, c[0]);
4502
4435
    }
4503
4436
    else
4504
4437
    {
4671
4604
      (result=mysql_use_result(&mysql)))
4672
4605
  {
4673
4606
    MYSQL_ROW cur=mysql_fetch_row(result);
4674
 
    full_username=my_strdup(cur[0],MYF(MY_WME));
4675
 
    part_username=my_strdup(strtok(cur[0],"@"),MYF(MY_WME));
 
4607
    full_username=g_strdup(cur[0]);
 
4608
    part_username=g_strdup(strtok(cur[0],"@"));
4676
4609
    (void) mysql_fetch_row(result);             // Read eof
4677
4610
  }
4678
4611
}
4682
4615
  char *ptr=strchr(line, ' ');
4683
4616
  prompt_counter = 0;
4684
4617
  my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR));
4685
 
  current_prompt=my_strdup(ptr ? ptr+1 : default_prompt->str,MYF(MY_WME));
 
4618
  current_prompt=g_strdup(ptr ? ptr+1 : default_prompt->str);
4686
4619
  if (!ptr)
4687
4620
    tee_fprintf(stdout, "Returning to default PROMPT of %s\n",
4688
4621
                default_prompt->str);