~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/mysqladmin.cc

  • Committer: Monty Taylor
  • Date: 2008-07-05 11:20:18 UTC
  • mto: This revision was merged to the branch mainline in revision 62.
  • Revision ID: monty@inaugust.com-20080705112018-fr12kkmgphtu7m29
Changes so that removal of duplicate curr_dir from my_sys.h work.

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