~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/mysqladmin.cc

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