~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/mysqladmin.cc

  • Committer: Brian Aker
  • Date: 2008-07-14 22:40:46 UTC
  • Revision ID: brian@tangent.org-20080714224046-x183907w9wp1txwv
Removed sql_manager. Ever heard of just setting up the OS to sync when you
want it to?

Show diffs side-by-side

added added

removed removed

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