~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/mysqladmin.cc

  • Committer: Brian Aker
  • Date: 2008-07-14 22:07:42 UTC
  • Revision ID: brian@tangent.org-20080714220742-y7fjh1mitrfcgfij
Second pass cleanup on removal of my_uint types

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2000-2006 MySQL AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; 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 */
 
15
 
 
16
/* maintaince of mysql databases */
 
17
 
 
18
#include "client_priv.h"
 
19
#include <signal.h>
 
20
#include <my_pthread.h>                         /* because of signal()  */
 
21
#include <sys/stat.h>
 
22
 
 
23
#define ADMIN_VERSION "8.42"
 
24
#define MAX_MYSQL_VAR 256
 
25
#define SHUTDOWN_DEF_TIMEOUT 3600               /* Wait for shutdown */
 
26
#define MAX_TRUNC_LENGTH 3
 
27
 
 
28
char *host= NULL, *user= 0, *opt_password= 0,
 
29
     *default_charset= NULL;
 
30
char truncated_var_names[MAX_MYSQL_VAR][MAX_TRUNC_LENGTH];
 
31
char ex_var_names[MAX_MYSQL_VAR][FN_REFLEN];
 
32
uint64_t last_values[MAX_MYSQL_VAR];
 
33
static int interval=0;
 
34
static bool option_force=0,interrupted=0,new_line=0,
 
35
               opt_compress=0, opt_relative=0, opt_verbose=0, opt_vertical=0,
 
36
               tty_password= 0, opt_nobeep;
 
37
static bool debug_info_flag= 0, debug_check_flag= 0;
 
38
static uint tcp_port = 0, option_wait = 0, option_silent=0, nr_iterations;
 
39
static uint opt_count_iterations= 0, my_end_arg;
 
40
static ulong opt_connect_timeout, opt_shutdown_timeout;
 
41
static char * unix_port=0;
 
42
 
 
43
#ifdef HAVE_SMEM
 
44
static char *shared_memory_base_name=0;
 
45
#endif
 
46
static uint opt_protocol=0;
 
47
static myf error_flags; /* flags to pass to my_printf_error, like ME_BELL */
 
48
 
 
49
/*
 
50
  When using extended-status relatively, ex_val_max_len is the estimated
 
51
  maximum length for any relative value printed by extended-status. The
 
52
  idea is to try to keep the length of output as short as possible.
 
53
*/
 
54
 
 
55
static uint ex_val_max_len[MAX_MYSQL_VAR];
 
56
static bool ex_status_printed = 0; /* First output is not relative. */
 
57
static uint ex_var_count, max_var_length, max_val_length;
 
58
 
 
59
static void print_version(void);
 
60
static void usage(void);
 
61
extern "C" bool get_one_option(int optid, const struct my_option *opt,
 
62
                                  char *argument);
 
63
static bool sql_connect(MYSQL *mysql, uint wait);
 
64
static int execute_commands(MYSQL *mysql,int argc, char **argv);
 
65
static int drop_db(MYSQL *mysql,const char *db);
 
66
extern "C" sig_handler endprog(int signal_number);
 
67
static void nice_time(ulong sec,char *buff);
 
68
static void print_header(MYSQL_RES *result);
 
69
static void print_top(MYSQL_RES *result);
 
70
static void print_row(MYSQL_RES *result,MYSQL_ROW cur, uint row);
 
71
static void print_relative_row(MYSQL_RES *result, MYSQL_ROW cur, uint row);
 
72
static void print_relative_row_vert(MYSQL_RES *result, MYSQL_ROW cur, uint row);
 
73
static void print_relative_header();
 
74
static void print_relative_line();
 
75
static void truncate_names();
 
76
static bool get_pidfile(MYSQL *mysql, char *pidfile);
 
77
static bool wait_pidfile(char *pidfile, time_t last_modified,
 
78
                            struct stat *pidfile_status);
 
79
static void store_values(MYSQL_RES *result);
 
80
 
 
81
/*
 
82
  The order of commands must be the same as command_names,
 
83
  except ADMIN_ERROR
 
84
*/
 
85
enum commands {
 
86
  ADMIN_ERROR,
 
87
  ADMIN_CREATE,           ADMIN_DROP,            ADMIN_SHUTDOWN,
 
88
  ADMIN_RELOAD,           ADMIN_REFRESH,         ADMIN_VER,
 
89
  ADMIN_PROCESSLIST,      ADMIN_STATUS,          ADMIN_KILL,
 
90
  ADMIN_DEBUG,            ADMIN_VARIABLES,       ADMIN_FLUSH_LOGS,
 
91
  ADMIN_FLUSH_HOSTS,      ADMIN_FLUSH_TABLES,    ADMIN_PASSWORD,
 
92
  ADMIN_PING,             ADMIN_EXTENDED_STATUS, ADMIN_FLUSH_STATUS,
 
93
  ADMIN_FLUSH_PRIVILEGES, ADMIN_START_SLAVE,     ADMIN_STOP_SLAVE,
 
94
  ADMIN_FLUSH_THREADS,    ADMIN_OLD_PASSWORD
 
95
};
 
96
static const char *command_names[]= {
 
97
  "create",               "drop",                "shutdown",
 
98
  "reload",               "refresh",             "version",
 
99
  "processlist",          "status",              "kill",
 
100
  "debug",                "variables",           "flush-logs",
 
101
  "flush-hosts",          "flush-tables",        "password",
 
102
  "ping",                 "extended-status",     "flush-status",
 
103
  "flush-privileges",     "start-slave",         "stop-slave",
 
104
  "flush-threads","old-password",
 
105
  NullS
 
106
};
 
107
 
 
108
static TYPELIB command_typelib=
 
109
{ array_elements(command_names)-1,"commands", command_names, NULL};
 
110
 
 
111
static struct my_option my_long_options[] =
 
112
{
 
113
  {"count", 'c',
 
114
   "Number of iterations to make. This works with -i (--sleep) only.",
 
115
   (char**) &nr_iterations, (char**) &nr_iterations, 0, GET_UINT,
 
116
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
117
  {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .",
 
118
   (char**) &debug_check_flag, (char**) &debug_check_flag, 0,
 
119
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
120
  {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
 
121
   (char**) &debug_info_flag, (char**) &debug_info_flag,
 
122
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
123
  {"force", 'f',
 
124
   "Don't ask for confirmation on drop database; with multiple commands, continue even if an error occurs.",
 
125
   (char**) &option_force, (char**) &option_force, 0, GET_BOOL, NO_ARG, 0, 0,
 
126
   0, 0, 0, 0},
 
127
  {"compress", 'C', "Use compression in server/client protocol.",
 
128
   (char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
 
129
   0, 0, 0},
 
130
  {"character-sets-dir", OPT_CHARSETS_DIR,
 
131
   "Directory where character sets are.", (char**) &charsets_dir,
 
132
   (char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
133
  {"default-character-set", OPT_DEFAULT_CHARSET,
 
134
   "Set the default character set.", (char**) &default_charset,
 
135
   (char**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
136
  {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG,
 
137
   NO_ARG, 0, 0, 0, 0, 0, 0},
 
138
  {"host", 'h', "Connect to host.", (char**) &host, (char**) &host, 0, GET_STR,
 
139
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
140
  {"no-beep", 'b', "Turn off beep on error.", (char**) &opt_nobeep,
 
141
   (char**) &opt_nobeep, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, 
 
142
  {"password", 'p',
 
143
   "Password to use when connecting to server. If password is not given it's asked from the tty.",
 
144
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
145
  {"port", 'P', "Port number to use for connection or 0 for default to, in "
 
146
   "order of preference, my.cnf, $MYSQL_TCP_PORT, "
 
147
#if MYSQL_PORT_DEFAULT == 0
 
148
   "/etc/services, "
 
149
#endif
 
150
   "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
 
151
   (char**) &tcp_port,
 
152
   (char**) &tcp_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
153
  {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
 
154
    0, 0, 0, GET_STR,  REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
155
  {"relative", 'r',
 
156
   "Show difference between current and previous values when used with -i. Currently works only with extended-status.",
 
157
   (char**) &opt_relative, (char**) &opt_relative, 0, GET_BOOL, NO_ARG, 0, 0, 0,
 
158
  0, 0, 0},
 
159
  {"set-variable", 'O',
 
160
   "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
 
161
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
162
#ifdef HAVE_SMEM
 
163
  {"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME,
 
164
   "Base name of shared memory.", (char**) &shared_memory_base_name, (char**) &shared_memory_base_name,
 
165
   0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
166
#endif
 
167
  {"silent", 's', "Silently exit if one can't connect to server.",
 
168
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
169
  {"socket", 'S', "Socket file to use for connection.",
 
170
   (char**) &unix_port, (char**) &unix_port, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
 
171
   0, 0, 0},
 
172
  {"sleep", 'i', "Execute commands again and again with a sleep between.",
 
173
   (char**) &interval, (char**) &interval, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0,
 
174
   0, 0},
 
175
#ifndef DONT_ALLOW_USER_CHANGE
 
176
  {"user", 'u', "User for login if not current user.", (char**) &user,
 
177
   (char**) &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
178
#endif
 
179
  {"verbose", 'v', "Write more information.", (char**) &opt_verbose,
 
180
   (char**) &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
181
  {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
 
182
   NO_ARG, 0, 0, 0, 0, 0, 0},
 
183
  {"vertical", 'E',
 
184
   "Print output vertically. Is similar to --relative, but prints output vertically.",
 
185
   (char**) &opt_vertical, (char**) &opt_vertical, 0, GET_BOOL, NO_ARG, 0, 0, 0,
 
186
   0, 0, 0},
 
187
  {"wait", 'w', "Wait and retry if connection is down.", 0, 0, 0, GET_UINT,
 
188
   OPT_ARG, 0, 0, 0, 0, 0, 0},
 
189
  {"connect_timeout", OPT_CONNECT_TIMEOUT, "", (char**) &opt_connect_timeout,
 
190
   (char**) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 3600*12, 0,
 
191
   3600*12, 0, 1, 0},
 
192
  {"shutdown_timeout", OPT_SHUTDOWN_TIMEOUT, "", (char**) &opt_shutdown_timeout,
 
193
   (char**) &opt_shutdown_timeout, 0, GET_ULONG, REQUIRED_ARG,
 
194
   SHUTDOWN_DEF_TIMEOUT, 0, 3600*12, 0, 1, 0},
 
195
  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 
196
};
 
197
 
 
198
 
 
199
static const char *load_default_groups[]= { "mysqladmin","client",0 };
 
200
 
 
201
bool
 
202
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
 
203
               char *argument)
 
204
{
 
205
  int error = 0;
 
206
 
 
207
  switch(optid) {
 
208
  case 'c':
 
209
    opt_count_iterations= 1;
 
210
    break;
 
211
  case 'p':
 
212
    if (argument)
 
213
    {
 
214
      char *start=argument;
 
215
      my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
 
216
      opt_password=my_strdup(argument,MYF(MY_FAE));
 
217
      while (*argument) *argument++= 'x';               /* Destroy argument */
 
218
      if (*start)
 
219
        start[1]=0;                             /* Cut length of argument */
 
220
      tty_password= 0;
 
221
    }
 
222
    else
 
223
      tty_password=1;
 
224
    break;
 
225
  case 's':
 
226
    option_silent++;
 
227
    break;
 
228
  case 'V':
 
229
    print_version();
 
230
    exit(0);
 
231
    break;
 
232
  case 'w':
 
233
    if (argument)
 
234
    {
 
235
      if ((option_wait=atoi(argument)) <= 0)
 
236
        option_wait=1;
 
237
    }
 
238
    else
 
239
      option_wait= ~(uint)0;
 
240
    break;
 
241
  case '?':
 
242
  case 'I':                                     /* Info */
 
243
    error++;
 
244
    break;
 
245
  case OPT_CHARSETS_DIR:
 
246
#if MYSQL_VERSION_ID > 32300
 
247
    charsets_dir = argument;
 
248
#endif
 
249
    break;
 
250
  case OPT_MYSQL_PROTOCOL:
 
251
    opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
 
252
                                    opt->name);
 
253
    break;
 
254
  }
 
255
  if (error)
 
256
  {
 
257
    usage();
 
258
    exit(1);
 
259
  }
 
260
  return 0;
 
261
}
 
262
 
 
263
 
 
264
int main(int argc,char *argv[])
 
265
{
 
266
  int error= 0, ho_error;
 
267
  MYSQL mysql;
 
268
  char **commands, **save_argv;
 
269
 
 
270
  MY_INIT(argv[0]);
 
271
  mysql_init(&mysql);
 
272
  load_defaults("my",load_default_groups,&argc,&argv);
 
273
  save_argv = argv;                             /* Save for free_defaults */
 
274
  if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
 
275
  {
 
276
    free_defaults(save_argv);
 
277
    exit(ho_error);
 
278
  }
 
279
  if (debug_info_flag)
 
280
    my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
 
281
  if (debug_check_flag)
 
282
    my_end_arg= MY_CHECK_ERROR;
 
283
 
 
284
  if (argc == 0)
 
285
  {
 
286
    usage();
 
287
    exit(1);
 
288
  }
 
289
  commands = argv;
 
290
  if (tty_password)
 
291
    opt_password = get_tty_password(NullS);
 
292
 
 
293
  VOID(signal(SIGINT,endprog));                 /* Here if abort */
 
294
  VOID(signal(SIGTERM,endprog));                /* Here if abort */
 
295
 
 
296
  if (opt_compress)
 
297
    mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS);
 
298
  if (opt_connect_timeout)
 
299
  {
 
300
    uint tmp=opt_connect_timeout;
 
301
    mysql_options(&mysql,MYSQL_OPT_CONNECT_TIMEOUT, (char*) &tmp);
 
302
  }
 
303
  if (opt_protocol)
 
304
    mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
 
305
#ifdef HAVE_SMEM
 
306
  if (shared_memory_base_name)
 
307
    mysql_options(&mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
 
308
#endif
 
309
  if (default_charset)
 
310
    mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset);
 
311
  error_flags= (myf)(opt_nobeep ? 0 : ME_BELL);
 
312
 
 
313
  if (sql_connect(&mysql, option_wait))
 
314
  {
 
315
    unsigned int err= mysql_errno(&mysql);
 
316
    if (err >= CR_MIN_ERROR && err <= CR_MAX_ERROR)
 
317
      error= 1;
 
318
    else
 
319
    {
 
320
      /* Return 0 if all commands are PING */
 
321
      for (; argc > 0; argv++, argc--)
 
322
      {
 
323
        if (find_type(argv[0], &command_typelib, 2) != ADMIN_PING)
 
324
        {
 
325
          error= 1;
 
326
          break;
 
327
        }
 
328
      }
 
329
    }
 
330
  }
 
331
  else
 
332
  {
 
333
    while (!interrupted && (!opt_count_iterations || nr_iterations))
 
334
    {
 
335
      new_line = 0;
 
336
      if ((error=execute_commands(&mysql,argc,commands)))
 
337
      {
 
338
        if (error > 0)
 
339
          break;                                /* Wrong command error */
 
340
        if (!option_force)
 
341
        {
 
342
          if (option_wait && !interrupted)
 
343
          {
 
344
            mysql_close(&mysql);
 
345
            if (!sql_connect(&mysql, option_wait))
 
346
            {
 
347
              sleep(1);                         /* Don't retry too rapidly */
 
348
              continue;                         /* Retry */
 
349
            }
 
350
          }
 
351
          error=1;
 
352
          break;
 
353
        }
 
354
      }
 
355
      if (interval)
 
356
      {
 
357
        sleep(interval);
 
358
        if (new_line)
 
359
          puts("");
 
360
        if (opt_count_iterations)
 
361
          nr_iterations--;
 
362
      }
 
363
      else
 
364
        break;
 
365
    }
 
366
    mysql_close(&mysql);
 
367
  }
 
368
  my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
 
369
  my_free(user,MYF(MY_ALLOW_ZERO_PTR));
 
370
#ifdef HAVE_SMEM
 
371
  my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
 
372
#endif
 
373
  free_defaults(save_argv);
 
374
  my_end(my_end_arg);
 
375
  exit(error ? 1 : 0);
 
376
}
 
377
 
 
378
 
 
379
sig_handler endprog(int signal_number __attribute__((unused)))
 
380
{
 
381
  interrupted=1;
 
382
}
 
383
 
 
384
 
 
385
static bool sql_connect(MYSQL *mysql, uint wait)
 
386
{
 
387
  bool info=0;
 
388
 
 
389
  for (;;)
 
390
  {
 
391
    if (mysql_real_connect(mysql,host,user,opt_password,NullS,tcp_port,
 
392
                           unix_port, 0))
 
393
    {
 
394
      mysql->reconnect= 1;
 
395
      if (info)
 
396
      {
 
397
        fputs("\n",stderr);
 
398
        (void) fflush(stderr);
 
399
      }
 
400
      return 0;
 
401
    }
 
402
 
 
403
    if (!wait)
 
404
    {
 
405
      if (!option_silent)
 
406
      {
 
407
        if (!host)
 
408
          host= (char*) LOCAL_HOST;
 
409
        my_printf_error(0,"connect to server at '%s' failed\nerror: '%s'",
 
410
                        error_flags, host, mysql_error(mysql));
 
411
        if (mysql_errno(mysql) == CR_CONNECTION_ERROR)
 
412
        {
 
413
          fprintf(stderr,
 
414
                  "Check that mysqld is running and that the socket: '%s' exists!\n",
 
415
                  unix_port ? unix_port : mysql_unix_port);
 
416
        }
 
417
        else if (mysql_errno(mysql) == CR_CONN_HOST_ERROR ||
 
418
                 mysql_errno(mysql) == CR_UNKNOWN_HOST)
 
419
        {
 
420
          fprintf(stderr,"Check that mysqld is running on %s",host);
 
421
          fprintf(stderr," and that the port is %d.\n",
 
422
                  tcp_port ? tcp_port: mysql_port);
 
423
          fprintf(stderr,"You can check this by doing 'telnet %s %d'\n",
 
424
                  host, tcp_port ? tcp_port: mysql_port);
 
425
        }
 
426
      }
 
427
      return 1;
 
428
    }
 
429
    if (wait != (uint) ~0)
 
430
      wait--;                           /* One less retry */
 
431
    if ((mysql_errno(mysql) != CR_CONN_HOST_ERROR) &&
 
432
        (mysql_errno(mysql) != CR_CONNECTION_ERROR))
 
433
    {
 
434
      fprintf(stderr,"Got error: %s\n", mysql_error(mysql));
 
435
      if (!option_force)
 
436
        return 1;
 
437
    }
 
438
    else if (!option_silent)
 
439
    {
 
440
      if (!info)
 
441
      {
 
442
        info=1;
 
443
        fputs("Waiting for MySQL server to answer",stderr);
 
444
        (void) fflush(stderr);
 
445
      }
 
446
      else
 
447
      {
 
448
        putc('.',stderr);
 
449
        (void) fflush(stderr);
 
450
      }
 
451
    }
 
452
    sleep(5);
 
453
  }
 
454
}
 
455
 
 
456
 
 
457
/*
 
458
  Execute a command.
 
459
  Return 0 on ok
 
460
         -1 on retryable error
 
461
         1 on fatal error
 
462
*/
 
463
 
 
464
static int execute_commands(MYSQL *mysql,int argc, char **argv)
 
465
{
 
466
  const char *status;
 
467
  /*
 
468
    MySQL documentation relies on the fact that mysqladmin will
 
469
    execute commands in the order specified, e.g.
 
470
    mysqladmin -u root flush-privileges password "newpassword"
 
471
    to reset a lost root password.
 
472
    If this behaviour is ever changed, Docs should be notified.
 
473
  */
 
474
 
 
475
  struct rand_struct rand_st;
 
476
 
 
477
  for (; argc > 0 ; argv++,argc--)
 
478
  {
 
479
    switch (find_type(argv[0],&command_typelib,2)) {
 
480
    case ADMIN_CREATE:
 
481
    {
 
482
      char buff[FN_REFLEN+20];
 
483
      if (argc < 2)
 
484
      {
 
485
        my_printf_error(0, "Too few arguments to create", error_flags);
 
486
        return 1;
 
487
      }
 
488
      sprintf(buff,"create database `%.*s`",FN_REFLEN,argv[1]);
 
489
      if (mysql_query(mysql,buff))
 
490
      {
 
491
        my_printf_error(0,"CREATE DATABASE failed; error: '%-.200s'",
 
492
                        error_flags, mysql_error(mysql));
 
493
        return -1;
 
494
      }
 
495
      argc--; argv++;
 
496
      break;
 
497
    }
 
498
    case ADMIN_DROP:
 
499
    {
 
500
      if (argc < 2)
 
501
      {
 
502
        my_printf_error(0, "Too few arguments to drop", error_flags);
 
503
        return 1;
 
504
      }
 
505
      if (drop_db(mysql,argv[1]))
 
506
        return -1;
 
507
      argc--; argv++;
 
508
      break;
 
509
    }
 
510
    case ADMIN_SHUTDOWN:
 
511
    {
 
512
      char pidfile[FN_REFLEN];
 
513
      bool got_pidfile= 0;
 
514
      time_t last_modified= 0;
 
515
      struct stat pidfile_status;
 
516
 
 
517
      /*
 
518
        Only wait for pidfile on local connections
 
519
        If pidfile doesn't exist, continue without pid file checking
 
520
      */
 
521
      if (mysql->unix_socket && (got_pidfile= !get_pidfile(mysql, pidfile)) &&
 
522
          !stat(pidfile, &pidfile_status))
 
523
        last_modified= pidfile_status.st_mtime;
 
524
 
 
525
      if (mysql_shutdown(mysql, SHUTDOWN_DEFAULT))
 
526
      {
 
527
        my_printf_error(0, "shutdown failed; error: '%s'", error_flags,
 
528
                        mysql_error(mysql));
 
529
        return -1;
 
530
      }
 
531
      mysql_close(mysql);       /* Close connection to avoid error messages */
 
532
      argc=1;                   /* force SHUTDOWN to be the last command    */
 
533
      if (got_pidfile)
 
534
      {
 
535
        if (opt_verbose)
 
536
          printf("Shutdown signal sent to server;  Waiting for pid file to disappear\n");
 
537
 
 
538
        /* Wait until pid file is gone */
 
539
        if (wait_pidfile(pidfile, last_modified, &pidfile_status))
 
540
          return -1;
 
541
      }
 
542
      break;
 
543
    }
 
544
    case ADMIN_FLUSH_PRIVILEGES:
 
545
    case ADMIN_RELOAD:
 
546
      if (mysql_query(mysql,"flush privileges"))
 
547
      {
 
548
        my_printf_error(0, "reload failed; error: '%s'", error_flags,
 
549
                        mysql_error(mysql));
 
550
        return -1;
 
551
      }
 
552
      break;
 
553
    case ADMIN_REFRESH:
 
554
      if (mysql_refresh(mysql,
 
555
                        (uint) ~(REFRESH_GRANT | REFRESH_STATUS |
 
556
                                 REFRESH_READ_LOCK | REFRESH_SLAVE |
 
557
                                 REFRESH_MASTER)))
 
558
      {
 
559
        my_printf_error(0, "refresh failed; error: '%s'", error_flags,
 
560
                        mysql_error(mysql));
 
561
        return -1;
 
562
      }
 
563
      break;
 
564
    case ADMIN_FLUSH_THREADS:
 
565
      if (mysql_refresh(mysql,(uint) REFRESH_THREADS))
 
566
      {
 
567
        my_printf_error(0, "refresh failed; error: '%s'", error_flags,
 
568
                        mysql_error(mysql));
 
569
        return -1;
 
570
      }
 
571
      break;
 
572
    case ADMIN_VER:
 
573
      new_line=1;
 
574
      print_version();
 
575
      puts("Copyright (C) 2000-2006 MySQL AB");
 
576
      puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
 
577
      printf("Server version\t\t%s\n", mysql_get_server_info(mysql));
 
578
      printf("Protocol version\t%d\n", mysql_get_proto_info(mysql));
 
579
      printf("Connection\t\t%s\n",mysql_get_host_info(mysql));
 
580
      if (mysql->unix_socket)
 
581
        printf("UNIX socket\t\t%s\n", mysql->unix_socket);
 
582
      else
 
583
        printf("TCP port\t\t%d\n", mysql->port);
 
584
      status=mysql_stat(mysql);
 
585
      {
 
586
        char *pos,buff[40];
 
587
        ulong sec;
 
588
        pos= (char*) strchr(status,' ');
 
589
        *pos++=0;
 
590
        printf("%s\t\t\t",status);                      /* print label */
 
591
        if ((status=str2int(pos,10,0,LONG_MAX,(long*) &sec)))
 
592
        {
 
593
          nice_time(sec,buff);
 
594
          puts(buff);                           /* print nice time */
 
595
          while (*status == ' ') status++;      /* to next info */
 
596
        }
 
597
      }
 
598
      putc('\n',stdout);
 
599
      if (status)
 
600
        puts(status);
 
601
      break;
 
602
    case ADMIN_PROCESSLIST:
 
603
    {
 
604
      MYSQL_RES *result;
 
605
      MYSQL_ROW row;
 
606
 
 
607
      if (mysql_query(mysql, (opt_verbose ? "show full processlist" :
 
608
                              "show processlist")) ||
 
609
          !(result = mysql_store_result(mysql)))
 
610
      {
 
611
        my_printf_error(0, "process list failed; error: '%s'", error_flags,
 
612
                        mysql_error(mysql));
 
613
        return -1;
 
614
      }
 
615
      print_header(result);
 
616
      while ((row=mysql_fetch_row(result)))
 
617
        print_row(result,row,0);
 
618
      print_top(result);
 
619
      mysql_free_result(result);
 
620
      new_line=1;
 
621
      break;
 
622
    }
 
623
    case ADMIN_STATUS:
 
624
      status=mysql_stat(mysql);
 
625
      if (status)
 
626
        puts(status);
 
627
      break;
 
628
    case ADMIN_KILL:
 
629
      {
 
630
        uint error=0;
 
631
        char *pos;
 
632
        if (argc < 2)
 
633
        {
 
634
          my_printf_error(0, "Too few arguments to 'kill'", error_flags);
 
635
          return 1;
 
636
        }
 
637
        pos=argv[1];
 
638
        for (;;)
 
639
        {
 
640
          if (mysql_kill(mysql,(ulong) atol(pos)))
 
641
          {
 
642
            my_printf_error(0, "kill failed on %ld; error: '%s'", error_flags,
 
643
                            atol(pos), mysql_error(mysql));
 
644
            error=1;
 
645
          }
 
646
          if (!(pos=strchr(pos,',')))
 
647
            break;
 
648
          pos++;
 
649
        }
 
650
        argc--; argv++;
 
651
        if (error)
 
652
          return -1;
 
653
        break;
 
654
      }
 
655
    case ADMIN_DEBUG:
 
656
      if (mysql_dump_debug_info(mysql))
 
657
      {
 
658
        my_printf_error(0, "debug failed; error: '%s'", error_flags,
 
659
                        mysql_error(mysql));
 
660
        return -1;
 
661
      }
 
662
      break;
 
663
    case ADMIN_VARIABLES:
 
664
    {
 
665
      MYSQL_RES *res;
 
666
      MYSQL_ROW row;
 
667
 
 
668
      new_line=1;
 
669
      if (mysql_query(mysql,"show /*!40003 GLOBAL */ variables") ||
 
670
          !(res=mysql_store_result(mysql)))
 
671
      {
 
672
        my_printf_error(0, "unable to show variables; error: '%s'", error_flags,
 
673
                        mysql_error(mysql));
 
674
        return -1;
 
675
      }
 
676
      print_header(res);
 
677
      while ((row=mysql_fetch_row(res)))
 
678
        print_row(res,row,0);
 
679
      print_top(res);
 
680
      mysql_free_result(res);
 
681
      break;
 
682
    }
 
683
    case ADMIN_EXTENDED_STATUS:
 
684
    {
 
685
      MYSQL_RES *res;
 
686
      MYSQL_ROW row;
 
687
      uint rownr = 0;
 
688
      void (*func) (MYSQL_RES*, MYSQL_ROW, uint);
 
689
 
 
690
      new_line = 1;
 
691
      if (mysql_query(mysql, "show /*!50002 GLOBAL */ status") ||
 
692
          !(res = mysql_store_result(mysql)))
 
693
      {
 
694
        my_printf_error(0, "unable to show status; error: '%s'", error_flags,
 
695
                        mysql_error(mysql));
 
696
        return -1;
 
697
      }
 
698
      if (!opt_vertical)
 
699
        print_header(res);
 
700
      else
 
701
      {
 
702
        if (!ex_status_printed)
 
703
        {
 
704
          store_values(res);
 
705
          truncate_names();   /* Does some printing also */
 
706
        }
 
707
        else
 
708
        {
 
709
          print_relative_line();
 
710
          print_relative_header();
 
711
          print_relative_line();
 
712
        }
 
713
      }
 
714
 
 
715
      /*      void (*func) (MYSQL_RES*, MYSQL_ROW, uint); */
 
716
      if (opt_relative && !opt_vertical)
 
717
        func = print_relative_row;
 
718
      else if (opt_vertical)
 
719
        func = print_relative_row_vert;
 
720
      else
 
721
        func = print_row;
 
722
 
 
723
      while ((row = mysql_fetch_row(res)))
 
724
        (*func)(res, row, rownr++);
 
725
      if (opt_vertical)
 
726
      {
 
727
        if (ex_status_printed)
 
728
        {
 
729
          putchar('\n');
 
730
          print_relative_line();
 
731
        }
 
732
      }
 
733
      else
 
734
        print_top(res);
 
735
 
 
736
      ex_status_printed = 1; /* From now on the output will be relative */
 
737
      mysql_free_result(res);
 
738
      break;
 
739
    }
 
740
    case ADMIN_FLUSH_LOGS:
 
741
    {
 
742
      if (mysql_refresh(mysql,REFRESH_LOG))
 
743
      {
 
744
        my_printf_error(0, "refresh failed; error: '%s'", error_flags,
 
745
                        mysql_error(mysql));
 
746
        return -1;
 
747
      }
 
748
      break;
 
749
    }
 
750
    case ADMIN_FLUSH_HOSTS:
 
751
    {
 
752
      if (mysql_query(mysql,"flush hosts"))
 
753
      {
 
754
        my_printf_error(0, "refresh failed; error: '%s'", error_flags,
 
755
                        mysql_error(mysql));
 
756
        return -1;
 
757
      }
 
758
      break;
 
759
    }
 
760
    case ADMIN_FLUSH_TABLES:
 
761
    {
 
762
      if (mysql_query(mysql,"flush tables"))
 
763
      {
 
764
        my_printf_error(0, "refresh failed; error: '%s'", error_flags,
 
765
                        mysql_error(mysql));
 
766
        return -1;
 
767
      }
 
768
      break;
 
769
    }
 
770
    case ADMIN_FLUSH_STATUS:
 
771
    {
 
772
      if (mysql_query(mysql,"flush status"))
 
773
      {
 
774
        my_printf_error(0, "refresh failed; error: '%s'", error_flags,
 
775
                        mysql_error(mysql));
 
776
        return -1;
 
777
      }
 
778
      break;
 
779
    }
 
780
    case ADMIN_OLD_PASSWORD:
 
781
    case ADMIN_PASSWORD:
 
782
    {
 
783
      char buff[128],crypted_pw[64];
 
784
      time_t start_time;
 
785
      /* Do initialization the same way as we do in mysqld */
 
786
      start_time=time((time_t*) 0);
 
787
      randominit(&rand_st,(ulong) start_time,(ulong) start_time/2);
 
788
 
 
789
      if (argc < 2)
 
790
      {
 
791
        my_printf_error(0, "Too few arguments to change password", error_flags);
 
792
        return 1;
 
793
      }
 
794
      if (argv[1][0])
 
795
      {
 
796
        char *pw= argv[1];
 
797
        bool old= (find_type(argv[0], &command_typelib, 2) ==
 
798
                   ADMIN_OLD_PASSWORD);
 
799
        /*
 
800
           If we don't already know to use an old-style password, see what
 
801
           the server is using
 
802
        */
 
803
        if (!old)
 
804
        {
 
805
          if (mysql_query(mysql, "SHOW VARIABLES LIKE 'old_passwords'"))
 
806
          {
 
807
            my_printf_error(0, "Could not determine old_passwords setting from server; error: '%s'",
 
808
                            error_flags, mysql_error(mysql));
 
809
            return -1;
 
810
          }
 
811
          else
 
812
          {
 
813
            MYSQL_RES *res= mysql_store_result(mysql);
 
814
            if (!res)
 
815
            {
 
816
              my_printf_error(0,
 
817
                              "Could not get old_passwords setting from "
 
818
                              "server; error: '%s'",
 
819
                              error_flags, mysql_error(mysql));
 
820
              return -1;
 
821
            }
 
822
            if (!mysql_num_rows(res))
 
823
              old= 1;
 
824
            else
 
825
            {
 
826
              MYSQL_ROW row= mysql_fetch_row(res);
 
827
              old= !strncmp(row[1], "ON", 2);
 
828
            }
 
829
            mysql_free_result(res);
 
830
          }
 
831
        }
 
832
        if (old)
 
833
          make_scrambled_password_323(crypted_pw, pw);
 
834
        else
 
835
          make_scrambled_password(crypted_pw, pw);
 
836
      }
 
837
      else
 
838
        crypted_pw[0]=0;                        /* No password */
 
839
      sprintf(buff,"set password='%s',sql_log_off=0",crypted_pw);
 
840
 
 
841
      if (mysql_query(mysql,"set sql_log_off=1"))
 
842
      {
 
843
        my_printf_error(0, "Can't turn off logging; error: '%s'",
 
844
                        error_flags, mysql_error(mysql));
 
845
        return -1;
 
846
      }
 
847
      if (mysql_query(mysql,buff))
 
848
      {
 
849
        if (mysql_errno(mysql)!=1290)
 
850
        {
 
851
          my_printf_error(0,"unable to change password; error: '%s'",
 
852
                          error_flags, mysql_error(mysql));
 
853
          return -1;
 
854
        }
 
855
        else
 
856
        {
 
857
          /*
 
858
            We don't try to execute 'update mysql.user set..'
 
859
            because we can't perfectly find out the host
 
860
           */
 
861
          my_printf_error(0,"\n"
 
862
                          "You cannot use 'password' command as mysqld runs\n"
 
863
                          " with grant tables disabled (was started with"
 
864
                          " --skip-grant-tables).\n"
 
865
                          "Use: \"mysqladmin flush-privileges password '*'\""
 
866
                          " instead", error_flags);
 
867
          return -1;
 
868
        }
 
869
      }
 
870
      argc--; argv++;
 
871
      break;
 
872
    }
 
873
 
 
874
    case ADMIN_START_SLAVE:
 
875
      if (mysql_query(mysql, "START SLAVE"))
 
876
      {
 
877
        my_printf_error(0, "Error starting slave: %s", error_flags,
 
878
                        mysql_error(mysql));
 
879
        return -1;
 
880
      }
 
881
      else
 
882
        puts("Slave started");
 
883
      break;
 
884
    case ADMIN_STOP_SLAVE:
 
885
      if (mysql_query(mysql, "STOP SLAVE"))
 
886
      {
 
887
          my_printf_error(0, "Error stopping slave: %s", error_flags,
 
888
                          mysql_error(mysql));
 
889
          return -1;
 
890
      }
 
891
      else
 
892
        puts("Slave stopped");
 
893
      break;
 
894
 
 
895
    case ADMIN_PING:
 
896
      mysql->reconnect=0;       /* We want to know of reconnects */
 
897
      if (!mysql_ping(mysql))
 
898
      {
 
899
        if (option_silent < 2)
 
900
          puts("mysqld is alive");
 
901
      }
 
902
      else
 
903
      {
 
904
        if (mysql_errno(mysql) == CR_SERVER_GONE_ERROR)
 
905
        {
 
906
          mysql->reconnect=1;
 
907
          if (!mysql_ping(mysql))
 
908
            puts("connection was down, but mysqld is now alive");
 
909
        }
 
910
        else
 
911
        {
 
912
          my_printf_error(0,"mysqld doesn't answer to ping, error: '%s'",
 
913
                          error_flags, mysql_error(mysql));
 
914
          return -1;
 
915
        }
 
916
      }
 
917
      mysql->reconnect=1;       /* Automatic reconnect is default */
 
918
      break;
 
919
    default:
 
920
      my_printf_error(0, "Unknown command: '%-.60s'", error_flags, argv[0]);
 
921
      return 1;
 
922
    }
 
923
  }
 
924
  return 0;
 
925
}
 
926
 
 
927
#include <help_start.h>
 
928
 
 
929
static void print_version(void)
 
930
{
 
931
  printf("%s  Ver %s Distrib %s, for %s on %s\n",my_progname,ADMIN_VERSION,
 
932
         MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
 
933
}
 
934
 
 
935
 
 
936
static void usage(void)
 
937
{
 
938
  print_version();
 
939
  puts("Copyright (C) 2000-2006 MySQL AB");
 
940
  puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
 
941
  puts("Administration program for the mysqld daemon.");
 
942
  printf("Usage: %s [OPTIONS] command command....\n", my_progname);
 
943
  my_print_help(my_long_options);
 
944
  my_print_variables(my_long_options);
 
945
  print_defaults("my",load_default_groups);
 
946
  puts("\nWhere command is a one or more of: (Commands may be shortened)\n\
 
947
  create databasename   Create a new database\n\
 
948
  debug                 Instruct server to write debug information to log\n\
 
949
  drop databasename     Delete a database and all its tables\n\
 
950
  extended-status       Gives an extended status message from the server\n\
 
951
  flush-hosts           Flush all cached hosts\n\
 
952
  flush-logs            Flush all logs\n\
 
953
  flush-status          Clear status variables\n\
 
954
  flush-tables          Flush all tables\n\
 
955
  flush-threads         Flush the thread cache\n\
 
956
  flush-privileges      Reload grant tables (same as reload)\n\
 
957
  kill id,id,...        Kill mysql threads");
 
958
#if MYSQL_VERSION_ID >= 32200
 
959
  puts("\
 
960
  password new-password Change old password to new-password, MySQL 4.1 hashing.\n\
 
961
  old-password new-password Change old password to new-password in old format.\n");
 
962
#endif
 
963
  puts("\
 
964
  ping                  Check if mysqld is alive\n\
 
965
  processlist           Show list of active threads in server\n\
 
966
  reload                Reload grant tables\n\
 
967
  refresh               Flush all tables and close and open logfiles\n\
 
968
  shutdown              Take server down\n\
 
969
  status                Gives a short status message from the server\n\
 
970
  start-slave           Start slave\n\
 
971
  stop-slave            Stop slave\n\
 
972
  variables             Prints variables available\n\
 
973
  version               Get version info from server");
 
974
}
 
975
 
 
976
#include <help_end.h>
 
977
 
 
978
static int drop_db(MYSQL *mysql, const char *db)
 
979
{
 
980
  char name_buff[FN_REFLEN+20], buf[10];
 
981
  if (!option_force)
 
982
  {
 
983
    puts("Dropping the database is potentially a very bad thing to do.");
 
984
    puts("Any data stored in the database will be destroyed.\n");
 
985
    printf("Do you really want to drop the '%s' database [y/N] ",db);
 
986
    fflush(stdout);
 
987
    VOID(fgets(buf,sizeof(buf)-1,stdin));
 
988
    if ((*buf != 'y') && (*buf != 'Y'))
 
989
    {
 
990
      puts("\nOK, aborting database drop!");
 
991
      return -1;
 
992
    }
 
993
  }
 
994
  sprintf(name_buff,"drop database `%.*s`",FN_REFLEN,db);
 
995
  if (mysql_query(mysql,name_buff))
 
996
  {
 
997
    my_printf_error(0, "DROP DATABASE %s failed;\nerror: '%s'", error_flags,
 
998
                    db,mysql_error(mysql));
 
999
    return 1;
 
1000
  }
 
1001
  printf("Database \"%s\" dropped\n",db);
 
1002
  return 0;
 
1003
}
 
1004
 
 
1005
 
 
1006
static void nice_time(ulong sec,char *buff)
 
1007
{
 
1008
  ulong tmp;
 
1009
 
 
1010
  if (sec >= 3600L*24)
 
1011
  {
 
1012
    tmp=sec/(3600L*24);
 
1013
    sec-=3600L*24*tmp;
 
1014
    buff=int10_to_str(tmp, buff, 10);
 
1015
    buff=strmov(buff,tmp > 1 ? " days " : " day ");
 
1016
  }
 
1017
  if (sec >= 3600L)
 
1018
  {
 
1019
    tmp=sec/3600L;
 
1020
    sec-=3600L*tmp;
 
1021
    buff=int10_to_str(tmp, buff, 10);
 
1022
    buff=strmov(buff,tmp > 1 ? " hours " : " hour ");
 
1023
  }
 
1024
  if (sec >= 60)
 
1025
  {
 
1026
    tmp=sec/60;
 
1027
    sec-=60*tmp;
 
1028
    buff=int10_to_str(tmp, buff, 10);
 
1029
    buff=strmov(buff," min ");
 
1030
  }
 
1031
  strmov(int10_to_str(sec, buff, 10)," sec");
 
1032
}
 
1033
 
 
1034
 
 
1035
static void print_header(MYSQL_RES *result)
 
1036
{
 
1037
  MYSQL_FIELD *field;
 
1038
 
 
1039
  print_top(result);
 
1040
  mysql_field_seek(result,0);
 
1041
  putchar('|');
 
1042
  while ((field = mysql_fetch_field(result)))
 
1043
  {
 
1044
    printf(" %-*s|",(int) field->max_length+1,field->name);
 
1045
  }
 
1046
  putchar('\n');
 
1047
  print_top(result);
 
1048
}
 
1049
 
 
1050
 
 
1051
static void print_top(MYSQL_RES *result)
 
1052
{
 
1053
  uint i,length;
 
1054
  MYSQL_FIELD *field;
 
1055
 
 
1056
  putchar('+');
 
1057
  mysql_field_seek(result,0);
 
1058
  while((field = mysql_fetch_field(result)))
 
1059
  {
 
1060
    if ((length=(uint) strlen(field->name)) > field->max_length)
 
1061
      field->max_length=length;
 
1062
    else
 
1063
      length=field->max_length;
 
1064
    for (i=length+2 ; i--> 0 ; )
 
1065
      putchar('-');
 
1066
    putchar('+');
 
1067
  }
 
1068
  putchar('\n');
 
1069
}
 
1070
 
 
1071
 
 
1072
/* 3.rd argument, uint row, is not in use. Don't remove! */
 
1073
static void print_row(MYSQL_RES *result, MYSQL_ROW cur,
 
1074
                      uint row __attribute__((unused)))
 
1075
{
 
1076
  uint i,length;
 
1077
  MYSQL_FIELD *field;
 
1078
 
 
1079
  putchar('|');
 
1080
  mysql_field_seek(result,0);
 
1081
  for (i=0 ; i < mysql_num_fields(result); i++)
 
1082
  {
 
1083
    field = mysql_fetch_field(result);
 
1084
    length=field->max_length;
 
1085
    printf(" %-*s|",length+1,cur[i] ? (char*) cur[i] : "");
 
1086
  }
 
1087
  putchar('\n');
 
1088
}
 
1089
 
 
1090
 
 
1091
static void print_relative_row(MYSQL_RES *result, MYSQL_ROW cur, uint row)
 
1092
{
 
1093
  uint64_t tmp;
 
1094
  char buff[22];
 
1095
  MYSQL_FIELD *field;
 
1096
 
 
1097
  mysql_field_seek(result, 0);
 
1098
  field = mysql_fetch_field(result);
 
1099
  printf("| %-*s|", (int) field->max_length + 1, cur[0]);
 
1100
 
 
1101
  field = mysql_fetch_field(result);
 
1102
  tmp = cur[1] ? strtoull(cur[1], NULL, 10) : (uint64_t) 0;
 
1103
  printf(" %-*s|\n", (int) field->max_length + 1,
 
1104
         llstr((tmp - last_values[row]), buff));
 
1105
  last_values[row] = tmp;
 
1106
}
 
1107
 
 
1108
 
 
1109
static void print_relative_row_vert(MYSQL_RES *result __attribute__((unused)),
 
1110
                                    MYSQL_ROW cur,
 
1111
                                    uint row __attribute__((unused)))
 
1112
{
 
1113
  uint length;
 
1114
  uint64_t tmp;
 
1115
  char buff[22];
 
1116
 
 
1117
  if (!row)
 
1118
    putchar('|');
 
1119
 
 
1120
  tmp = cur[1] ? strtoull(cur[1], NULL, 10) : (uint64_t) 0;
 
1121
  printf(" %-*s|", ex_val_max_len[row] + 1,
 
1122
         llstr((tmp - last_values[row]), buff));
 
1123
 
 
1124
  /* Find the minimum row length needed to output the relative value */
 
1125
  if ((length=(uint) strlen(buff) > ex_val_max_len[row]) && ex_status_printed)
 
1126
    ex_val_max_len[row] = length;
 
1127
  last_values[row] = tmp;
 
1128
}
 
1129
 
 
1130
 
 
1131
static void store_values(MYSQL_RES *result)
 
1132
{
 
1133
  uint i;
 
1134
  MYSQL_ROW row;
 
1135
  MYSQL_FIELD *field;
 
1136
 
 
1137
  field = mysql_fetch_field(result);
 
1138
  max_var_length = field->max_length;
 
1139
  field = mysql_fetch_field(result);
 
1140
  max_val_length = field->max_length;
 
1141
 
 
1142
  for (i = 0; (row = mysql_fetch_row(result)); i++)
 
1143
  {
 
1144
    strmov(ex_var_names[i], row[0]);
 
1145
    last_values[i]=strtoull(row[1],NULL,10);
 
1146
    ex_val_max_len[i]=2;                /* Default print width for values */
 
1147
  }
 
1148
  ex_var_count = i;
 
1149
  return;
 
1150
}
 
1151
 
 
1152
 
 
1153
static void print_relative_header()
 
1154
{
 
1155
  uint i;
 
1156
 
 
1157
  putchar('|');
 
1158
  for (i = 0; i < ex_var_count; i++)
 
1159
    printf(" %-*s|", ex_val_max_len[i] + 1, truncated_var_names[i]);
 
1160
  putchar('\n');
 
1161
}
 
1162
 
 
1163
 
 
1164
static void print_relative_line()
 
1165
{
 
1166
  uint i;
 
1167
 
 
1168
  putchar('+');
 
1169
  for (i = 0; i < ex_var_count; i++)
 
1170
  {
 
1171
    uint j;
 
1172
    for (j = 0; j < ex_val_max_len[i] + 2; j++)
 
1173
      putchar('-');
 
1174
    putchar('+');
 
1175
  }
 
1176
  putchar('\n');
 
1177
}
 
1178
 
 
1179
 
 
1180
static void truncate_names()
 
1181
{
 
1182
  uint i;
 
1183
  char *ptr,top_line[MAX_TRUNC_LENGTH+4+NAME_LEN+22+1],buff[22];
 
1184
 
 
1185
  ptr=top_line;
 
1186
  *ptr++='+';
 
1187
  ptr=strfill(ptr,max_var_length+2,'-');
 
1188
  *ptr++='+';
 
1189
  ptr=strfill(ptr,MAX_TRUNC_LENGTH+2,'-');
 
1190
  *ptr++='+';
 
1191
  ptr=strfill(ptr,max_val_length+2,'-');
 
1192
  *ptr++='+';
 
1193
  *ptr=0;
 
1194
  puts(top_line);
 
1195
 
 
1196
  for (i = 0 ; i < ex_var_count; i++)
 
1197
  {
 
1198
    uint sfx=1,j;
 
1199
    printf("| %-*s|", max_var_length + 1, ex_var_names[i]);
 
1200
    ptr = ex_var_names[i];
 
1201
    /* Make sure no two same truncated names will become */
 
1202
    for (j = 0; j < i; j++)
 
1203
      if (*truncated_var_names[j] == *ptr)
 
1204
        sfx++;
 
1205
 
 
1206
    truncated_var_names[i][0]= *ptr;            /* Copy first var char */
 
1207
    int10_to_str(sfx, truncated_var_names[i]+1,10);
 
1208
    printf(" %-*s|", MAX_TRUNC_LENGTH + 1, truncated_var_names[i]);
 
1209
    printf(" %-*s|\n", max_val_length + 1, llstr(last_values[i],buff));
 
1210
  }
 
1211
  puts(top_line);
 
1212
  return;
 
1213
}
 
1214
 
 
1215
 
 
1216
static bool get_pidfile(MYSQL *mysql, char *pidfile)
 
1217
{
 
1218
  MYSQL_RES* result;
 
1219
 
 
1220
  if (mysql_query(mysql, "SHOW VARIABLES LIKE 'pid_file'"))
 
1221
  {
 
1222
    my_printf_error(0, "query failed; error: '%s'", error_flags,
 
1223
                    mysql_error(mysql));
 
1224
  }
 
1225
  result = mysql_store_result(mysql);
 
1226
  if (result)
 
1227
  {
 
1228
    MYSQL_ROW row=mysql_fetch_row(result);
 
1229
    if (row)
 
1230
      strmov(pidfile, row[1]);
 
1231
    mysql_free_result(result);
 
1232
    return row == 0;                            /* Error if row = 0 */
 
1233
  }
 
1234
  return 1;                                     /* Error */
 
1235
}
 
1236
 
 
1237
/*
 
1238
  Return 1 if pid file didn't disappear or change
 
1239
*/
 
1240
 
 
1241
static bool wait_pidfile(char *pidfile, time_t last_modified,
 
1242
                            struct stat *pidfile_status)
 
1243
{
 
1244
  char buff[FN_REFLEN];
 
1245
  int error= 1;
 
1246
  uint count= 0;
 
1247
 
 
1248
 
 
1249
  system_filename(buff, pidfile);
 
1250
  do
 
1251
  {
 
1252
    int fd;
 
1253
    if ((fd= my_open(buff, O_RDONLY, MYF(0))) < 0)
 
1254
    {
 
1255
      error= 0;
 
1256
      break;
 
1257
    }
 
1258
    (void) my_close(fd,MYF(0));
 
1259
    if (last_modified && !stat(pidfile, pidfile_status))
 
1260
    {
 
1261
      if (last_modified != pidfile_status->st_mtime)
 
1262
      {
 
1263
        /* File changed;  Let's assume that mysqld did restart */
 
1264
        if (opt_verbose)
 
1265
          printf("pid file '%s' changed while waiting for it to disappear!\nmysqld did probably restart\n",
 
1266
                 buff);
 
1267
        error= 0;
 
1268
        break;
 
1269
      }
 
1270
    }
 
1271
    if (count++ == opt_shutdown_timeout)
 
1272
      break;
 
1273
    sleep(1);
 
1274
  } while (!interrupted);
 
1275
 
 
1276
  if (error)
 
1277
  {
 
1278
    fprintf(stderr,
 
1279
            "Warning;  Aborted waiting on pid file: '%s' after %d seconds\n",
 
1280
            buff, count-1);
 
1281
  }
 
1282
  return(error);
 
1283
}