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() */
31
/* Added this for string translation. */
32
#include <drizzled/gettext.h>
34
#define ADMIN_VERSION "8.42"
35
#define SHUTDOWN_DEF_TIMEOUT 3600 /* Wait for shutdown */
36
#define NUM_COMMAND_NAMES 2
38
char *host= NULL, *user= NULL, *opt_password= NULL;
39
static bool interrupted= false, opt_verbose= false,tty_password= false;
40
static uint32_t tcp_port= 0, option_wait= 0, option_silent= 0;
41
static uint32_t my_end_arg;
42
static uint32_t opt_connect_timeout, opt_shutdown_timeout;
49
static void usage(void);
50
static void print_version(void);
51
extern "C" void endprog(int signal_number);
52
extern "C" bool get_one_option(int optid, const struct my_option *opt,
54
static int execute_commands(drizzle_con_st *con,int argc, char **argv);
55
static bool sql_connect(drizzle_con_st *con, uint32_t wait);
58
The order of commands must be the same as command_names,
67
static string command_names[]= {
73
command_vector(command_names, command_names + NUM_COMMAND_NAMES);
75
static struct my_option my_long_options[] =
77
{"help", '?', N_("Display this help and exit."), 0, 0, 0, GET_NO_ARG,
78
NO_ARG, 0, 0, 0, 0, 0, 0},
79
{"host", 'h', N_("Connect to host."), (char**) &host, (char**) &host, 0, GET_STR,
80
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
82
N_("Password to use when connecting to server. If password is not given it's asked from the tty."),
83
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
84
{"port", 'p', N_("Port number to use for connection or 0 for default to, in "
85
"order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, "
86
"built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ")."),
87
0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
88
{"silent", 's', N_("Silently exit if one can't connect to server."),
89
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
90
#ifndef DONT_ALLOW_USER_CHANGE
91
{"user", 'u', N_("User for login if not current user."), (char**) &user,
92
(char**) &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
94
{"verbose", 'v', N_("Write more information."), (char**) &opt_verbose,
95
(char**) &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
96
{"version", 'V', N_("Output version information and exit."), 0, 0, 0, GET_NO_ARG,
97
NO_ARG, 0, 0, 0, 0, 0, 0},
98
{"wait", 'w', N_("Wait and retry if connection is down."), 0, 0, 0, GET_UINT,
99
OPT_ARG, 0, 0, 0, 0, 0, 0},
100
{"connect_timeout", OPT_CONNECT_TIMEOUT, "", (char**) &opt_connect_timeout,
101
(char**) &opt_connect_timeout, 0, GET_UINT32, REQUIRED_ARG, 3600*12, 0,
103
{"shutdown_timeout", OPT_SHUTDOWN_TIMEOUT, "", (char**) &opt_shutdown_timeout,
104
(char**) &opt_shutdown_timeout, 0, GET_UINT32, REQUIRED_ARG,
105
SHUTDOWN_DEF_TIMEOUT, 0, 3600*12, 0, 1, 0},
106
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
110
static const char *load_default_groups[]= { "drizzleadmin","client",0 };
112
inline string lower_string(const char * from_string)
114
string to_string= from_string;
115
transform(to_string.begin(), to_string.end(),
116
to_string.begin(), ::tolower);
121
* Searches for the given command and determines
124
* Returns the type of the command corresponding
125
* to the commands enum defined in drizzleadmin.cc
126
* If the command is not supported, return ADMIN_ERROR.
128
* @param command name to search for
130
static int get_command_type(const char *name)
132
int type= ADMIN_ERROR;
133
string comp_string= lower_string(name);
134
vector<string>::iterator it=
135
std::find(command_vector.begin(), command_vector.end(),
137
if (it != command_vector.end())
139
/* add 1 due to the way the commands ENUM is defined */
140
type= distance(command_vector.begin(), it) + 1;
146
get_one_option(int optid, const struct my_option *, char *argument)
149
uint64_t temp_drizzle_port= 0;
154
temp_drizzle_port= (uint64_t) strtoul(argument, &endchar, 10);
155
/* if there is an alpha character this is not a valid port */
156
if (strlen(endchar) != 0)
158
fprintf(stderr, _("Non-integer value supplied for port. If you are trying to enter a password please use --password instead.\n"));
161
/* If the port number is > 65535 it is not a valid port
162
This also helps with potential data loss casting unsigned long to a
164
if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
166
fprintf(stderr, _("Value supplied for port is not valid.\n"));
171
tcp_port= (uint32_t) temp_drizzle_port;
177
char *start= argument;
181
opt_password= strdup(argument);
182
if (opt_password == NULL)
184
fprintf(stderr, _("Memory allocation error while copying password. "
190
/* Overwriting password with 'x' */
195
/* Cut length of argument */
212
if ((option_wait=atoi(argument)) <= 0)
216
option_wait= ~(uint32_t)0;
232
int main(int argc,char *argv[])
234
int error= 0, ho_error;
237
char **commands, **save_argv;
240
drizzle_create(&drizzle);
241
drizzle_con_create(&drizzle, &con);
242
load_defaults("drizzle",load_default_groups,&argc,&argv);
243
save_argv= argv; /* Save for free_defaults */
244
if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
246
free_defaults(save_argv);
258
opt_password = client_get_tty_password(NULL);
260
signal(SIGINT,endprog); /* Here if abort */
261
signal(SIGTERM,endprog); /* Here if abort */
264
if (opt_connect_timeout)
266
uint32_t tmp= opt_connect_timeout;
267
drizzleclient_options(&drizzle,DRIZZLE_OPT_CONNECT_TIMEOUT, (char*) &tmp);
271
if (sql_connect(&con, option_wait))
273
/* Return 0 if all commands are PING */
274
for (; argc > 0; argv++, argc--)
276
int type= get_command_type(argv[0]);
277
if (type != ADMIN_PING)
286
error=execute_commands(&con,argc,commands);
288
drizzle_con_free(&con);
289
drizzle_free(&drizzle);
292
free_defaults(save_argv);
294
return error ? 1 : 0;
302
static bool sql_connect(drizzle_con_st *con, uint32_t wait)
305
drizzle_return_t ret;
307
drizzle_con_set_tcp(con, host, tcp_port);
308
drizzle_con_set_auth(con, user, opt_password);
312
ret= drizzle_con_connect(con);
313
if (ret == DRIZZLE_RETURN_OK)
318
(void) fflush(stderr);
328
host= (char *)DRIZZLE_DEFAULT_TCP_HOST;
330
fprintf(stderr,_("connect to server at '%s' failed\nerror: '%s'"),
331
host, drizzle_con_error(con));
333
if (ret == DRIZZLE_RETURN_GETADDRINFO ||
334
ret == DRIZZLE_RETURN_COULD_NOT_CONNECT)
336
fprintf(stderr,_("Check that drizzled is running on %s"),host);
337
fprintf(stderr,_(" and that the port is %d.\n"),
338
tcp_port ? tcp_port: DRIZZLE_DEFAULT_TCP_PORT);
339
fprintf(stderr,_("You can check this by doing 'telnet %s %d'\n"),
340
host, tcp_port ? tcp_port: DRIZZLE_DEFAULT_TCP_PORT);
345
if (wait != UINT32_MAX)
346
wait--; /* One less retry */
347
if (ret != DRIZZLE_RETURN_GETADDRINFO &&
348
ret != DRIZZLE_RETURN_COULD_NOT_CONNECT)
350
fprintf(stderr,_("Got error: %s\n"), drizzle_con_error(con));
352
else if (!option_silent)
357
fputs(_("Waiting for Drizzle server to answer"),stderr);
358
(void) fflush(stderr);
363
(void) fflush(stderr);
373
-1 on retryable error
376
static int execute_commands(drizzle_con_st *con,int argc, char **argv)
378
drizzle_result_st result;
379
drizzle_return_t ret;
382
DRIZZLE documentation relies on the fact that drizzleadmin will
383
execute commands in the order specified.
384
If this behaviour is ever changed, Docs should be notified.
386
for (; argc > 0 ; argv++,argc--)
388
int type= get_command_type(argv[0]);
393
printf(_("shutting down drizzled...\n"));
395
if (drizzle_shutdown(con, &result, DRIZZLE_SHUTDOWN_DEFAULT,
397
ret != DRIZZLE_RETURN_OK)
399
if (ret == DRIZZLE_RETURN_ERROR_CODE)
401
fprintf(stderr, _("shutdown failed; error: '%s'"),
402
drizzle_result_error(&result));
403
drizzle_result_free(&result);
407
fprintf(stderr, _("shutdown failed; error: '%s'"),
408
drizzle_con_error(con));
413
drizzle_result_free(&result);
417
argc= 1; /* Force SHUTDOWN to be the last command */
421
if (drizzle_ping(con, &result, &ret) != NULL && ret == DRIZZLE_RETURN_OK)
423
if (option_silent < 2)
424
puts(_("drizzled is alive"));
428
if (ret == DRIZZLE_RETURN_SERVER_GONE)
430
if (drizzle_ping(con, &result, &ret) != NULL &&
431
ret == DRIZZLE_RETURN_OK)
433
puts(_("connection was down, but drizzled is now alive"));
438
if (ret == DRIZZLE_RETURN_ERROR_CODE)
440
fprintf(stderr, _("shutdown failed; error: '%s'"),
441
drizzle_result_error(&result));
442
drizzle_result_free(&result);
446
fprintf(stderr,_("drizzled doesn't answer to ping, error: '%s'"),
447
drizzle_con_error(con));
452
drizzle_result_free(&result);
456
fprintf(stderr, _("Unknown command: '%-.60s'"), argv[0]);
463
static void print_version(void)
465
printf(_("%s Ver %s Distrib %s, for %s on %s\n"),my_progname,ADMIN_VERSION,
466
drizzle_version(),SYSTEM_TYPE,MACHINE_TYPE);
469
static void usage(void)
472
puts(_("Copyright (C) 2000-2008 MySQL AB"));
473
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"));
474
puts(_("Administration program for the drizzled daemon."));
475
printf(_("Usage: %s [OPTIONS] command command....\n"), my_progname);
476
my_print_help(my_long_options);
478
ping Check if server is down\n\
479
shutdown Take server down\n"));