1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 MySQL
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.
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.
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
21
/* maintaince of drizzle databases */
23
#include "client_priv.h"
25
#include <mysys/my_pthread.h> /* because of signal() */
28
/* Added this for string translation. */
29
#include <drizzled/gettext.h>
31
#define ADMIN_VERSION "8.42"
32
#define SHUTDOWN_DEF_TIMEOUT 3600 /* Wait for shutdown */
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;
39
static myf error_flags; /* flags to pass to my_printf_error, like ME_BELL */
46
static void usage(void);
47
static void print_version(void);
48
extern "C" RETSIGTYPE endprog(int signal_number);
49
extern "C" bool get_one_option(int optid, const struct my_option *opt,
51
static int execute_commands(DRIZZLE *drizzle,int argc, char **argv);
52
static bool sql_connect(DRIZZLE *drizzle, uint wait);
55
The order of commands must be the same as command_names,
64
static const char *command_names[]= {
70
static TYPELIB command_typelib=
71
{ array_elements(command_names)-1,"commands", command_names, NULL };
73
static struct my_option my_long_options[] =
75
{"help", '?', N_("Display this help and exit."), 0, 0, 0, GET_NO_ARG,
76
NO_ARG, 0, 0, 0, 0, 0, 0},
77
{"host", 'h', N_("Connect to host."), (char**) &host, (char**) &host, 0, GET_STR,
78
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
80
N_("Password to use when connecting to server. If password is not given it's asked from the tty."),
81
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
82
{"port", 'p', N_("Port number to use for connection or 0 for default to, in "
83
"order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, "
84
"built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ")."),
85
0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
86
{"silent", 's', N_("Silently exit if one can't connect to server."),
87
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
88
#ifndef DONT_ALLOW_USER_CHANGE
89
{"user", 'u', N_("User for login if not current user."), (char**) &user,
90
(char**) &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
92
{"verbose", 'v', N_("Write more information."), (char**) &opt_verbose,
93
(char**) &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
94
{"version", 'V', N_("Output version information and exit."), 0, 0, 0, GET_NO_ARG,
95
NO_ARG, 0, 0, 0, 0, 0, 0},
96
{"wait", 'w', N_("Wait and retry if connection is down."), 0, 0, 0, GET_UINT,
97
OPT_ARG, 0, 0, 0, 0, 0, 0},
98
{"connect_timeout", OPT_CONNECT_TIMEOUT, "", (char**) &opt_connect_timeout,
99
(char**) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 3600*12, 0,
101
{"shutdown_timeout", OPT_SHUTDOWN_TIMEOUT, "", (char**) &opt_shutdown_timeout,
102
(char**) &opt_shutdown_timeout, 0, GET_ULONG, REQUIRED_ARG,
103
SHUTDOWN_DEF_TIMEOUT, 0, 3600*12, 0, 1, 0},
104
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
108
static const char *load_default_groups[]= { "drizzleadmin","client",0 };
111
get_one_option(int optid, const struct my_option *, char *argument)
114
uint64_t temp_drizzle_port= 0;
119
temp_drizzle_port= (uint64_t) strtoul(argument, &endchar, 10);
120
/* if there is an alpha character this is not a valid port */
121
if (strlen(endchar) != 0)
123
fprintf(stderr, _("Non-integer value supplied for port. If you are trying to enter a password please use --password instead.\n"));
126
/* If the port number is > 65535 it is not a valid port
127
This also helps with potential data loss casting unsigned long to a
129
if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
131
fprintf(stderr, _("Value supplied for port is not valid.\n"));
136
tcp_port= (uint32_t) temp_drizzle_port;
142
char *start=argument;
146
opt_password= strdup(argument);
147
if (opt_password == NULL)
149
fprintf(stderr, _("Memory allocation error while copying password. "
155
/* Overwriting password with 'x' */
160
/* Cut length of argument */
177
if ((option_wait=atoi(argument)) <= 0)
181
option_wait= ~(uint)0;
197
int main(int argc,char *argv[])
199
int error= 0, ho_error;
201
char **commands, **save_argv;
204
drizzle_create(&drizzle);
205
load_defaults("drizzle",load_default_groups,&argc,&argv);
206
save_argv = argv; /* Save for free_defaults */
207
if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
209
free_defaults(save_argv);
221
opt_password = get_tty_password(NULL);
223
signal(SIGINT,endprog); /* Here if abort */
224
signal(SIGTERM,endprog); /* Here if abort */
226
if (opt_connect_timeout)
228
uint tmp=opt_connect_timeout;
229
drizzle_options(&drizzle,DRIZZLE_OPT_CONNECT_TIMEOUT, (char*) &tmp);
234
if (sql_connect(&drizzle, option_wait))
236
unsigned int err= drizzle_errno(&drizzle);
237
if (err >= CR_MIN_ERROR && err <= CR_MAX_ERROR)
241
/* Return 0 if all commands are PING */
242
for (; argc > 0; argv++, argc--)
244
if (find_type(argv[0], &command_typelib, 2) != ADMIN_PING)
254
error=execute_commands(&drizzle,argc,commands);
255
drizzle_close(&drizzle);
259
free_defaults(save_argv);
261
return error ? 1 : 0;
264
RETSIGTYPE endprog(int)
269
static bool sql_connect(DRIZZLE *drizzle, uint wait)
275
if (drizzle_connect(drizzle,host,user,opt_password,NULL,tcp_port,NULL,0))
277
drizzle->reconnect= 1;
281
(void) fflush(stderr);
291
host= (char*) LOCAL_HOST;
293
my_printf_error(0,_("connect to server at '%s' failed\nerror: '%s'"),
294
error_flags, host, drizzle_error(drizzle));
296
if (drizzle_errno(drizzle) == CR_CONN_HOST_ERROR ||
297
drizzle_errno(drizzle) == CR_UNKNOWN_HOST)
299
fprintf(stderr,_("Check that drizzled is running on %s"),host);
300
fprintf(stderr,_(" and that the port is %d.\n"),
301
tcp_port ? tcp_port: drizzle_get_default_port());
302
fprintf(stderr,_("You can check this by doing 'telnet %s %d'\n"),
303
host, tcp_port ? tcp_port: drizzle_get_default_port());
308
if (wait != UINT32_MAX)
309
wait--; /* One less retry */
310
if ((drizzle_errno(drizzle) != CR_CONN_HOST_ERROR) &&
311
(drizzle_errno(drizzle) != CR_CONNECTION_ERROR))
313
fprintf(stderr,_("Got error: %s\n"), drizzle_error(drizzle));
315
else if (!option_silent)
320
fputs(_("Waiting for Drizzle server to answer"),stderr);
321
(void) fflush(stderr);
326
(void) fflush(stderr);
336
-1 on retryable error
339
static int execute_commands(DRIZZLE *drizzle,int argc, char **argv)
343
DRIZZLE documentation relies on the fact that drizzleadmin will
344
execute commands in the order specified.
345
If this behaviour is ever changed, Docs should be notified.
347
for (; argc > 0 ; argv++,argc--)
349
switch (find_type(argv[0],&command_typelib,2)) {
353
printf(_("shutting down drizzled...\n"));
355
if (drizzle_shutdown(drizzle))
357
my_printf_error(0, _("shutdown failed; error: '%s'"), error_flags,
358
drizzle_error(drizzle));
361
drizzle_close(drizzle); /* Close connection to avoid error messages */
366
argc=1; /* Force SHUTDOWN to be the last command */
370
drizzle->reconnect=0; /* We want to know of reconnects */
371
if (!drizzle_ping(drizzle))
373
if (option_silent < 2)
374
puts(_("drizzled is alive"));
378
if (drizzle_errno(drizzle) == CR_SERVER_GONE_ERROR)
380
drizzle->reconnect=1;
381
if (!drizzle_ping(drizzle))
382
puts(_("connection was down, but drizzled is now alive"));
386
my_printf_error(0,_("drizzled doesn't answer to ping, error: '%s'"),
387
error_flags, drizzle_error(drizzle));
391
drizzle->reconnect=1; /* Automatic reconnect is default */
395
my_printf_error(0, _("Unknown command: '%-.60s'"), error_flags, argv[0]);
402
static void print_version(void)
404
printf(_("%s Ver %s Distrib %s, for %s on %s\n"),my_progname,ADMIN_VERSION,
405
drizzle_get_client_info(),SYSTEM_TYPE,MACHINE_TYPE);
408
static void usage(void)
411
puts(_("Copyright (C) 2000-2008 MySQL AB"));
412
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"));
413
puts(_("Administration program for the drizzled daemon."));
414
printf(_("Usage: %s [OPTIONS] command command....\n"), my_progname);
415
my_print_help(my_long_options);
417
ping Check if server is down\n\
418
shutdown Take server down\n"));