~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/mysqladmin.cc

MergingĀ mainline

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