options.cc 9.85 KB
Newer Older
1
/* Copyright (C) 2003 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

17
#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
18
#pragma implementation
19 20
#endif

21 22
#include "options.h"

23
#include "priv.h"
unknown's avatar
unknown committed
24
#include "portability.h"
25 26
#include <my_sys.h>
#include <my_getopt.h>
27 28
#include <m_string.h>
#include <mysql_com.h>
29 30 31

#define QUOTE2(x) #x
#define QUOTE(x) QUOTE2(x)
32

33
#ifdef __WIN__
34 35
char Options::install_as_service;
char Options::remove_service;
unknown's avatar
unknown committed
36
char Options::stand_alone;
37 38 39 40
char windows_config_file[FN_REFLEN];
char default_password_file_name[FN_REFLEN];
char default_log_file_name[FN_REFLEN];
const char *Options::config_file= windows_config_file;
41 42 43
#else
char Options::run_as_service;
const char *Options::user= 0;                   /* No default value */
44 45
const char *default_password_file_name= QUOTE(DEFAULT_PASSWORD_FILE_NAME);
const char *default_log_file_name= QUOTE(DEFAULT_LOG_FILE_NAME);
46
const char *Options::config_file= QUOTE(DEFAULT_CONFIG_FILE);
47
#endif
48
const char *Options::log_file_name= default_log_file_name;
49 50
const char *Options::pid_file_name= QUOTE(DEFAULT_PID_FILE_NAME);
const char *Options::socket_file_name= QUOTE(DEFAULT_SOCKET_FILE_NAME);
51
const char *Options::password_file_name= default_password_file_name;
52
const char *Options::default_mysqld_path= QUOTE(DEFAULT_MYSQLD_PATH);
53
const char *Options::bind_address= 0;           /* No default value */
54 55
uint Options::monitoring_interval= DEFAULT_MONITORING_INTERVAL;
uint Options::port_number= DEFAULT_PORT;
56
/* just to declare */
57
char **Options::saved_argv= NULL;
58 59
/* Remember if the config file was forced */
bool Options::is_forced_default_file= 0;
60 61 62 63 64 65 66 67 68 69

/*
  List of options, accepted by the instance manager.
  List must be closed with empty option.
*/

enum options {
  OPT_LOG= 256,
  OPT_PID_FILE,
  OPT_SOCKET,
70 71
  OPT_PASSWORD_FILE,
  OPT_MYSQLD_PATH,
72
#ifndef __WIN__
73 74
  OPT_RUN_AS_SERVICE,
  OPT_USER,
75 76 77
#else
  OPT_INSTALL_SERVICE,
  OPT_REMOVE_SERVICE,
unknown's avatar
unknown committed
78
  OPT_STAND_ALONE,
79
#endif
80 81 82
  OPT_MONITORING_INTERVAL,
  OPT_PORT,
  OPT_BIND_ADDRESS
83
};
84

85 86 87 88 89 90 91 92 93 94 95 96
static struct my_option my_long_options[] =
{
  { "help", '?', "Display this help and exit.",
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },

  { "log", OPT_LOG, "Path to log file. Used only with --run-as-service.",
    (gptr *) &Options::log_file_name, (gptr *) &Options::log_file_name,
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },

  { "pid-file", OPT_PID_FILE, "Pid file to use.",
    (gptr *) &Options::pid_file_name, (gptr *) &Options::pid_file_name,
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
97

98 99 100 101
  { "socket", OPT_SOCKET, "Socket file to use for connection.",
    (gptr *) &Options::socket_file_name, (gptr *) &Options::socket_file_name,
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },

102 103 104
  { "passwd", 'P', "Prepare entry for passwd file and exit.", 0, 0, 0,
    GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },

unknown's avatar
unknown committed
105
  { "bind-address", OPT_BIND_ADDRESS, "Bind address to use for connection.",
106 107 108 109 110
    (gptr *) &Options::bind_address, (gptr *) &Options::bind_address,
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },

  { "port", OPT_PORT, "Port number to use for connections",
    (gptr *) &Options::port_number, (gptr *) &Options::port_number,
111
    0, GET_UINT, REQUIRED_ARG, DEFAULT_PORT, 0, 0, 0, 0, 0 },
112

unknown's avatar
unknown committed
113
  { "password-file", OPT_PASSWORD_FILE, "Look for Instance Manager users"
114 115 116 117 118
                                        " and passwords here.",
    (gptr *) &Options::password_file_name,
    (gptr *) &Options::password_file_name,
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },

unknown's avatar
unknown committed
119
  { "default-mysqld-path", OPT_MYSQLD_PATH, "Where to look for MySQL"
unknown's avatar
unknown committed
120 121 122
    " Server binary.",
    (gptr *) &Options::default_mysqld_path,
    (gptr *) &Options::default_mysqld_path,
123
    0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0 },
124

unknown's avatar
unknown committed
125 126 127 128 129 130
  { "monitoring-interval", OPT_MONITORING_INTERVAL, "Interval to monitor"
    " instances in seconds.",
    (gptr *) &Options::monitoring_interval,
    (gptr *) &Options::monitoring_interval,
    0, GET_UINT, REQUIRED_ARG, DEFAULT_MONITORING_INTERVAL,
    0, 0, 0, 0, 0 },
131
#ifdef __WIN__
unknown's avatar
unknown committed
132 133
  { "install", OPT_INSTALL_SERVICE, "Install as system service.",
    (gptr *) &Options::install_as_service, (gptr*) &Options::install_as_service,
134
    0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 0, 0 },
unknown's avatar
unknown committed
135 136
  { "remove", OPT_REMOVE_SERVICE, "Remove system service.",
    (gptr *)&Options::remove_service, (gptr*) &Options::remove_service,
137
    0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 0, 0},
unknown's avatar
unknown committed
138 139 140
  { "standalone", OPT_STAND_ALONE, "Run the application in stand alone mode.",
    (gptr *)&Options::stand_alone, (gptr*) &Options::stand_alone,
    0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 0, 0},
141
#else
142 143 144 145
  { "run-as-service", OPT_RUN_AS_SERVICE,
    "Daemonize and start angel process.", (gptr *) &Options::run_as_service,
    0, 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 0, 0 },

146
  { "user", OPT_USER, "Username to start mysqlmanager",
unknown's avatar
unknown committed
147 148 149
    (gptr *) &Options::user,
    (gptr *) &Options::user,
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
150
#endif
151
  { "version", 'V', "Output version information and exit.", 0, 0, 0,
unknown's avatar
unknown committed
152
    GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
153 154 155 156 157 158

  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }
};

static void version()
{
159
  printf("%s Ver %s for %s on %s\n", my_progname, mysqlmanager_version,
160 161 162
         SYSTEM_TYPE, MACHINE_TYPE);
}

163

unknown's avatar
unknown committed
164
static const char *default_groups[]= { "manager", 0 };
165 166


167 168 169
static void usage()
{
  version();
170 171 172 173 174 175

  printf("Copyright (C) 2003, 2004 MySQL AB\n"
  "This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
  "and you are welcome to modify and redistribute it under the GPL license\n");
  printf("Usage: %s [OPTIONS] \n", my_progname);

176
  my_print_help(my_long_options);
177 178 179 180 181 182
  printf("\nThe following options may be given as the first argument:\n"
  "--print-defaults        Print the program argument list and exit\n"
  "--defaults-file=#       Only read manager configuration and instance\n"
  "                        setings from the given file #. The same file\n"
  "                        will be used to modify configuration of instances\n"
  "                        with SET commands.\n");
183
  my_print_variables(my_long_options);
184 185
}

186 187 188

static void passwd()
{
189 190 191 192
  char user[1024], *p;
  const char *pw1, *pw2;
  char pw1msg[]= "Enter password: ";
  char pw2msg[]= "Re-type password: ";
193 194 195 196
  char crypted_pw[SCRAMBLED_PASSWORD_CHAR_LENGTH + 1];

  fprintf(stderr, "Creating record for new user.\n");
  fprintf(stderr, "Enter user name: ");
unknown's avatar
unknown committed
197
  if (!fgets(user, sizeof(user), stdin))
198 199 200 201 202 203
  {
    fprintf(stderr, "Unable to read user.\n");
    return;
  }
  if ((p= strchr(user, '\n'))) *p= 0;

204 205 206 207
  pw1= get_tty_password(pw1msg);
  pw2= get_tty_password(pw2msg);

  if (strcmp(pw1, pw2))
208
  {
209
    fprintf(stderr, "Sorry, passwords do not match.\n");
210 211 212
    return;
  }

213
  make_scrambled_password(crypted_pw, pw1);
214 215 216 217
  printf("%s:%s\n", user, crypted_pw);
}


218 219 220 221 222 223 224 225 226 227 228
C_MODE_START

static my_bool
get_one_option(int optid,
               const struct my_option *opt __attribute__((unused)),
               char *argument __attribute__((unused)))
{
  switch(optid) {
  case 'V':
    version();
    exit(0);
229 230 231
  case 'P':
    passwd();
    exit(0);
232 233 234 235 236 237 238 239 240 241
  case '?':
    usage();
    exit(0);
  }
  return 0;
}

C_MODE_END


242
/*
243 244 245 246
  - Process argv of original program: get tid of --defaults-extra-file
    and print a message if met there.
  - call load_defaults to load configuration file section and save the pointer
    for free_defaults.
247
  - call handle_options to assign defaults and command-line arguments
248 249
  to the class members.
  if either of these function fail, return the error code.
250 251
*/

unknown's avatar
unknown committed
252
int Options::load(int argc, char **argv)
253
{
254
  if (argc >= 2)
255
  {
256
    if (is_prefix(argv[1], "--defaults-file="))
257
    {
258
      Options::config_file= strchr(argv[1], '=') + 1;
259
      Options::is_forced_default_file= 1;
260
    }
261 262
    if (is_prefix(argv[1], "--defaults-extra-file=") ||
        is_prefix(argv[1], "--no-defaults"))
263 264
    {
      /* the log is not enabled yet */
265
      fprintf(stderr, "The --defaults-extra-file and --no-defaults options"
unknown's avatar
unknown committed
266 267
              " are not supported by\n"
              "Instance Manager. Program aborted.\n");
268
      goto err;
269
    }
270 271
  }

272
#ifdef __WIN__
273 274
  if (setup_windows_defaults())
    goto err;
275
#endif
unknown's avatar
unknown committed
276 277
  /* load_defaults will reset saved_argv with a new allocated list */
  saved_argv= argv;
278

279
  /* config-file options are prepended to command-line ones */
280
  load_defaults(config_file, default_groups, &argc,
281 282
                &saved_argv);

283 284
  if ((handle_options(&argc, &saved_argv, my_long_options,
                      get_one_option)) != 0)
285
    goto err;
286

unknown's avatar
unknown committed
287
  return 0;
288 289

err:
290
  return 1;
291 292
}

293 294 295
void Options::cleanup()
{
  /* free_defaults returns nothing */
296 297
  if (Options::saved_argv != NULL)
    free_defaults(Options::saved_argv);
298
}
299 300 301

#ifdef __WIN__

302
int Options::setup_windows_defaults()
303
{
304 305
  if (!GetModuleFileName(NULL, default_password_file_name,
                         sizeof(default_password_file_name)))
306
    return 1;
307
  char *filename= strstr(default_password_file_name, ".exe");
308
  strcpy(filename, ".passwd");
309
 
310 311
  if (!GetModuleFileName(NULL, default_log_file_name,
                         sizeof(default_log_file_name)))
312
    return 1;
313
  filename= strstr(default_log_file_name, ".exe");
314 315 316 317
  strcpy(filename, ".log");

  if (!GetModuleFileName(NULL, windows_config_file,
                         sizeof(windows_config_file)))
318
    return 1;
319
  char *slash= strrchr(windows_config_file, '\\');
320 321
  strcpy(slash, "\\my.ini");
  return 0;
322 323 324
}

#endif