~linuxjedi/drizzle/trunk-bug-667053

« back to all changes in this revision

Viewing changes to client/mysqladmin.cc

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

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