~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/mysqladmin.cc

  • Committer: Brian Aker
  • Date: 2008-07-01 20:14:24 UTC
  • Revision ID: brian@tangent.org-20080701201424-rsof5enxl7gkr50p
More cleanup on pread()

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