~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzleadmin.cc

Merged in Jay's tree.

Show diffs side-by-side

added added

removed removed

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