Commit 88301da1 authored by unknown's avatar unknown

Many files:

  new file
Makefile.am:
  Changes from Novell diff


netware/Makefile.am:
  Changes from Novell diff
BitKeeper/etc/logging_ok:
  Logging to logging@openlogging.org accepted
parent 2479bdea
......@@ -15,6 +15,7 @@ bell@sanja.is.com.ua
bk@admin.bk
davida@isil.mysql.com
gluh@gluh.(none)
gweir@work.mysql.com
heikki@donna.mysql.fi
heikki@hundin.mysql.fi
heikki@rescue.
......
# Copyright (C) 2002 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
#
# 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
# Copyright (c) 2002 Novell, Inc. All Rights Reserved.
#
# 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
## Process this file with automake to create Makefile.in
EXTRA_DIST = netware.patch
INCLUDES = -I$(srcdir)/../include -I../include -I..
bin_PROGRAMS = mysqld_safe mysql_install_db mysql_test_run libmysql
mysqld_safe_SOURCES= mysqld_safe.c my_manage.c
mysql_install_db_SOURCES= mysql_install_db.c my_manage.c
mysql_test_run_SOURCES= mysql_test_run.c my_manage.c
libmysql_SOURCES= libmysqlmain.c
libmysql_LDADD = ../libmysql/.libs/libmysqlclient.a
# Don't update the files from bitkeeper
%::SCCS/s.%
USE mysql;
CREATE TABLE db (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL, References_priv enum('N','Y') DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db,User), KEY User (User)) comment='Database privileges';
INSERT INTO db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y');
INSERT INTO db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y');
CREATE TABLE host (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL, References_priv enum('N','Y') DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db)) comment='Host privileges; Merged with database privileges';
CREATE TABLE user (Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Password char(16) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL, Reload_priv enum('N','Y') DEFAULT 'N' NOT NULL, Shutdown_priv enum('N','Y') DEFAULT 'N' NOT NULL, Process_priv enum('N','Y') DEFAULT 'N' NOT NULL, File_priv enum('N','Y') DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL, References_priv enum('N','Y') DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL, Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL, Super_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL, Repl_slave_priv enum('N','Y') DEFAULT 'N' NOT NULL, Repl_client_priv enum('N','Y') DEFAULT 'N' NOT NULL, ssl_type enum('','ANY','X509', 'SPECIFIED') DEFAULT '' NOT NULL, ssl_cipher BLOB NOT NULL, x509_issuer BLOB NOT NULL, x509_subject BLOB NOT NULL, max_questions int(11) unsigned DEFAULT 0 NOT NULL, max_updates int(11) unsigned DEFAULT 0 NOT NULL, max_connections int(11) unsigned DEFAULT 0 NOT NULL, PRIMARY KEY Host (Host,User)) comment='Users and global privileges';
INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
INSERT INTO user VALUES ('%','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
INSERT INTO user (host,user) values ('localhost','');
INSERT INTO user (host,user) values ('%','');
CREATE TABLE func (name char(64) binary DEFAULT '' NOT NULL, ret tinyint(1) DEFAULT '0' NOT NULL, dl char(128) DEFAULT '' NOT NULL, type enum ('function','aggregate') NOT NULL, PRIMARY KEY (name)) comment='User defined functions';
CREATE TABLE tables_priv (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(60) binary DEFAULT '' NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp(14), Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') DEFAULT '' NOT NULL, Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name), KEY Grantor (Grantor)) comment='Table privileges';
CREATE TABLE columns_priv (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Column_name char(64) binary DEFAULT '' NOT NULL, Timestamp timestamp(14), Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name)) comment='Column privileges';
# This functionality is handled by mysql-test-run.nlm on NetWare
myodbc_remove_escape,
mysql_add_slave,
mysql_affected_rows,
mysql_change_user,
mysql_character_set_name,
mysql_close,
mysql_data_seek,
mysql_debug,
mysql_disable_reads_from_master,
mysql_disable_rpl_parse,
mysql_dump_debug_info,
mysql_enable_reads_from_master,
mysql_enable_rpl_parse,
mysql_eof,
mysql_errno,
mysql_error,
mysql_escape_string,
mysql_fetch_field,
mysql_fetch_field_direct,
mysql_fetch_fields,
mysql_fetch_lengths,
mysql_fetch_row,
mysql_field_count,
mysql_field_seek,
mysql_field_tell,
mysql_free_result,
mysql_get_client_info,
mysql_get_host_info,
mysql_get_proto_info,
mysql_get_server_info,
mysql_info,
mysql_init,
mysql_insert_id,
mysql_kill,
mysql_list_dbs,
mysql_list_fields,
mysql_list_processes,
mysql_list_tables,
mysql_manager_close,
mysql_manager_command,
mysql_manager_connect,
mysql_manager_fetch_line,
mysql_manager_init,
mysql_master_query,
mysql_master_send_query,
mysql_num_fields,
mysql_num_rows,
mysql_odbc_escape_string,
mysql_options,
mysql_ping,
mysql_query,
mysql_read_query_result,
mysql_reads_from_master_enabled,
mysql_real_connect,
mysql_real_escape_string,
mysql_real_query,
mysql_refresh,
mysql_row_seek,
mysql_row_tell,
mysql_rpl_parse_enabled,
mysql_rpl_probe,
mysql_rpl_query_type,
mysql_select_db,
mysql_send_query,
mysql_server_end,
mysql_server_init,
mysql_set_master,
mysql_shutdown,
mysql_slave_query,
mysql_slave_send_query,
mysql_ssl_set,
mysql_stat,
mysql_store_result,
mysql_thread_end,
mysql_thread_id,
mysql_thread_init,
mysql_thread_safe,
mysql_use_result,
net_safe_read,
simple_command,
mysql_connect,
mysql_create_db,
mysql_drop_db,
/*
Copyright (c) 2002 Novell, Inc. All Rights Reserved.
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
*/
#include "my_global.h"
my_bool init_available_charsets(myf myflags);
/* this function is required so that global memory is allocated against this
library nlm, and not against a paticular client */
int _NonAppStart(void *NLMHandle, void *errorScreen, const char *commandLine,
const char *loadDirPath, size_t uninitializedDataLength,
void *NLMFileHandle, int (*readRoutineP)( int conn, void *fileHandle,
size_t offset, size_t nbytes, size_t *bytesRead, void *buffer ),
size_t customDataOffset, size_t customDataSize, int messageCount,
const char **messages)
{
mysql_server_init(0, NULL, NULL);
init_available_charsets(MYF(0));
return 0;
}
/*
Copyright (c) 2003 Novell, Inc. All Rights Reserved.
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
*/
#include <stdio.h>
#include <errno.h>
#include <dirent.h>
#include <string.h>
#include <screen.h>
#include <nks/vm.h>
#include <ctype.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include "my_manage.h"
/******************************************************************************
macros
******************************************************************************/
/******************************************************************************
global variables
******************************************************************************/
/******************************************************************************
functions
******************************************************************************/
/******************************************************************************
init_args()
Init an argument list.
******************************************************************************/
void _init_args(arg_list *al)
{
int i;
*al = malloc(sizeof(arg_list_t));
(*al)->argc = 0;
for(i = 0; i < ARG_MAX; i++)
{
(*al)->argv[i] = NULL;
}
}
/******************************************************************************
add_arg()
Add an argument to a list.
******************************************************************************/
void add_arg(arg_list al, char *format, ...)
{
va_list ap;
ASSERT(al != NULL);
ASSERT(al->argc < ARG_MAX);
al->argv[al->argc] = malloc(PATH_MAX);
ASSERT(al->argv[al->argc] != NULL);
va_start(ap, format);
vsprintf(al->argv[al->argc], format, ap);
va_end(ap);
++(al->argc);
}
/******************************************************************************
_free_args()
Free an argument list.
******************************************************************************/
void _free_args(arg_list *al)
{
int i;
ASSERT(al != NULL);
ASSERT(*al != NULL);
for(i = 0; i < (*al)->argc; i++)
{
ASSERT((*al)->argv[i] != NULL);
free((*al)->argv[i]);
(*al)->argv[i] = NULL;
}
free(*al);
*al = NULL;
}
/******************************************************************************
sleep_until_file_deleted()
Sleep until the given file is no longer found.
******************************************************************************/
int sleep_until_file_deleted(char *pid_file)
{
struct stat buf;
int i, err;
for(i = 0; (i < TRY_MAX) && (err = !stat(pid_file, &buf)); i++) sleep(1);
if (err != 0) err = errno;
return err;
}
/******************************************************************************
sleep_until_file_exists()
Sleep until the given file exists.
******************************************************************************/
int sleep_until_file_exists(char *pid_file)
{
struct stat buf;
int i, err;
for(i = 0; (i < TRY_MAX) && (err = stat(pid_file, &buf)); i++) sleep(1);
if (err != 0) err = errno;
return err;
}
/******************************************************************************
wait_for_server_start()
Wait for the server on the given port to start.
******************************************************************************/
int wait_for_server_start(char *bin_dir, char *user, char *password, int port)
{
arg_list al;
int err, i;
char mysqladmin_file[PATH_MAX];
char trash[PATH_MAX];
// mysqladmin file
snprintf(mysqladmin_file, PATH_MAX, "%s/mysqladmin", bin_dir);
snprintf(trash, PATH_MAX, "/tmp/trash.out");
// args
init_args(al);
add_arg(al, "%s", mysqladmin_file);
add_arg(al, "--no-defaults");
add_arg(al, "--port=%u", port);
add_arg(al, "--user=%s", user);
add_arg(al, "--password=%s", password);
add_arg(al, "--silent");
add_arg(al, "-O");
add_arg(al, "connect_timeout=10");
add_arg(al, "-w");
add_arg(al, "--host=localhost");
add_arg(al, "ping");
// NetWare does not support the connect timeout in the TCP/IP stack
// -- we will try the ping multiple times
for(i = 0; (i < TRY_MAX)
&& (err = spawn(mysqladmin_file, al, TRUE, NULL,
trash, NULL)); i++) sleep(1);
// free args
free_args(al);
return err;
}
/******************************************************************************
spawn()
Spawn the given file with the given arguments.
******************************************************************************/
int spawn(char *file, arg_list al, int join, char *input,
char *output, char *error)
{
NXNameSpec_t name;
NXExecEnvSpec_t env;
NXVmId_t vm, ignore;
int result;
// name
name.ssType = NX_OBJ_FILE;
name.ssPathCtx = 0;
name.ssPath = file;
// env
env.esArgc = al->argc;
env.esArgv = al->argv;
env.esEnv = NULL;
env.esStdin.ssPathCtx = 0;
env.esStdout.ssPathCtx = 0;
env.esStderr.ssPathCtx = 0;
if (input == NULL)
{
env.esStdin.ssType = NX_OBJ_DEFAULT;
env.esStdin.ssPath = NULL;
}
else
{
env.esStdin.ssType = NX_OBJ_FILE;
env.esStdin.ssPath = input;
}
if (output == NULL)
{
env.esStdout.ssType = NX_OBJ_DEFAULT;
env.esStdout.ssPath = NULL;
}
else
{
env.esStdout.ssType = NX_OBJ_FILE;
env.esStdout.ssPath = output;
}
if (error == NULL)
{
env.esStderr.ssType = NX_OBJ_DEFAULT;
env.esStderr.ssPath = NULL;
}
else
{
env.esStderr.ssType = NX_OBJ_FILE;
env.esStderr.ssPath = error;
}
result = NXVmSpawn(&name, &env, NX_VM_SAME_ADDRSPACE | NX_VM_INHERIT_ENV, &vm);
if (!result && join)
{
NXVmJoin(vm, &ignore, &result);
}
return result;
}
/******************************************************************************
stop_server()
Stop the server with the given port and pid file.
******************************************************************************/
int stop_server(char *bin_dir, char *user, char *password, int port,
char *pid_file)
{
arg_list al;
int err, i, argc = 0;
char mysqladmin_file[PATH_MAX];
char trash[PATH_MAX];
// mysqladmin file
snprintf(mysqladmin_file, PATH_MAX, "%s/mysqladmin", bin_dir);
snprintf(trash, PATH_MAX, "/tmp/trash.out");
// args
init_args(al);
add_arg(al, "%s", mysqladmin_file);
add_arg(al, "--no-defaults");
add_arg(al, "--port=%u", port);
add_arg(al, "--user=%s", user);
add_arg(al, "--password=%s", password);
add_arg(al, "-O");
add_arg(al, "shutdown_timeout=20");
add_arg(al, "shutdown");
// spawn
if ((err = spawn(mysqladmin_file, al, TRUE, NULL,
trash, NULL)) == 0)
{
sleep_until_file_deleted(pid_file);
}
else
{
pid_t pid = get_server_pid(pid_file);
// shutdown failed - kill server
kill_server(pid);
sleep(TRY_MAX);
// remove pid file if possible
err = remove(pid_file);
}
// free args
free_args(al);
return err;
}
/******************************************************************************
get_server_pid()
Get the VM id with the given pid file.
******************************************************************************/
pid_t get_server_pid(char *pid_file)
{
char buf[PATH_MAX];
int fd, err;
char *p;
pid_t id;
// discover id
fd = open(pid_file, O_RDONLY);
err = read(fd, buf, PATH_MAX);
close(fd);
if (err > 0)
{
// terminate string
if ((p = strchr(buf, '\n')) != NULL)
{
*p = NULL;
// check for a '\r'
if ((p = strchr(buf, '\r')) != NULL)
{
*p = NULL;
}
}
else
{
buf[err] = NULL;
}
id = strtol(buf, NULL, 0);
}
return id;
}
/******************************************************************************
kill_server()
Force a kill of the server with the given pid.
******************************************************************************/
void kill_server(pid_t pid)
{
if (pid > 0)
{
// destroy vm
NXVmDestroy(pid);
}
}
/******************************************************************************
del_tree()
Delete the directory and subdirectories.
******************************************************************************/
void del_tree(char *dir)
{
DIR *parent = opendir(dir);
DIR *entry;
char temp[PATH_MAX];
if (parent == NULL)
{
return;
}
while((entry = readdir(parent)) != NULL)
{
// create long name
snprintf(temp, PATH_MAX, "%s/%s", dir, entry->d_name);
if (entry->d_name[0] == '.')
{
// Skip
}
else if (S_ISDIR(entry->d_type))
{
// delete subdirectory
del_tree(temp);
}
else
{
// remove file
remove(temp);
}
}
// remove directory
rmdir(dir);
}
/******************************************************************************
removef()
******************************************************************************/
int removef(char *format, ...)
{
va_list ap;
char path[PATH_MAX];
va_start(ap, format);
vsnprintf(path, PATH_MAX, format, ap);
va_end(ap);
return remove(path);
}
/******************************************************************************
get_basedir()
******************************************************************************/
void get_basedir(char *argv0, char *basedir)
{
char temp[PATH_MAX];
char *p;
ASSERT(argv0 != NULL);
ASSERT(basedir != NULL);
strcpy(temp, strlwr(argv0));
while((p = strchr(temp, '\\')) != NULL) *p = '/';
if ((p = strindex(temp, "/bin/")) != NULL)
{
*p = NULL;
strcpy(basedir, temp);
}
}
/*
Copyright (c) 2002 Novell, Inc. All Rights Reserved.
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
*/
#ifndef _MY_MANAGE
#define _MY_MANAGE
/******************************************************************************
includes
******************************************************************************/
#include <stdlib.h>
#include <unistd.h>
/******************************************************************************
macros
******************************************************************************/
#define ARG_MAX 50
#define TRY_MAX 5
#define init_args(al) _init_args(&al);
#define free_args(al) _free_args(&al);
/******************************************************************************
structures
******************************************************************************/
typedef struct
{
int argc;
char *argv[ARG_MAX];
} arg_list_t, * arg_list;
/******************************************************************************
global variables
******************************************************************************/
/******************************************************************************
prototypes
******************************************************************************/
void _init_args(arg_list *);
void add_arg(arg_list, char *, ...);
void _free_args(arg_list *);
int sleep_until_file_exists(char *);
int sleep_until_file_deleted(char *);
int wait_for_server_start(char *, char *, char *, int);
int spawn(char *, arg_list, int, char *, char *, char *);
int stop_server(char *, char *, char *, int, char *);
pid_t get_server_pid(char *);
void kill_server(pid_t pid);
void del_tree(char *);
int removef(char *, ...);
void get_basedir(char *, char *);
#endif /* _MY_MANAGE */
/*
Copyright (c) 2002 Novell, Inc. All Rights Reserved.
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
*/
#include <stdlib.h>
#include <stdio.h>
#include <netdb.h>
#include <sys/stat.h>
#include <monitor.h>
#include <strings.h>
#include <getopt.h>
#include <screen.h>
#include "my_config.h"
#include "my_manage.h"
/******************************************************************************
global variables
******************************************************************************/
char autoclose;
char basedir[PATH_MAX];
char datadir[PATH_MAX];
char err_log[PATH_MAX];
char out_log[PATH_MAX];
char mysqld[PATH_MAX];
char hostname[PATH_MAX];
char sql_file[PATH_MAX];
char default_option[PATH_MAX];
/******************************************************************************
prototypes
******************************************************************************/
void start_defaults(int, char*[]);
void finish_defaults();
void read_defaults(arg_list);
void parse_args(int, char*[]);
void get_options(int, char*[]);
void create_paths();
int mysql_install_db(int argc, char *argv[]);
/******************************************************************************
functions
******************************************************************************/
/******************************************************************************
start_defaults()
Start setting the defaults.
******************************************************************************/
void start_defaults(int argc, char *argv[])
{
struct stat buf;
int i;
// default options
static char *default_options[] =
{
"--no-defaults",
"--defaults-file=",
"--defaults-extra-file=",
NULL
};
// autoclose
autoclose = FALSE;
// basedir
get_basedir(argv[0], basedir);
// hostname
if (gethostname(hostname,PATH_MAX) < 0)
{
// default
strcpy(hostname,"mysql");
}
// default option
default_option[0] = NULL;
for (i=0; (argc > 1) && default_options[i]; i++)
{
if(!strnicmp(argv[1], default_options[i], strlen(default_options[i])))
{
strncpy(default_option, argv[1], PATH_MAX);
break;
}
}
// set after basedir is established
datadir[0] = NULL;
err_log[0] = NULL;
out_log[0] = NULL;
mysqld[0] = NULL;
sql_file[0] = NULL;
}
/******************************************************************************
finish_defaults()
Finish setting the defaults.
******************************************************************************/
void finish_defaults()
{
struct stat buf;
int i;
// datadir
if (!datadir[0]) snprintf(datadir, PATH_MAX, "%s/data", basedir);
// err-log
if (!err_log[0]) snprintf(err_log, PATH_MAX, "%s/%s.err", datadir, hostname);
// out-log
if (!out_log[0]) snprintf(out_log, PATH_MAX, "%s/%s.out", datadir, hostname);
// sql-file
if (!sql_file[0]) snprintf(sql_file, PATH_MAX, "%s/bin/init_db.sql", basedir);
// mysqld
if (!mysqld[0]) snprintf(mysqld, PATH_MAX, "%s/bin/mysqld", basedir);
}
/******************************************************************************
read_defaults()
Read the defaults.
******************************************************************************/
void read_defaults(arg_list pal)
{
arg_list al;
char defaults_file[PATH_MAX];
char mydefaults[PATH_MAX];
char line[PATH_MAX];
FILE *fp;
// defaults output file
snprintf(defaults_file, PATH_MAX, "%s/bin/defaults.out", basedir);
remove(defaults_file);
// mysqladmin file
snprintf(mydefaults, PATH_MAX, "%s/bin/my_print_defaults", basedir);
// args
init_args(al);
add_arg(al, mydefaults);
if (default_option[0]) add_arg(al, default_option);
add_arg(al, "mysqld");
add_arg(al, "mysql_install_db");
spawn(mydefaults, al, TRUE, NULL, defaults_file, NULL);
free_args(al);
// gather defaults
if((fp = fopen(defaults_file, "r")) != NULL)
{
while(fgets(line, PATH_MAX, fp))
{
char *p;
// remove end-of-line character
if ((p = strrchr(line, '\n')) != NULL) *p = '\0';
// add the option as an argument
add_arg(pal, line);
}
fclose(fp);
}
// remove file
remove(defaults_file);
}
/******************************************************************************
parse_args()
Get the options.
******************************************************************************/
void parse_args(int argc, char *argv[])
{
int index = 0;
int c;
// parse options
enum opts
{
OPT_BASEDIR = 0xFF,
OPT_DATADIR,
OPT_SQL_FILE
};
static struct option options[] =
{
{"autoclose", no_argument, &autoclose, TRUE},
{"basedir", required_argument, 0, OPT_BASEDIR},
{"datadir", required_argument, 0, OPT_DATADIR},
{"sql-file", required_argument, 0, OPT_SQL_FILE},
{0, 0, 0, 0}
};
// we have to reset getopt_long because we use it multiple times
optind = 1;
// turn off error reporting
opterr = 0;
while ((c = getopt_long(argc, argv, "b:h:", options, &index)) >= 0)
{
switch (c)
{
case OPT_BASEDIR:
case 'b':
strcpy(basedir, optarg);
break;
case OPT_DATADIR:
case 'h':
strcpy(datadir, optarg);
break;
case OPT_SQL_FILE:
strcpy(sql_file, optarg);
break;
default:
// ignore
break;
}
}
}
/******************************************************************************
get_options()
Get the options.
******************************************************************************/
void get_options(int argc, char *argv[])
{
arg_list al;
// start defaults
start_defaults(argc, argv);
// default file arguments
init_args(al);
add_arg(al, "dummy");
read_defaults(al);
parse_args(al->argc, al->argv);
free_args(al);
// command-line arguments
parse_args(argc, argv);
// finish defaults
finish_defaults();
}
/******************************************************************************
create_paths()
Create database paths.
******************************************************************************/
void create_paths()
{
struct stat info;
char temp[PATH_MAX];
// check for tables
snprintf(temp, PATH_MAX, "%s/mysql/host.frm", datadir);
if (!stat(temp, &info))
{
printf("A database already exists in the directory:\n");
printf("\t%s\n\n", datadir);
exit(-1);
}
// data directory
if (stat(datadir, &info))
{
mkdir(datadir, 0);
}
// mysql directory
snprintf(temp, PATH_MAX, "%s/mysql", datadir);
if (stat(temp, &info))
{
mkdir(temp, 0);
}
// test directory
snprintf(temp, PATH_MAX, "%s/test", datadir);
if (stat(temp, &info))
{
mkdir(temp, 0);
}
}
/******************************************************************************
mysql_install_db()
Install the database.
******************************************************************************/
int mysql_install_db(int argc, char *argv[])
{
arg_list al;
int i, j, err;
char skip;
// private options
static char *private_options[] =
{
"--autoclose",
"--sql-file=",
NULL
};
// args
init_args(al);
add_arg(al, "%s", mysqld);
// parent args
for(i = 1; i < argc; i++)
{
skip = FALSE;
// skip private arguments
for (j=0; private_options[j]; j++)
{
if(!strnicmp(argv[i], private_options[j], strlen(private_options[j])))
{
skip = TRUE;
break;
}
}
if (!skip) add_arg(al, "%s", argv[i]);
}
add_arg(al, "--bootstrap");
add_arg(al, "--skip-grant-tables");
add_arg(al, "--skip-innodb");
add_arg(al, "--skip-bdb");
// spawn mysqld
err = spawn(mysqld, al, TRUE, sql_file, out_log, err_log);
// free args
free_args(al);
return err;
}
/******************************************************************************
main()
******************************************************************************/
int main(int argc, char **argv)
{
// get options
get_options(argc, argv);
// check for an autoclose option
if (!autoclose) setscreenmode(SCR_NO_MODE);
// create paths
create_paths();
// install the database
if (mysql_install_db(argc, argv))
{
printf("ERROR - The database creation failed!\n");
printf("See the following log for more infomration:\n");
printf("\t%s\n\n", err_log);
exit(-1);
}
// status
printf("Initial database successfully created in the directory:\n");
printf("\t%s\n", datadir);
// info
printf("\nPLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !\n");
printf("\nThis is done with:\n");
printf("\tmysqladmin -u root password 'new-password'\n");
printf("\nSee the manual for more instructions.\n");
printf("\nYou can start the MySQL daemon with:\n");
printf("\tmysqld_safe\n");
printf("\nPlease report any problems with:\n");
printf("\t/mysql/mysqlbug.txt\n");
printf("\nThe latest information about MySQL is available on the web at\n");
printf("\thttp://www.mysql.com\n");
printf("\nSupport MySQL by buying support at https://order.mysql.com\n\n");
return 0;
}
#-----------------------------------------------------------------------------
# Copyright (C) 2002 MySQL AB and Jeremy Cole
#
# 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
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# This notice applies to changes, created by or for Novell, Inc.,
# to preexisting works for which notices appear elsewhere in this file.
# Copyright (c) 2003 Novell, Inc. All Rights Reserved.
# 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
#-----------------------------------------------------------------------------
use strict;
use Mysql;
print "MySQL Secure Installation Script\n\n";
print "NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQL\n";
print " SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!\n\n";
#-----------------------------------------------------------------------------
# get the current root password
#-----------------------------------------------------------------------------
print "In order to log into MySQL to secure it, we'll need the current\n";
print "password for the root user. If you've just installed MySQL, and\n";
print "you haven't set the root password yet, the password will be blank,\n";
print "so you should just press enter here.\n\n";
print "Enter the current password for root: ";
my $password = <STDIN>;
chomp $password;
print "\n";
my $conn = Mysql->connect("localhost", "mysql", "root", $password)
|| die "Unable to connect to MySQL.";
print "OK, successfully used the password, moving on...\n\n";
#-----------------------------------------------------------------------------
# set the root password
#-----------------------------------------------------------------------------
unless ($password)
{
print "Setting the root password ensures that no one can log into MySQL\n";
print "using the root user without the proper authorization.\n\n";
print "Set root password (Y/N)? ";
my $reply = <STDIN>;
chomp $reply;
print "\n";
if ($reply =~ /Y/i)
{
print "New password for root: ";
my $pass1 = <STDIN>;
chomp $pass1;
print "\n";
print "Re-enter new password for root: ";
my $pass2 = <STDIN>;
chomp $pass2;
print "\n";
unless ($pass1 eq $pass2) { die "Sorry, the passwords do not match."; }
unless ($pass1) { die "Sorry, you can't use an empty password here."; }
$conn->query("SET PASSWORD FOR root\@localhost=PASSWORD('$pass1')")
|| die "Unable to set password.";
print "OK, successfully set the password, moving on...\n\n";
}
else
{
print "WARNING, the password is not set, moving on...\n\n";
}
}
#-----------------------------------------------------------------------------
# remove anonymous users
#-----------------------------------------------------------------------------
print "By default, a MySQL installation has anonymous users, allowing anyone\n";
print "to log into MySQL without having to have a user account created for\n";
print "them. This is intended only for testing, and to make the installation\n";
print "go a bit smoother. You should remove them before moving into a\n";
print "production environment.\n\n";
print "Remove anonymous users (Y/N)? ";
my $reply = <STDIN>;
chomp $reply;
print "\n";
if ($reply =~ /Y/i)
{
$conn->query("DELETE FROM mysql.user WHERE user=''")
|| die "Unable to remove anonymous users.";
print "OK, successfully removed anonymous users, moving on...\n\n";
}
else
{
print "WARNING, the anonymous users have not been removed, moving on...\n\n";
}
#-----------------------------------------------------------------------------
# disallow remote root login
#-----------------------------------------------------------------------------
print "Normally, root should only be allowed to connect from 'localhost'. This\n";
print "ensures that someone cannot guess at the root password from the network.\n\n";
print "Disallow remote root login (Y/N)? ";
my $reply = <STDIN>;
chomp $reply;
print "\n";
if ($reply =~ /Y/i)
{
$conn->query("DELETE FROM mysql.user WHERE user='root' AND host!='localhost'")
|| die "Unable to disallow remote root login.";
print "OK, successfully disallowed remote root login, moving on...\n\n";
}
else
{
print "WARNING, remote root login has not been disallowed, moving on...\n\n";
}
#-----------------------------------------------------------------------------
# remove test database
#-----------------------------------------------------------------------------
print "By default, MySQL comes with a database named 'test' that anyone can\n";
print "access. This is intended only for testing, and should be removed\n";
print "before moving into a production environment.\n\n";
print "Remove the test database (Y/N)? ";
my $reply = <STDIN>;
chomp $reply;
print "\n";
if ($reply =~ /Y/i)
{
$conn->query("DROP DATABASE IF EXISTS test")
|| die "Unable to remove test database.";
$conn->query("DELETE FROM mysql.db WHERE db='test' OR db='test\\_%'")
|| die "Unable to remove access to the test database.";
print "OK, successfully removed the test database, moving on...\n\n";
}
else
{
print "WARNING, the test database has not been removed, moving on...\n\n";
}
#-----------------------------------------------------------------------------
# reload privilege tables
#-----------------------------------------------------------------------------
print "Reloading the privilege tables will ensure that all changes made so far\n";
print "will take effect immediately.\n\n";
print "Reload privilege tables (Y/N)? ";
my $reply = <STDIN>;
chomp $reply;
print "\n";
if ($reply =~ /Y/i)
{
$conn->query("FLUSH PRIVILEGES")
|| die "Unable to reload privilege tables.";
print "OK, successfully reloaded privilege tables, moving on...\n\n";
}
else
{
print "WARNING, the privilege tables have not been reloaded, moving on...\n\n";
}
#-----------------------------------------------------------------------------
# done
#-----------------------------------------------------------------------------
print "\n\nAll done! If you've completed all of the above steps, your MySQL\n";
print "installation should now be secure.\n\n";
print "Thanks for using MySQL!\n\n";
/*
Copyright (c) 2002, 2003 Novell, Inc. All Rights Reserved.
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
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <dirent.h>
#include <string.h>
#include <screen.h>
#include <nks/vm.h>
#include <ctype.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include "my_manage.h"
/******************************************************************************
macros
******************************************************************************/
#define HEADER "TEST ELAPSED RESULT \n"
#define DASH "------------------------------------------------------------------------\n"
#define NW_TEST_SUFFIX ".nw-test"
#define NW_RESULT_SUFFIX ".nw-result"
#define TEST_SUFFIX ".test"
#define RESULT_SUFFIX ".result"
#define REJECT_SUFFIX ".reject"
#define OUT_SUFFIX ".out"
#define ERR_SUFFIX ".err"
#define TEST_PASS "[ pass ]"
#define TEST_SKIP "[ skip ]"
#define TEST_FAIL "[ fail ]"
#define TEST_BAD "[ bad ]"
/******************************************************************************
global variables
******************************************************************************/
char base_dir[PATH_MAX] = "sys:/mysql";
char db[PATH_MAX] = "test";
char user[PATH_MAX] = "root";
char password[PATH_MAX] = "";
int master_port = 9306;
int slave_port = 9307;
// comma delimited list of tests to skip or empty string
char skip_test[PATH_MAX] = "";
char bin_dir[PATH_MAX];
char mysql_test_dir[PATH_MAX];
char test_dir[PATH_MAX];
char mysql_tmp_dir[PATH_MAX];
char result_dir[PATH_MAX];
char master_dir[PATH_MAX];
char slave_dir[PATH_MAX];
char lang_dir[PATH_MAX];
char char_dir[PATH_MAX];
char mysqladmin_file[PATH_MAX];
char mysqld_file[PATH_MAX];
char mysqltest_file[PATH_MAX];
char master_pid[PATH_MAX];
char slave_pid[PATH_MAX];
char master_opt[PATH_MAX] = "";
char slave_opt[PATH_MAX] = "";
char slave_master_info[PATH_MAX] = "";
char master_init_script[PATH_MAX] = "";
char slave_init_script[PATH_MAX] = "";
int total_skip = 0;
int total_pass = 0;
int total_fail = 0;
int total_test = 0;
double total_time = 0;
int master_running = FALSE;
int slave_running = FALSE;
int skip_slave = TRUE;
int single_test = TRUE;
int restarts = 0;
FILE *log_fd = NULL;
/******************************************************************************
functions
******************************************************************************/
/******************************************************************************
prototypes
******************************************************************************/
void report_stats();
void install_db(char *);
void mysql_install_db();
void start_master();
void start_slave();
void mysql_start();
void stop_slave();
void stop_master();
void mysql_stop();
void mysql_restart();
int read_option(char *, char *);
void run_test(char *);
void setup(char *);
void vlog(char *, va_list);
void log(char *, ...);
void log_info(char *, ...);
void log_error(char *, ...);
void log_errno(char *, ...);
void die(char *);
/******************************************************************************
report_stats()
Report the gathered statistics.
******************************************************************************/
void report_stats()
{
if (total_fail == 0)
{
log("\nAll %d test(s) were successful.\n", total_test);
}
else
{
double percent = ((double)total_pass / total_test) * 100;
log("\nFailed %u/%u test(s), %.02f%% successful.\n",
total_fail, total_test, percent);
log("\nThe .out and .err files in %s may give you some\n", result_dir);
log("hint of what when wrong.\n");
log("\nIf you want to report this error, please first read the documentation\n");
log("at: http://www.mysql.com/doc/M/y/MySQL_test_suite.html\n");
}
log("\n%.02f total minutes elapsed in the test cases\n\n", total_time / 60);
}
/******************************************************************************
install_db()
Install the a database.
******************************************************************************/
void install_db(char *datadir)
{
arg_list al;
int err, i;
char input[PATH_MAX];
char output[PATH_MAX];
char error[PATH_MAX];
// input file
snprintf(input, PATH_MAX, "%s/bin/init_db.sql", base_dir);
snprintf(output, PATH_MAX, "%s/install.out", datadir);
snprintf(error, PATH_MAX, "%s/install.err", datadir);
// args
init_args(al);
add_arg(al, mysqld_file);
add_arg(al, "--bootstrap");
add_arg(al, "--skip-grant-tables");
add_arg(al, "--basedir=%s", base_dir);
add_arg(al, "--datadir=%s", datadir);
add_arg(al, "--skip-innodb");
add_arg(al, "--skip-bdb");
// spawn
if ((err = spawn(mysqld_file, al, TRUE, input, output, error)) != 0)
{
die("Unable to create database.");
}
// free args
free_args(al);
}
/******************************************************************************
mysql_install_db()
Install the test databases.
******************************************************************************/
void mysql_install_db()
{
char temp[PATH_MAX];
// var directory
snprintf(temp, PATH_MAX, "%s/var", mysql_test_dir);
// clean up old direcotry
del_tree(temp);
// create var directory
mkdir(temp, S_IRWXU);
// create subdirectories
snprintf(temp, PATH_MAX, "%s/var/run", mysql_test_dir);
mkdir(temp, S_IRWXU);
snprintf(temp, PATH_MAX, "%s/var/tmp", mysql_test_dir);
mkdir(temp, S_IRWXU);
snprintf(temp, PATH_MAX, "%s/var/master-data", mysql_test_dir);
mkdir(temp, S_IRWXU);
snprintf(temp, PATH_MAX, "%s/var/master-data/mysql", mysql_test_dir);
mkdir(temp, S_IRWXU);
snprintf(temp, PATH_MAX, "%s/var/master-data/test", mysql_test_dir);
mkdir(temp, S_IRWXU);
snprintf(temp, PATH_MAX, "%s/var/slave-data", mysql_test_dir);
mkdir(temp, S_IRWXU);
snprintf(temp, PATH_MAX, "%s/var/slave-data/mysql", mysql_test_dir);
mkdir(temp, S_IRWXU);
snprintf(temp, PATH_MAX, "%s/var/slave-data/test", mysql_test_dir);
mkdir(temp, S_IRWXU);
// install databases
install_db(master_dir);
install_db(slave_dir);
}
/******************************************************************************
start_master()
Start the master server.
******************************************************************************/
void start_master()
{
arg_list al;
int err, i;
char master_out[PATH_MAX];
char master_err[PATH_MAX];
// remove old berkeley db log files that can confuse the server
removef("%s/log.*", master_dir);
// remove stale binary logs
removef("%s/*-bin.*", master_dir);
// remove stale binary logs
removef("%s/*.index", master_dir);
// remove master.info file
removef("%s/master.info", master_dir);
// remove relay files
removef("%s/var/log/*relay*", mysql_test_dir);
// remove relay-log.info file
removef("%s/relay-log.info", master_dir);
// init script
if (master_init_script[0] != NULL)
{
// run_init_script(master_init_script);
}
// redirection files
snprintf(master_out, PATH_MAX, "%s/var/run/master%u.out",
mysql_test_dir, restarts);
snprintf(master_err, PATH_MAX, "%s/var/run/master%u.err",
mysql_test_dir, restarts);
// args
init_args(al);
add_arg(al, "%s", mysqld_file);
add_arg(al, "--no-defaults");
add_arg(al, "--log-bin=master-bin");
add_arg(al, "--server-id=1");
add_arg(al, "--basedir=%s", base_dir);
add_arg(al, "--port=%u", master_port);
add_arg(al, "--local-infile");
add_arg(al, "--core");
add_arg(al, "--datadir=%s", master_dir);
add_arg(al, "--pid-file=%s", master_pid);
add_arg(al, "--character-sets-dir=%s", char_dir);
add_arg(al, "--tmpdir=%s", mysql_tmp_dir);
add_arg(al, "--language=%s", lang_dir);
// $MASTER_40_ARGS
add_arg(al, "--rpl-recovery-rank=1");
add_arg(al, "--init-rpl-role=master");
// $SMALL_SERVER
add_arg(al, "-O");
add_arg(al, "key_buffer_size=1M");
add_arg(al, "-O");
add_arg(al, "sort_buffer=256K");
add_arg(al, "-O");
add_arg(al, "max_heap_table_size=1M");
// $EXTRA_MASTER_OPT
if (master_opt[0] != NULL)
{
char *p;
p = (char *)strtok(master_opt, " \t");
while(p)
{
add_arg(al, "%s", p);
p = (char *)strtok(NULL, " \t");
}
}
// remove the pid file if it exists
remove(master_pid);
// spawn
if ((err = spawn(mysqld_file, al, FALSE, NULL, master_out, master_err)) == 0)
{
sleep_until_file_exists(master_pid);
if ((err = wait_for_server_start(bin_dir, user, password, master_port)) == 0)
{
master_running = TRUE;
}
else
{
log_error("The master server went down early.");
}
}
else
{
log_error("Unable to start master server.");
}
// free_args
free_args(al);
}
/******************************************************************************
start_slave()
Start the slave server.
******************************************************************************/
void start_slave()
{
arg_list al;
int err, i;
char slave_out[PATH_MAX];
char slave_err[PATH_MAX];
char temp[PATH_MAX];
// skip?
if (skip_slave) return;
// remove stale binary logs
removef("%s/*-bin.*", slave_dir);
// remove stale binary logs
removef("%s/*.index", slave_dir);
// remove master.info file
removef("%s/master.info", slave_dir);
// remove relay files
removef("%s/var/log/*relay*", mysql_test_dir);
// remove relay-log.info file
removef("%s/relay-log.info", slave_dir);
// init script
if (slave_init_script[0] != NULL)
{
// run_init_script(slave_init_script);
// TODO: use the scripts
if (strindex(slave_init_script, "rpl000016-slave.sh") != NULL)
{
// create empty master.info file
snprintf(temp, PATH_MAX, "%s/master.info", slave_dir);
close(open(temp, O_WRONLY | O_CREAT));
}
else if (strindex(slave_init_script, "rpl000017-slave.sh") != NULL)
{
FILE *fp;
// create a master.info file
snprintf(temp, PATH_MAX, "%s/master.info", slave_dir);
fp = fopen(temp, "wb+");
fputs("master-bin.001\n", fp);
fputs("4\n", fp);
fputs("127.0.0.1\n", fp);
fputs("replicate\n", fp);
fputs("aaaaaaaaaaaaaaabthispartofthepasswordisnotused\n", fp);
fputs("9306\n", fp);
fputs("1\n", fp);
fputs("0\n", fp);
fclose(fp);
}
else if (strindex(slave_init_script, "rpl_rotate_logs-slave.sh") != NULL)
{
// create empty master.info file
snprintf(temp, PATH_MAX, "%s/master.info", slave_dir);
close(open(temp, O_WRONLY | O_CREAT));
}
}
// redirection files
snprintf(slave_out, PATH_MAX, "%s/var/run/slave%u.out",
mysql_test_dir, restarts);
snprintf(slave_err, PATH_MAX, "%s/var/run/slave%u.err",
mysql_test_dir, restarts);
// args
init_args(al);
add_arg(al, "%s", mysqld_file);
add_arg(al, "--no-defaults");
add_arg(al, "--log-bin=slave-bin");
add_arg(al, "--relay_log=slave-relay-bin");
add_arg(al, "--basedir=%s", base_dir);
add_arg(al, "--port=%u", slave_port);
add_arg(al, "--datadir=%s", slave_dir);
add_arg(al, "--pid-file=%s", slave_pid);
add_arg(al, "--character-sets-dir=%s", char_dir);
add_arg(al, "--core");
add_arg(al, "--tmpdir=%s", mysql_tmp_dir);
add_arg(al, "--language=%s", lang_dir);
add_arg(al, "--exit-info=256");
add_arg(al, "--log-slave-updates");
add_arg(al, "--init-rpl-role=slave");
add_arg(al, "--skip-innodb");
add_arg(al, "--skip-slave-start");
add_arg(al, "--slave-load-tmpdir=../../var/tmp");
add_arg(al, "--report-user=%s", user);
add_arg(al, "--report-host=127.0.0.1");
add_arg(al, "--report-port=%u", slave_port);
add_arg(al, "--master-retry-count=10");
add_arg(al, "-O");
add_arg(al, "slave_net_timeout=10");
// slave master info
if (slave_master_info[0] != NULL)
{
char *p;
p = (char *)strtok(slave_master_info, " \t");
while(p)
{
add_arg(al, "%s", p);
p = (char *)strtok(NULL, " \t");
}
}
else
{
add_arg(al, "--master-user=%s", user);
add_arg(al, "--master-password=%s", password);
add_arg(al, "--master-host=127.0.0.1");
add_arg(al, "--master-port=%u", master_port);
add_arg(al, "--master-connect-retry=1");
add_arg(al, "--server-id=2");
add_arg(al, "--rpl-recovery-rank=2");
}
// small server
add_arg(al, "-O");
add_arg(al, "key_buffer_size=1M");
add_arg(al, "-O");
add_arg(al, "sort_buffer=256K");
add_arg(al, "-O");
add_arg(al, "max_heap_table_size=1M");
// opt args
if (slave_opt[0] != NULL)
{
char *p;
p = (char *)strtok(slave_opt, " \t");
while(p)
{
add_arg(al, "%s", p);
p = (char *)strtok(NULL, " \t");
}
}
// remove the pid file if it exists
remove(slave_pid);
// spawn
if ((err = spawn(mysqld_file, al, FALSE, NULL, slave_out, slave_err)) == 0)
{
sleep_until_file_exists(slave_pid);
if ((err = wait_for_server_start(bin_dir, user, password, slave_port)) == 0)
{
slave_running = TRUE;
}
else
{
log_error("The slave server went down early.");
}
}
else
{
log_error("Unable to start slave server.");
}
// free args
free_args(al);
}
/******************************************************************************
mysql_start()
Start the mysql servers.
******************************************************************************/
void mysql_start()
{
start_master();
start_slave();
// activate the test screen
ActivateScreen(getscreenhandle());
}
/******************************************************************************
stop_slave()
Stop the slave server.
******************************************************************************/
void stop_slave()
{
int err;
// running?
if (!slave_running) return;
// stop
if ((err = stop_server(bin_dir, user, password, slave_port, slave_pid)) == 0)
{
slave_running = FALSE;
}
else
{
log_error("Unable to stop slave server.");
}
}
/******************************************************************************
stop_master()
Stop the master server.
******************************************************************************/
void stop_master()
{
int err;
// running?
if (!master_running) return;
if ((err = stop_server(bin_dir, user, password, master_port, master_pid)) == 0)
{
master_running = FALSE;
}
else
{
log_error("Unable to stop master server.");
}
}
/******************************************************************************
mysql_stop()
Stop the mysql servers.
******************************************************************************/
void mysql_stop()
{
stop_master();
stop_slave();
// activate the test screen
ActivateScreen(getscreenhandle());
}
/******************************************************************************
mysql_restart()
Restart the mysql servers.
******************************************************************************/
void mysql_restart()
{
log_info("Restarting the MySQL server(s): %u", ++restarts);
mysql_stop();
mysql_start();
}
/******************************************************************************
read_option()
Read the option file.
******************************************************************************/
int read_option(char *opt_file, char *opt)
{
int fd, err;
int result;
char *p;
char buf[PATH_MAX];
// copy current option
strncpy(buf, opt, PATH_MAX);
// open options file
fd = open(opt_file, O_RDONLY);
err = read(fd, opt, PATH_MAX);
close(fd);
if (err > 0)
{
// terminate string
if ((p = strchr(opt, '\n')) != NULL)
{
*p = NULL;
// check for a '\r'
if ((p = strchr(opt, '\r')) != NULL)
{
*p = NULL;
}
}
else
{
opt[err] = NULL;
}
// check for $MYSQL_TEST_DIR
if ((p = strstr(opt, "$MYSQL_TEST_DIR")) != NULL)
{
char temp[PATH_MAX];
*p = NULL;
strcpy(temp, p + strlen("$MYSQL_TEST_DIR"));
strcat(opt, mysql_test_dir);
strcat(opt, temp);
}
}
else
{
// clear option
*opt = NULL;
}
// compare current option with previous
return strcmp(opt, buf);
}
/******************************************************************************
run_test()
Run the given test case.
******************************************************************************/
void run_test(char *test)
{
char temp[PATH_MAX];
char *rstr;
double elapsed = 0;
int skip = FALSE;
int restart = FALSE;
int flag = FALSE;
struct stat info;
// single test?
if (!single_test)
{
// skip tests in the skip list
snprintf(temp, PATH_MAX, " %s ", test);
skip = (strindex(skip_test, temp) != NULL);
}
// skip test?
if (!skip)
{
char test_file[PATH_MAX];
char master_opt_file[PATH_MAX];
char slave_opt_file[PATH_MAX];
char slave_master_info_file[PATH_MAX];
char result_file[PATH_MAX];
char reject_file[PATH_MAX];
char out_file[PATH_MAX];
char err_file[PATH_MAX];
int err;
arg_list al;
NXTime_t start, stop;
// skip slave?
flag = skip_slave;
skip_slave = (strncmp(test, "rpl", 3) != 0);
if (flag != skip_slave) restart = TRUE;
// create files
snprintf(master_opt_file, PATH_MAX, "%s/%s-master.opt", test_dir, test);
snprintf(slave_opt_file, PATH_MAX, "%s/%s-slave.opt", test_dir, test);
snprintf(slave_master_info_file, PATH_MAX, "%s/%s-slave-master-info.opt", test_dir, test);
snprintf(reject_file, PATH_MAX, "%s/%s%s", result_dir, test, REJECT_SUFFIX);
snprintf(out_file, PATH_MAX, "%s/%s%s", result_dir, test, OUT_SUFFIX);
snprintf(err_file, PATH_MAX, "%s/%s%s", result_dir, test, ERR_SUFFIX);
// netware specific files
snprintf(test_file, PATH_MAX, "%s/%s%s", test_dir, test, NW_TEST_SUFFIX);
if (stat(test_file, &info))
{
snprintf(test_file, PATH_MAX, "%s/%s%s", test_dir, test, TEST_SUFFIX);
}
snprintf(result_file, PATH_MAX, "%s/%s%s", result_dir, test, NW_RESULT_SUFFIX);
if (stat(result_file, &info))
{
snprintf(result_file, PATH_MAX, "%s/%s%s", result_dir, test, RESULT_SUFFIX);
}
// init scripts
snprintf(master_init_script, PATH_MAX, "%s/%s-master.sh", test_dir, test);
if (stat(master_init_script, &info))
master_init_script[0] = NULL;
else
restart = TRUE;
snprintf(slave_init_script, PATH_MAX, "%s/%s-slave.sh", test_dir, test);
if (stat(slave_init_script, &info))
slave_init_script[0] = NULL;
else
restart = TRUE;
// read options
if (read_option(master_opt_file, master_opt)) restart = TRUE;
if (read_option(slave_opt_file, slave_opt)) restart = TRUE;
if (read_option(slave_master_info_file, slave_master_info)) restart = TRUE;
// cleanup previous run
remove(reject_file);
remove(out_file);
remove(err_file);
// start or restart?
if (!master_running) mysql_start();
else if (restart) mysql_restart();
// let the system stabalize
sleep(1);
// show test
log("%-46s ", test);
// args
init_args(al);
add_arg(al, "%s", mysqltest_file);
add_arg(al, "--no-defaults");
add_arg(al, "--port=%u", master_port);
add_arg(al, "--database=%s", db);
add_arg(al, "--user=%s", user);
add_arg(al, "--password=%s", password);
add_arg(al, "--silent");
add_arg(al, "--basedir=%s/", mysql_test_dir);
add_arg(al, "--host=127.0.0.1");
add_arg(al, "-v");
add_arg(al, "-R");
add_arg(al, "%s", result_file);
// start timer
NXGetTime(NX_SINCE_BOOT, NX_USECONDS, &start);
// spawn
err = spawn(mysqltest_file, al, TRUE, test_file, out_file, err_file);
// stop timer
NXGetTime(NX_SINCE_BOOT, NX_USECONDS, &stop);
// calculate
elapsed = ((double)(stop - start)) / NX_USECONDS;
total_time += elapsed;
// free args
free_args(al);
if (err == 0)
{
// pass
rstr = TEST_PASS;
++total_pass;
// increment total
++total_test;
}
else if (err == 2)
{
// skip
rstr = TEST_SKIP;
++total_skip;
}
else if (err == 1)
{
// fail
rstr = TEST_FAIL;
++total_fail;
// increment total
++total_test;
}
else
{
rstr = TEST_BAD;
}
}
else // early skips
{
// show test
log("%-46s ", test);
// skip
rstr = TEST_SKIP;
++total_skip;
}
// result
log("%10.06f %-14s\n", elapsed, rstr);
}
/******************************************************************************
vlog()
Log the message.
******************************************************************************/
void vlog(char *format, va_list ap)
{
vfprintf(stdout, format, ap);
fflush(stdout);
if (log_fd)
{
vfprintf(log_fd, format, ap);
fflush(log_fd);
}
}
/******************************************************************************
log()
Log the message.
******************************************************************************/
void log(char *format, ...)
{
va_list ap;
va_start(ap, format);
vlog(format, ap);
va_end(ap);
}
/******************************************************************************
log_info()
Log the given information.
******************************************************************************/
void log_info(char *format, ...)
{
va_list ap;
va_start(ap, format);
log("-- INFO : ");
vlog(format, ap);
log("\n");
va_end(ap);
}
/******************************************************************************
log_error()
Log the given error.
******************************************************************************/
void log_error(char *format, ...)
{
va_list ap;
va_start(ap, format);
log("-- ERROR: ");
vlog(format, ap);
log("\n");
va_end(ap);
}
/******************************************************************************
log_errno()
Log the given error and errno.
******************************************************************************/
void log_errno(char *format, ...)
{
va_list ap;
va_start(ap, format);
log("-- ERROR: (%003u) ", errno);
vlog(format, ap);
log("\n");
va_end(ap);
}
/******************************************************************************
die()
Exit the application.
******************************************************************************/
void die(char *msg)
{
log_error(msg);
pressanykey();
exit(-1);
}
/******************************************************************************
setup()
Setup the mysql test enviornment.
******************************************************************************/
void setup(char *file)
{
char temp[PATH_MAX];
char *p;
// set the timezone for the timestamp test
setenv("TZ", "GMT-3", TRUE);
// find base dir
strcpy(temp, strlwr(file));
while((p = strchr(temp, '\\')) != NULL) *p = '/';
if ((p = strindex(temp, "/mysql-test/")) != NULL)
{
*p = NULL;
strcpy(base_dir, temp);
}
// setup paths
snprintf(bin_dir, PATH_MAX, "%s/bin", base_dir);
snprintf(mysql_test_dir, PATH_MAX, "%s/mysql-test", base_dir);
snprintf(test_dir, PATH_MAX, "%s/t", mysql_test_dir);
snprintf(mysql_tmp_dir, PATH_MAX, "%s/var/tmp", mysql_test_dir);
snprintf(result_dir, PATH_MAX, "%s/r", mysql_test_dir);
snprintf(master_dir, PATH_MAX, "%s/var/master-data", mysql_test_dir);
snprintf(slave_dir, PATH_MAX, "%s/var/slave-data", mysql_test_dir);
snprintf(lang_dir, PATH_MAX, "%s/share/english", base_dir);
snprintf(char_dir, PATH_MAX, "%s/share/charsets", base_dir);
// setup files
snprintf(mysqld_file, PATH_MAX, "%s/mysqld", bin_dir);
snprintf(mysqltest_file, PATH_MAX, "%s/mysqltest", bin_dir);
snprintf(mysqladmin_file, PATH_MAX, "%s/mysqladmin", bin_dir);
snprintf(master_pid, PATH_MAX, "%s/var/run/master.pid", mysql_test_dir);
snprintf(slave_pid, PATH_MAX, "%s/var/run/slave.pid", mysql_test_dir);
// create log file
snprintf(temp, PATH_MAX, "%s/mysql-test-run.log", mysql_test_dir);
if ((log_fd = fopen(temp, "w+")) == NULL)
{
log_errno("Unable to create log file.");
}
// prepare skip test list
while((p = strchr(skip_test, ',')) != NULL) *p = ' ';
strcpy(temp, strlwr(skip_test));
snprintf(skip_test, PATH_MAX, " %s ", temp);
// enviornment
setenv("MYSQL_TEST_DIR", mysql_test_dir, 1);
// install test databases
mysql_install_db();
}
/******************************************************************************
main()
******************************************************************************/
int main(int argc, char **argv)
{
log("Initializing Tests...\n");
// setup
setup(argv[0]);
log("Starting Tests...\n");
log("\n");
log(HEADER);
log(DASH);
if (argc > 1)
{
int i;
// single test
single_test = TRUE;
for (i = 1; i < argc; i++)
{
// run given test
run_test(argv[i]);
}
}
else
{
// run all tests
DIR *dir = opendir(test_dir);
DIR *entry;
char test[NAME_MAX];
char *p;
// single test
single_test = FALSE;
if (dir == NULL)
{
die("Unable to open tests directory.");
}
while((entry = readdir(dir)) != NULL)
{
if (!S_ISDIR(entry->d_type))
{
strcpy(test, strlwr(entry->d_name));
// find the test suffix
if ((p = strindex(test, TEST_SUFFIX)) != NULL)
{
// null terminate at the suffix
*p = '\0';
// run test
run_test(test);
}
}
}
closedir(dir);
}
log(DASH);
log("\n");
log("Ending Tests...\n");
// stop server
mysql_stop();
// report stats
report_stats();
// close log
if (log_fd) fclose(log_fd);
// keep results up
pressanykey();
return 0;
}
/*
Copyright (c) 2003 Novell, Inc. All Rights Reserved.
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
*/
#include <stdlib.h>
#include <stdio.h>
#include <netdb.h>
#include <sys/stat.h>
#include <monitor.h>
#include <strings.h>
#include <getopt.h>
#include <screen.h>
#include <dirent.h>
#include "my_config.h"
#include "my_manage.h"
/******************************************************************************
global variables
******************************************************************************/
char autoclose;
char basedir[PATH_MAX];
char datadir[PATH_MAX];
char pid_file[PATH_MAX];
char address[PATH_MAX];
char port[PATH_MAX];
char err_log[PATH_MAX];
char safe_log[PATH_MAX];
char mysqld[PATH_MAX];
char hostname[PATH_MAX];
char default_option[PATH_MAX];
FILE *log_fd = NULL;
/******************************************************************************
prototypes
******************************************************************************/
void vlog(char *, va_list);
void log(char *, ...);
void start_defaults(int, char*[]);
void finish_defaults();
void read_defaults(arg_list);
void parse_args(int, char*[]);
void get_options(int, char*[]);
void check_data_vol();
void check_setup();
void check_tables();
void mysql_start(int, char*[]);
/******************************************************************************
functions
******************************************************************************/
/******************************************************************************
vlog()
Log the message.
******************************************************************************/
void vlog(char *format, va_list ap)
{
vfprintf(stdout, format, ap);
fflush(stdout);
if (log_fd)
{
vfprintf(log_fd, format, ap);
fflush(log_fd);
}
}
/******************************************************************************
log()
Log the message.
******************************************************************************/
void log(char *format, ...)
{
va_list ap;
va_start(ap, format);
vlog(format, ap);
va_end(ap);
}
/******************************************************************************
start_defaults()
Start setting the defaults.
******************************************************************************/
void start_defaults(int argc, char *argv[])
{
struct stat buf;
int i;
// default options
static char *default_options[] =
{
"--no-defaults",
"--defaults-file=",
"--defaults-extra-file=",
NULL
};
// autoclose
autoclose = FALSE;
// basedir
get_basedir(argv[0], basedir);
// hostname
if (gethostname(hostname,PATH_MAX) < 0)
{
// default
strcpy(hostname,"mysql");
}
// address
snprintf(address, PATH_MAX, "0.0.0.0");
// port
snprintf(port, PATH_MAX, "3306");
// default option
default_option[0] = NULL;
for (i=0; (argc > 1) && default_options[i]; i++)
{
if(!strnicmp(argv[1], default_options[i], strlen(default_options[i])))
{
strncpy(default_option, argv[1], PATH_MAX);
break;
}
}
// set after basedir is established
datadir[0] = NULL;
pid_file[0] = NULL;
err_log[0] = NULL;
safe_log[0] = NULL;
mysqld[0] = NULL;
}
/******************************************************************************
finish_defaults()
Finish settig the defaults.
******************************************************************************/
void finish_defaults()
{
struct stat buf;
int i;
// datadir
if (!datadir[0]) snprintf(datadir, PATH_MAX, "%s/data", basedir);
// pid-file
if (!pid_file[0]) snprintf(pid_file, PATH_MAX, "%s/%s.pid", datadir, hostname);
// err-log
if (!err_log[0]) snprintf(err_log, PATH_MAX, "%s/%s.err", datadir, hostname);
// safe-log
if (!safe_log[0]) snprintf(safe_log, PATH_MAX, "%s/%s.log", datadir, hostname);
// mysqld
if (!mysqld[0]) snprintf(mysqld, PATH_MAX, "%s/bin/mysqld-max", basedir);
if (stat(mysqld, &buf))
{
snprintf(mysqld, PATH_MAX, "%s/bin/mysqld", basedir);
}
}
/******************************************************************************
read_defaults()
Read the defaults.
******************************************************************************/
void read_defaults(arg_list pal)
{
arg_list al;
char defaults_file[PATH_MAX];
char mydefaults[PATH_MAX];
char line[PATH_MAX];
FILE *fp;
// defaults output file
snprintf(defaults_file, PATH_MAX, "%s/bin/defaults.out", basedir);
remove(defaults_file);
// mysqladmin file
snprintf(mydefaults, PATH_MAX, "%s/bin/my_print_defaults", basedir);
// args
init_args(al);
add_arg(al, mydefaults);
if (default_option[0]) add_arg(al, default_option);
add_arg(al, "mysqld");
add_arg(al, "server");
add_arg(al, "mysqld_safe");
add_arg(al, "safe_mysqld");
spawn(mydefaults, al, TRUE, NULL, defaults_file, NULL);
free_args(al);
// gather defaults
if((fp = fopen(defaults_file, "r")) != NULL)
{
while(fgets(line, PATH_MAX, fp))
{
char *p;
// remove end-of-line character
if ((p = strrchr(line, '\n')) != NULL) *p = '\0';
// add the option as an argument
add_arg(pal, line);
}
fclose(fp);
}
// remove file
remove(defaults_file);
}
/******************************************************************************
parse_args()
Get the options.
******************************************************************************/
void parse_args(int argc, char *argv[])
{
int index = 0;
int c;
// parse options
enum opts
{
OPT_BASEDIR = 0xFF,
OPT_DATADIR,
OPT_PID_FILE,
OPT_BIND_ADDRESS,
OPT_PORT,
OPT_ERR_LOG,
OPT_SAFE_LOG,
OPT_MYSQLD
};
static struct option options[] =
{
{"autoclose", no_argument, &autoclose, TRUE},
{"basedir", required_argument, 0, OPT_BASEDIR},
{"datadir", required_argument, 0, OPT_DATADIR},
{"pid-file", required_argument, 0, OPT_PID_FILE},
{"bind-address", required_argument, 0, OPT_BIND_ADDRESS},
{"port", required_argument, 0, OPT_PORT},
{"err-log", required_argument, 0, OPT_ERR_LOG},
{"safe-log", required_argument, 0, OPT_SAFE_LOG},
{"mysqld", required_argument, 0, OPT_MYSQLD},
{0, 0, 0, 0}
};
// we have to reset getopt_long because we use it multiple times
optind = 1;
// turn off error reporting
opterr = 0;
while ((c = getopt_long(argc, argv, "b:h:P:", options, &index)) >= 0)
{
switch (c)
{
case OPT_BASEDIR:
case 'b':
strcpy(basedir, optarg);
break;
case OPT_DATADIR:
case 'h':
strcpy(datadir, optarg);
break;
case OPT_PID_FILE:
strcpy(pid_file, optarg);
break;
case OPT_BIND_ADDRESS:
strcpy(address, optarg);
break;
case OPT_PORT:
case 'P':
strcpy(port, optarg);
break;
case OPT_ERR_LOG:
strcpy(err_log, optarg);
break;
case OPT_SAFE_LOG:
strcpy(safe_log, optarg);
break;
case OPT_MYSQLD:
strcpy(mysqld, optarg);
break;
default:
// ignore
break;
}
}
}
/******************************************************************************
get_options()
Get the options.
******************************************************************************/
void get_options(int argc, char *argv[])
{
arg_list al;
// start defaults
start_defaults(argc, argv);
// default file arguments
init_args(al);
add_arg(al, "dummy");
read_defaults(al);
parse_args(al->argc, al->argv);
free_args(al);
// command-line arguments
parse_args(argc, argv);
// finish defaults
finish_defaults();
}
/******************************************************************************
check_data_vol()
Check the database volume.
******************************************************************************/
void check_data_vol()
{
// warn if the data is on a Traditional volume
struct volume_info vol;
char buff[PATH_MAX];
char *p;
// clear struct
memset(&vol, 0, sizeof(vol));
// find volume name
strcpy(buff, datadir);
if (p = strchr(buff, ':'))
{
// terminate after volume name
*p = 0;
}
else
{
// assume SYS volume
strcpy(buff, "SYS");
}
// retrieve information
netware_vol_info_from_name(&vol, buff);
if ((vol.flags & VOL_NSS_PRESENT) == 0)
{
log("Error: The data directory is not on an NSS volume!\n\n");
exit(-1);
}
}
/******************************************************************************
check_setup()
Check the current setup.
******************************************************************************/
void check_setup()
{
struct stat info;
char temp[PATH_MAX];
// remove any current pid_file
if (!stat(pid_file, &info) && (remove(pid_file) < 0))
{
log("ERROR: Unable to remove current pid file!\n\n");
exit(-1);
}
// check the data volume
check_data_vol();
// check for a database
snprintf(temp, PATH_MAX, "%s/mysql/host.frm", datadir);
if (stat(temp, &info))
{
log("ERROR: No database found in the data directory!\n\n");
exit(-1);
}
}
/******************************************************************************
check_tables()
Check the database tables.
******************************************************************************/
void check_tables()
{
arg_list al;
char mycheck[PATH_MAX];
char table[PATH_MAX];
char db[PATH_MAX];
DIR *datadir_entry, *db_entry, *table_entry;
// status
log("checking tables...\n");
// list databases
if ((datadir_entry = opendir(datadir)) == NULL)
{
return;
}
while((db_entry = readdir(datadir_entry)) != NULL)
{
if (db_entry->d_name[0] == '.')
{
// Skip
}
else if (S_ISDIR(db_entry->d_type))
{
// create long db name
snprintf(db, PATH_MAX, "%s/%s", datadir, db_entry->d_name);
// list tables
if ((db_entry = opendir(db)) == NULL)
{
continue;
}
while((table_entry = readdir(db_entry)) != NULL)
{
// create long table name
snprintf(table, PATH_MAX, "%s/%s", db, strlwr(table_entry->d_name));
if (strindex(table, ".myi"))
{
// ** myisamchk
// mysqladmin file
snprintf(mycheck, PATH_MAX, "%s/bin/myisamchk", basedir);
// args
init_args(al);
add_arg(al, mycheck);
add_arg(al, "--silent");
add_arg(al, "--force");
add_arg(al, "--fast");
add_arg(al, "--medium-check");
add_arg(al, "-O");
add_arg(al, "key_buffer=64M");
add_arg(al, "-O");
add_arg(al, "sort_buffer=64M");
add_arg(al, table);
spawn(mycheck, al, TRUE, NULL, NULL, NULL);
free_args(al);
}
else if (strindex(table, ".ism"))
{
// ** isamchk
// mysqladmin file
snprintf(mycheck, PATH_MAX, "%s/bin/isamchk", basedir);
// args
init_args(al);
add_arg(al, mycheck);
add_arg(al, "--silent");
add_arg(al, "--force");
add_arg(al, "-O");
add_arg(al, "sort_buffer=64M");
add_arg(al, table);
spawn(mycheck, al, TRUE, NULL, NULL, NULL);
free_args(al);
}
}
}
}
}
/******************************************************************************
mysql_start()
Start the mysql server.
******************************************************************************/
void mysql_start(int argc, char *argv[])
{
arg_list al;
int i, j, err;
struct stat info;
time_t cal;
struct tm lt;
char stamp[PATH_MAX];
char skip;
// private options
static char *private_options[] =
{
"--autoclose",
"--err-log=",
"--mysqld=",
NULL
};
// args
init_args(al);
add_arg(al, "%s", mysqld);
// parent args
for(i = 1; i < argc; i++)
{
skip = FALSE;
// skip private arguments
for (j=0; private_options[j]; j++)
{
if(!strnicmp(argv[i], private_options[j], strlen(private_options[j])))
{
skip = TRUE;
break;
}
}
if (!skip) add_arg(al, "%s", argv[i]);
}
// spawn
do
{
// check the database tables
check_tables();
// status
time(&cal);
localtime_r(&cal, &lt);
strftime(stamp, PATH_MAX, "%d %b %Y %H:%M:%S", &lt);
log("mysql started : %s\n", stamp);
// spawn mysqld
spawn(mysqld, al, TRUE, NULL, NULL, err_log);
}
while (!stat(pid_file, &info));
// status
time(&cal);
localtime_r(&cal, &lt);
strftime(stamp, PATH_MAX, "%d %b %Y %H:%M:%S", &lt);
log("mysql stopped : %s\n\n", stamp);
// free args
free_args(al);
}
/******************************************************************************
main()
******************************************************************************/
int main(int argc, char **argv)
{
char temp[PATH_MAX];
// get the options
get_options(argc, argv);
// keep the screen up
if (!autoclose) setscreenmode(SCR_NO_MODE);
// create log file
log_fd = fopen(safe_log, "w+");
// header
log("MySQL Server %s, for %s (%s)\n\n", VERSION, SYSTEM_TYPE, MACHINE_TYPE);
// status
log("address : %s\n", address);
log("port : %s\n", port);
log("daemon : %s\n", mysqld);
log("base directory : %s\n", basedir);
log("data directory : %s\n", datadir);
log("pid file : %s\n", pid_file);
log("error file : %s\n", err_log);
log("log file : %s\n", safe_log);
log("\n");
// check setup
check_setup();
// start the MySQL server
mysql_start(argc, argv);
// close log file
if (log_fd) fclose(log_fd);
return 0;
}
USE mysql;
CREATE TABLE db (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL, References_priv enum('N','Y') DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db,User), KEY User (User)) comment='Database privileges';
CREATE TABLE host (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL, References_priv enum('N','Y') DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db)) comment='Host privileges; Merged with database privileges';
CREATE TABLE user (Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Password char(16) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL, Reload_priv enum('N','Y') DEFAULT 'N' NOT NULL, Shutdown_priv enum('N','Y') DEFAULT 'N' NOT NULL, Process_priv enum('N','Y') DEFAULT 'N' NOT NULL, File_priv enum('N','Y') DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL, References_priv enum('N','Y') DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL, Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL, Super_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL, Repl_slave_priv enum('N','Y') DEFAULT 'N' NOT NULL, Repl_client_priv enum('N','Y') DEFAULT 'N' NOT NULL, ssl_type enum('','ANY','X509', 'SPECIFIED') DEFAULT '' NOT NULL, ssl_cipher BLOB NOT NULL, x509_issuer BLOB NOT NULL, x509_subject BLOB NOT NULL, max_questions int(11) unsigned DEFAULT 0 NOT NULL, max_updates int(11) unsigned DEFAULT 0 NOT NULL, max_connections int(11) unsigned DEFAULT 0 NOT NULL, PRIMARY KEY Host (Host,User)) comment='Users and global privileges';
INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
INSERT INTO user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
INSERT INTO user VALUES ('localhost','','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
CREATE TABLE func (name char(64) binary DEFAULT '' NOT NULL, ret tinyint(1) DEFAULT '0' NOT NULL, dl char(128) DEFAULT '' NOT NULL, type enum ('function','aggregate') NOT NULL, PRIMARY KEY (name)) comment='User defined functions';
CREATE TABLE tables_priv (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(60) binary DEFAULT '' NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp(14), Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') DEFAULT '' NOT NULL, Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name), KEY Grantor (Grantor)) comment='Table privileges';
CREATE TABLE columns_priv (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Column_name char(64) binary DEFAULT '' NOT NULL, Timestamp timestamp(14), Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name)) comment='Column privileges';
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment