diff options
-rw-r--r-- | .bzrignore | 1 | ||||
-rw-r--r-- | client/Makefile.am | 4 | ||||
-rw-r--r-- | client/mysqlmanagerc.c | 189 | ||||
-rw-r--r-- | include/Makefile.am | 2 | ||||
-rw-r--r-- | include/md5.h (renamed from sql/md5.h) | 0 | ||||
-rw-r--r-- | include/mysql.h | 37 | ||||
-rw-r--r-- | include/mysql_com.h | 2 | ||||
-rw-r--r-- | libmysql/Makefile.shared | 4 | ||||
-rw-r--r-- | libmysql/libmysql.c | 8 | ||||
-rw-r--r-- | mysys/Makefile.am | 2 | ||||
-rw-r--r-- | mysys/md5.c (renamed from sql/md5.c) | 0 | ||||
-rw-r--r-- | sql/Makefile.am | 4 | ||||
-rw-r--r-- | sql/handler.cc | 2 | ||||
-rw-r--r-- | tools/managertest1.nc | 3 | ||||
-rw-r--r-- | tools/mysqlmanager-sample.pwd | 1 | ||||
-rw-r--r-- | tools/mysqlmanager.c | 124 | ||||
-rwxr-xr-x | vio/test-ssl | bin | 42160 -> 42160 bytes |
17 files changed, 325 insertions, 58 deletions
diff --git a/.bzrignore b/.bzrignore index 4011bf5ff5e..235fd1d5491 100644 --- a/.bzrignore +++ b/.bzrignore @@ -400,3 +400,4 @@ vio/test-sslclient vio/test-sslserver vio/viotest-ssl tools/mysqlmanager +client/mysqlmanagerc diff --git a/client/Makefile.am b/client/Makefile.am index e39c663de15..365d013f074 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -23,7 +23,7 @@ noinst_HEADERS = client_priv.h LIBS = @CLIENT_LIBS@ LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysql/libmysqlclient.la bin_PROGRAMS = mysql mysqladmin mysqlcheck mysqlshow \ - mysqldump mysqlimport mysqltest mysqlbinlog + mysqldump mysqlimport mysqltest mysqlbinlog mysqlmanagerc noinst_PROGRAMS = insert_test select_test thread_test noinst_HEADERS = sql_string.h completion_hash.h my_readline.h mysql_SOURCES = mysql.cc readline.cc sql_string.cc completion_hash.cc @@ -40,6 +40,8 @@ mysqltest_SOURCES= mysqltest.c mysqltest_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) mysqlbinlog_SOURCES = mysqlbinlog.cc mysqlbinlog_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) +mysqlmanagerc_SOURCES = mysqlmanagerc.c +mysqlmanagerc_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) sql_src=log_event.h log_event.cc # Fix for mit-threads diff --git a/client/mysqlmanagerc.c b/client/mysqlmanagerc.c new file mode 100644 index 00000000000..c4426c36426 --- /dev/null +++ b/client/mysqlmanagerc.c @@ -0,0 +1,189 @@ +/* Copyright (C) 2000 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 */ + +#define MANAGER_CLIENT_VERSION "1.0" + +#include <global.h> +#include <my_sys.h> +#include <m_string.h> +#include <mysql.h> +#include <mysql_version.h> +#include <m_ctype.h> +#ifdef OS2 +#include <config-os2.h> +#else +#include <my_config.h> +#endif +#include <my_dir.h> +#include <hash.h> +#include <mysqld_error.h> +#include <stdio.h> +#include <stdlib.h> +#include <getopt.h> +#include <stdarg.h> +#include <sys/stat.h> +#include <unistd.h> +#include <errno.h> +#include <violite.h> + +#ifndef MYSQL_MANAGER_PORT +#define MYSQL_MANAGER_PORT 23546 +#endif + +static void die(const char* fmt, ...); + +const char* user="root",*host="localhost"; +char* pass=0; +int quiet=0; +uint port=MYSQL_MANAGER_PORT; +static const char *load_default_groups[]= { "mysqlmanagerc",0 }; +char** default_argv; +MYSQL_MANAGER *manager; +FILE* fp, *fp_out; + +struct option long_options[] = +{ + {"host",required_argument,0,'h'}, + {"user",required_argument,0,'u'}, + {"password",optional_argument,0,'p',}, + {"port",required_argument,0,'P'}, + {"help",no_argument,0,'?'}, + {"version",no_argument,0,'V'}, + {"quiet",no_argument,0,'q'}, + {0,0,0,0} +}; + +static void die(const char* fmt, ...) +{ + va_list args; + DBUG_ENTER("die"); + va_start(args, fmt); + if (fmt) + { + fprintf(stderr, "%s: ", my_progname); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + fflush(stderr); + } + va_end(args); + exit(1); +} + +static void print_version(void) +{ + printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname, + MANAGER_CLIENT_VERSION, + MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE); +} + +void usage() +{ + print_version(); + printf("MySQL AB, by Sasha, Matt & Monty\n"); + printf("This software comes with ABSOLUTELY NO WARRANTY\n\n"); + printf("Runs a test against the mysql server and compares output with a results file.\n\n"); + printf("Usage: %s [OPTIONS] < command_file\n", my_progname); + printf("\n\ + -?, --help Display this help and exit.\n"); + printf("\ + -h, --host=... Connect to host.\n\ + -u, --user=... User for login.\n\ + -p[password], --password[=...]\n\ + Password to use when connecting to server.\n\ + -P, --port=... Port number to use for connection.\n\ + -q, --quiet, --silent Suppress all normal output.\n\ + -V, --version Output version information and exit.\n\ + --no-defaults Don't read default options from any options file.\n\n"); +} +int parse_args(int argc, char **argv) +{ + int c, option_index = 0; + my_bool tty_password=0; + + load_defaults("my",load_default_groups,&argc,&argv); + default_argv= argv; + + while ((c = getopt_long(argc, argv, "h:p::u:P:?Vq", + long_options, &option_index)) != EOF) + { + switch (c) + { + case 'h': + host=optarg; + break; + case 'u': + user=optarg; + break; + case 'p': + if (optarg) + { + my_free(pass,MYF(MY_ALLOW_ZERO_PTR)); + pass=my_strdup(optarg,MYF(MY_FAE)); + while (*optarg) *optarg++= 'x'; /* Destroy argument */ + } + else + tty_password=1; + break; + case 'P': + port=atoi(optarg); + break; + case 'q': + quiet=1; + break; + case 'V': + print_version(); + exit(0); + case '?': + usage(); + exit(1); /* Unknown option */ + default: + usage(); + exit(1); + } + } + return 0; +} +int main(int argc, char** argv) +{ + MY_INIT(argv[0]); + fp=stdin; + fp_out=stdout; + parse_args(argc,argv); + if (!(manager=mysql_manager_init(0))) + die("Failed in mysql_manager_init()"); + if (!mysql_manager_connect(manager,host,user,pass,port)) + die("Could not connect to MySQL manager: %s(%d)",manager->last_error, + manager->last_errno); + for (;!feof(fp);) + { + char buf[1024]; + if (!fgets(buf,sizeof(buf),fp)) + break; + if (mysql_manager_command(manager,buf,strlen(buf))) + die("Error in command: %s(%d)",manager->last_error,manager->last_errno); + while (!manager->eof) + { + if (mysql_manager_fetch_line(manager,buf,sizeof(buf))) + die("Error fetching result line: %s(%d)", manager->last_error, + manager->last_errno); + fprintf(fp_out,"%s\n",buf); + } + } + mysql_manager_close(manager); + return 0; +} + + diff --git a/include/Makefile.am b/include/Makefile.am index f3685b51cd3..b43e8dcca4b 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -28,7 +28,7 @@ noinst_HEADERS = global.h config-win.h \ my_dir.h mysys_err.h my_base.h \ my_nosys.h my_alarm.h queues.h \ my_tree.h hash.h thr_alarm.h thr_lock.h \ - getopt.h t_ctype.h violite.h \ + getopt.h t_ctype.h violite.h md5.h \ mysql_version.h.in # mysql_version.h are generated diff --git a/sql/md5.h b/include/md5.h index 6fe4e543bb0..6fe4e543bb0 100644 --- a/sql/md5.h +++ b/include/md5.h diff --git a/include/mysql.h b/include/mysql.h index 7db907fb0f3..44dfe9c2f6a 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -220,7 +220,31 @@ typedef struct st_mysql_res { my_bool eof; /* Used my mysql_fetch_row */ } MYSQL_RES; +#define MAX_MYSQL_MANAGER_ERR 256 +#define MAX_MYSQL_MANAGER_MSG 256 +#define MANAGER_OK 200 +#define MANAGER_INFO 250 +#define MANAGER_ACCESS 401 +#define MANAGER_CLIENT_ERR 450 +#define MANAGER_INTERNAL_ERR 500 + + + +typedef struct st_mysql_manager +{ + Vio* vio; + char *host,*user,*passwd; + unsigned int port; + my_bool free_me; + my_bool eof; + int cmd_status; + int last_errno; + char* net_buf,*net_buf_pos,*net_data_end; + int net_buf_size; + char last_error[MAX_MYSQL_MANAGER_ERR]; +} MYSQL_MANAGER; + /* Set up and bring down the server; to ensure that applications will * work when linked against either the standard client library or the * embedded server library, these functions should be called. */ @@ -365,7 +389,18 @@ char * STDCALL mysql_odbc_escape_string(MYSQL *mysql, unsigned long *length)); void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name); unsigned int STDCALL mysql_thread_safe(void); - +MYSQL_MANAGER* STDCALL mysql_manager_init(MYSQL_MANAGER* con); +MYSQL_MANAGER* STDCALL mysql_manager_connect(MYSQL_MANAGER* con, + const char* host, + const char* user, + const char* passwd, + unsigned int port); +void STDCALL mysql_manager_close(MYSQL_MANAGER* con); +int STDCALL mysql_manager_command(MYSQL_MANAGER* con, + const char* cmd, int cmd_len); +int STDCALL mysql_manager_fetch_line(MYSQL_MANAGER* con, + char* res_buf, + int res_buf_size); #define mysql_reload(mysql) mysql_refresh((mysql),REFRESH_GRANT) #ifdef USE_OLD_FUNCTIONS diff --git a/include/mysql_com.h b/include/mysql_com.h index ce134fcab2c..6128a29ed5a 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -164,6 +164,8 @@ int net_write_command(NET *net,unsigned char command,const char *packet, unsigned long len); int net_real_write(NET *net,const char *packet,unsigned long len); unsigned long my_net_read(NET *net); +int my_connect(my_socket s, const struct sockaddr *name, uint namelen, + uint timeout); struct rand_struct { unsigned long seed1,seed2,max_value; diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared index 8513b92624e..e00a961cabe 100644 --- a/libmysql/Makefile.shared +++ b/libmysql/Makefile.shared @@ -31,7 +31,7 @@ noinst_PROGRAMS = conf_to_src CHARSET_OBJS=@CHARSET_OBJS@ LTCHARSET_OBJS= ${CHARSET_OBJS:.o=.lo} -target_sources = libmysql.c net.c password.c \ +target_sources = libmysql.c net.c password.c manager.c \ get_password.c errmsg.c mystringsobjects = strmov.lo strxmov.lo strnmov.lo strmake.lo strend.lo \ @@ -56,7 +56,7 @@ mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \ thr_mutex.lo mulalloc.lo string.lo default.lo \ my_compress.lo array.lo my_once.lo list.lo my_net.lo \ charset.lo hash.lo mf_iocache.lo my_seek.lo \ - my_pread.lo mf_cache.lo my_vsnprintf.lo + my_pread.lo mf_cache.lo my_vsnprintf.lo md5.lo # Not needed in the minimum library mysysobjects2 = getopt.lo getopt1.lo getvar.lo my_lib.lo diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index e7705ee20e4..f0cc6429118 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -138,12 +138,12 @@ static MYSQL* spawn_init(MYSQL* parent, const char* host, * A modified version of connect(). connect2() allows you to specify * a timeout value, in seconds, that we should wait until we * derermine we can't connect to a particular host. If timeout is 0, -* connect2() will behave exactly like connect(). +* my_connect() will behave exactly like connect(). * * Base version coded by Steve Bernacki, Jr. <steve@navinet.net> *****************************************************************************/ -static int connect2(my_socket s, const struct sockaddr *name, uint namelen, +int my_connect(my_socket s, const struct sockaddr *name, uint namelen, uint timeout) { #if defined(__WIN__) || defined(OS2) @@ -1521,7 +1521,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, bzero((char*) &UNIXaddr,sizeof(UNIXaddr)); UNIXaddr.sun_family = AF_UNIX; strmov(UNIXaddr.sun_path, unix_socket); - if (connect2(sock,(struct sockaddr *) &UNIXaddr, sizeof(UNIXaddr), + if (my_connect(sock,(struct sockaddr *) &UNIXaddr, sizeof(UNIXaddr), mysql->options.connect_timeout) <0) { DBUG_PRINT("error",("Got error %d on connect to local server",socket_errno)); @@ -1621,7 +1621,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, } #endif sock_addr.sin_port = (ushort) htons((ushort) port); - if (connect2(sock,(struct sockaddr *) &sock_addr, sizeof(sock_addr), + if (my_connect(sock,(struct sockaddr *) &sock_addr, sizeof(sock_addr), mysql->options.connect_timeout) <0) { DBUG_PRINT("error",("Got error %d on connect to '%s'",socket_errno,host)); diff --git a/mysys/Makefile.am b/mysys/Makefile.am index 9a44d569e45..4542eafa5c0 100644 --- a/mysys/Makefile.am +++ b/mysys/Makefile.am @@ -45,7 +45,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\ my_quick.c my_lockmem.c my_static.c \ getopt.c getopt1.c getvar.c my_mkdir.c \ default.c my_compress.c checksum.c raid.cc my_net.c \ - my_vsnprintf.c charset.c my_bitmap.c + my_vsnprintf.c charset.c my_bitmap.c md5.c EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \ thr_mutex.c thr_rwlock.c libmysys_a_LIBADD = @THREAD_LOBJECTS@ diff --git a/sql/md5.c b/mysys/md5.c index 66b96b92ab2..66b96b92ab2 100644 --- a/sql/md5.c +++ b/mysys/md5.c diff --git a/sql/Makefile.am b/sql/Makefile.am index 3456a07977d..d978d56db3d 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -55,7 +55,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ ha_heap.h ha_myisam.h ha_berkeley.h ha_innobase.h \ ha_gemini.h opt_range.h opt_ft.h \ sql_select.h structs.h table.h sql_udf.h hash_filo.h\ - lex.h lex_symbol.h sql_acl.h sql_crypt.h md5.h \ + lex.h lex_symbol.h sql_acl.h sql_crypt.h \ log_event.h mini_client.h sql_repl.h slave.h \ stacktrace.h sql_sort.h mysqld_SOURCES = sql_lex.cc sql_handler.cc \ @@ -82,7 +82,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \ sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc \ slave.cc sql_repl.cc sql_union.cc \ mini_client.cc mini_client_errors.c \ - md5.c stacktrace.c + stacktrace.c gen_lex_hash_SOURCES = gen_lex_hash.cc gen_lex_hash_LDADD = $(LDADD) $(CXXLDFLAGS) diff --git a/sql/handler.cc b/sql/handler.cc index f790417cf79..366a8abd631 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -840,7 +840,7 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info, error=table.file->create(name,&table,create_info); VOID(closefrm(&table)); if (error) { - if (table.db_type == DB_TYPE_INNOBASE) { + if (table.db_type == DB_TYPE_INNODB) { /* Creation of InnoDB table cannot fail because of an OS error: put error as the number */ my_error(ER_CANT_CREATE_TABLE,MYF(ME_BELL+ME_WAITTANG),name,error); diff --git a/tools/managertest1.nc b/tools/managertest1.nc index 1125e141588..5478cb56abb 100644 --- a/tools/managertest1.nc +++ b/tools/managertest1.nc @@ -1,4 +1,3 @@ -root secret def_exec server /usr/sbin/mysqld --socket=/tmp/temp.sock --skip-grant --skip-net --datadir=/tmp set_exec_con server root localhost /tmp/temp.sock start_exec server 3 @@ -9,4 +8,4 @@ start_exec server 3 show_exec stop_exec server 3 show_exec -shutdown +quit diff --git a/tools/mysqlmanager-sample.pwd b/tools/mysqlmanager-sample.pwd new file mode 100644 index 00000000000..51c1ade1b77 --- /dev/null +++ b/tools/mysqlmanager-sample.pwd @@ -0,0 +1 @@ +root:5ebe2294ecd0e0f08eab7690d2a6ee69 diff --git a/tools/mysqlmanager.c b/tools/mysqlmanager.c index 3572dde67d3..4730ea8b043 100644 --- a/tools/mysqlmanager.c +++ b/tools/mysqlmanager.c @@ -41,10 +41,10 @@ #include <errno.h> #include <violite.h> #include <my_pthread.h> +#include <md5.h> #define MANAGER_VERSION "1.0" -#define MANAGER_GREETING "MySQL Server Management Daemon v." ## \ - MANAGER_VERSION +#define MANAGER_GREETING "MySQL Server Management Daemon v. 1.0" #define LOG_ERR 1 #define LOG_WARN 2 @@ -121,16 +121,10 @@ int one_thread = 0; /* for debugging */ #define MAX_CLIENT_MSG_LEN 256 #define NET_BLOCK 2048 -#define MD5_LEN 32 +#define MD5_LEN 16 #define ESCAPE_CHAR '\\' #define EOL_CHAR '\n' -#define MSG_OK 200 -#define MSG_INFO 250 -#define MSG_ACCESS 401 -#define MSG_CLIENT_ERR 450 -#define MSG_INTERNAL_ERR 500 - /* access flags */ #define PRIV_SHUTDOWN 1 @@ -138,7 +132,7 @@ int one_thread = 0; /* for debugging */ struct manager_thd { Vio* vio; - char user[MAX_USER_NAME]; + char user[MAX_USER_NAME+1]; int priv_flags; char* cmd_buf; int fatal,finished; @@ -146,7 +140,7 @@ struct manager_thd struct manager_user { - char user[MAX_USER_NAME]; + char user[MAX_USER_NAME+1]; char md5_pass[MD5_LEN]; int user_len; const char* error; @@ -175,6 +169,7 @@ static byte* get_user_key(const byte* u, uint* len, my_bool __attribute__((unused)) t); static uint tokenize_args(char* arg_start,char** arg_end); static void init_arg_array(char* arg_str,char** args,uint arg_count); +static int hex_val(char c); typedef int (*manager_cmd_handler)(struct manager_thd*,char*,char*); @@ -359,7 +354,7 @@ static int exec_line(struct manager_thd* thd,char* buf,char* buf_end) *p=tolower(*p); if (!(cmd=lookup_cmd(buf,(int)(p-buf)))) { - client_msg(thd->vio,MSG_CLIENT_ERR, + client_msg(thd->vio,MANAGER_CLIENT_ERR, "Unrecognized command, type help to see list of supported\ commands"); return 1; @@ -381,13 +376,13 @@ static struct manager_cmd* lookup_cmd(char* s,int len) HANDLE_NOARG_DECL(ping) { - client_msg(thd->vio,MSG_OK,"Server management daemon is alive"); + client_msg(thd->vio,MANAGER_OK,"Server management daemon is alive"); return 0; } HANDLE_NOARG_DECL(quit) { - client_msg(thd->vio,MSG_OK,"Goodbye"); + client_msg(thd->vio,MANAGER_OK,"Goodbye"); thd->finished=1; return 0; } @@ -396,18 +391,18 @@ HANDLE_NOARG_DECL(help) { struct manager_cmd* cmd = commands; Vio* vio = thd->vio; - client_msg_pre(vio,MSG_INFO,"Available commands:"); + client_msg_pre(vio,MANAGER_INFO,"Available commands:"); for (;cmd->name;cmd++) { - client_msg_pre(vio,MSG_INFO,"%s - %s", cmd->name, cmd->help); + client_msg_pre(vio,MANAGER_INFO,"%s - %s", cmd->name, cmd->help); } - client_msg_pre(vio,MSG_INFO,"End of help"); + client_msg_pre(vio,MANAGER_INFO,"End of help"); return 0; } HANDLE_NOARG_DECL(shutdown) { - client_msg(thd->vio,MSG_OK,"Shutdown started, goodbye"); + client_msg(thd->vio,MANAGER_OK,"Shutdown started, goodbye"); thd->finished=1; shutdown_requested = 1; if (!one_thread) @@ -458,10 +453,10 @@ HANDLE_DECL(set_exec_con) } } pthread_mutex_unlock(&lock_exec_hash); - client_msg(thd->vio,MSG_OK,"Entry updated"); + client_msg(thd->vio,MANAGER_OK,"Entry updated"); return 0; err: - client_msg(thd->vio,MSG_CLIENT_ERR,error); + client_msg(thd->vio,MANAGER_CLIENT_ERR,error); return 1; } @@ -506,10 +501,10 @@ HANDLE_DECL(start_exec) pthread_mutex_unlock(&e->lock); if (error) goto err; - client_msg(thd->vio,MSG_OK,"'%s' started",e->ident); + client_msg(thd->vio,MANAGER_OK,"'%s' started",e->ident); return 0; err: - client_msg(thd->vio,MSG_CLIENT_ERR,error); + client_msg(thd->vio,MANAGER_CLIENT_ERR,error); return 1; } @@ -560,11 +555,11 @@ HANDLE_DECL(stop_exec) pthread_mutex_unlock(&e->lock); if (!error) { - client_msg(thd->vio,MSG_OK,"'%s' terminated",e->ident); + client_msg(thd->vio,MANAGER_OK,"'%s' terminated",e->ident); return 0; } err: - client_msg(thd->vio,MSG_CLIENT_ERR,error); + client_msg(thd->vio,MANAGER_CLIENT_ERR,error); return 1; } @@ -592,10 +587,10 @@ HANDLE_DECL(def_exec) } hash_insert(&exec_hash,(byte*)e); pthread_mutex_unlock(&lock_exec_hash); - client_msg(thd->vio,MSG_OK,"Exec definition created"); + client_msg(thd->vio,MANAGER_OK,"Exec definition created"); return 0; err: - client_msg(thd->vio,MSG_CLIENT_ERR,error); + client_msg(thd->vio,MANAGER_CLIENT_ERR,error); if (e) manager_exec_free(e); return 1; @@ -604,7 +599,7 @@ err: HANDLE_NOARG_DECL(show_exec) { uint i; - client_msg_pre(thd->vio,MSG_INFO,"Exec_def\tPid\tExit_status\tCon_info\ + client_msg_pre(thd->vio,MANAGER_INFO,"Exec_def\tPid\tExit_status\tCon_info\ \tArguments"); pthread_mutex_lock(&lock_exec_hash); for (i=0;i<exec_hash.records;i++) @@ -613,7 +608,7 @@ HANDLE_NOARG_DECL(show_exec) manager_exec_print(thd->vio,e); } pthread_mutex_unlock(&lock_exec_hash); - client_msg(thd->vio,MSG_INFO,"End"); + client_msg(thd->vio,MANAGER_INFO,"End"); return 0; } @@ -699,7 +694,7 @@ static char* arg_strmov(char* dest, const char* src, int n) static void manager_exec_print(Vio* vio,struct manager_exec* e) { - char buf[MAX_CLIENT_MSG_LEN]; + char buf[MAX_MYSQL_MANAGER_MSG]; char* p=buf,*buf_end=buf+sizeof(buf)-1; char** args=e->args; @@ -737,17 +732,45 @@ static void manager_exec_print(Vio* vio,struct manager_exec* e) } end: *p=0; - client_msg_pre(vio,MSG_INFO,buf); + client_msg_pre(vio,MANAGER_INFO,buf); return; } static int authenticate(struct manager_thd* thd) { - char* buf_end; - client_msg(thd->vio,MSG_INFO, manager_greeting); + char* buf_end,*buf,*p,*p_end; + my_MD5_CTX context; + uchar digest[MD5_LEN]; + struct manager_user* u; + char c; + + client_msg(thd->vio,MANAGER_INFO, manager_greeting); if (!(buf_end=read_line(thd))) return -1; - client_msg(thd->vio,MSG_OK,"OK"); + for (buf=thd->cmd_buf,p=thd->user,p_end=p+MAX_USER_NAME; + buf<buf_end && (c=*buf) && p<p_end; buf++,p++) + { + if (isspace(c)) + { + *p=0; + break; + } + else + *p=c; + } + if (p==p_end || buf==buf_end) + return 1; + if (!(u=(struct manager_user*)hash_search(&user_hash,thd->user, + (uint)(p-thd->user)))) + return 1; + for (;isspace(*buf) && buf<buf_end;buf++) /* empty */; + + my_MD5Init(&context); + my_MD5Update(&context,buf,(uint)(buf_end-buf)); + my_MD5Final(digest,&context); + if (memcmp(u->md5_pass,digest,MD5_LEN)) + return 1; + client_msg(thd->vio,MANAGER_OK,"OK"); return 0; } @@ -923,7 +946,7 @@ static void client_msg_raw(Vio* vio, int err_code, int pre, const char* fmt, *p++='\r'; *p++='\n'; if (vio_write(vio,buf,(uint)(p-buf))<=0) - log_err("Failed writing to client: errno=%d"); + log_err("Failed writing to client: errno=%d",errno); } static void client_msg(Vio* vio, int err_code, const char* fmt, ...) @@ -953,6 +976,7 @@ static char* read_line(struct manager_thd* thd) if ((len=vio_read(thd->vio,p,read_len))<=0) { log_err("Error reading command from client"); + thd->fatal=1; return 0; } block_end=p+len; @@ -981,7 +1005,7 @@ static char* read_line(struct manager_thd* thd) return p_back; } } - client_msg(thd->vio,MSG_CLIENT_ERR,"Command line too long"); + client_msg(thd->vio,MANAGER_CLIENT_ERR,"Command line too long"); return 0; } @@ -1092,7 +1116,7 @@ static int parse_args(int argc, char **argv) one_thread=1; break; case 'p': - manager_pw_file=MANAGER_PW_FILE; + manager_pw_file=optarg; break; case 'C': manager_connect_retries=atoi(optarg); @@ -1185,7 +1209,7 @@ static int run_server_loop() if (authenticate(thd)) { - client_msg(vio,MSG_ACCESS, "Access denied"); + client_msg(vio,MANAGER_ACCESS, "Access denied"); manager_thd_free(thd); continue; } @@ -1199,7 +1223,7 @@ static int run_server_loop() } else if (pthread_create(&th,0,process_connection,(void*)thd)) { - client_msg(vio,MSG_INTERNAL_ERR,"Could not create thread, errno=%d", + client_msg(vio,MANAGER_INTERNAL_ERR,"Could not create thread, errno=%d", errno); manager_thd_free(thd); continue; @@ -1352,15 +1376,24 @@ static void manager_exec_free(void* e) my_free(e,MYF(0)); } +static int hex_val(char c) +{ + if (isdigit(c)) + return c-'0'; + c=tolower(c); + return c-'a'+10; +} + static struct manager_user* manager_user_new(char* buf) { struct manager_user* tmp; - char* p,*user_end; + char* p,*user_end,*p_end; char c; if (!(tmp=(struct manager_user*)my_malloc(sizeof(*tmp),MYF(0)))) return 0; p=tmp->user; - user_end=p+MAX_USER_NAME-1; + tmp->error=0; + user_end=p+MAX_USER_NAME; for (;(c=*buf) && p<user_end;buf++) { if (c == ':') @@ -1379,13 +1412,18 @@ static struct manager_user* manager_user_new(char* buf) tmp->error="Username too long"; if (tmp->error) return tmp; - if (strlen(buf) < MD5_LEN) + if (strlen(buf) < 2*MD5_LEN) { tmp->error="Invalid MD5 sum, too short"; return tmp; } - memcpy(tmp->md5_pass,buf,MD5_LEN); - tmp->error=0; + p=tmp->md5_pass; + p_end=p+MD5_LEN; + for (; p<p_end;p++,buf+=2) + { + *p=hex_val(*buf)*16+hex_val(buf[1]); + } + return tmp; } diff --git a/vio/test-ssl b/vio/test-ssl Binary files differindex 0a3e73a819d..7d74ce3d0f9 100755 --- a/vio/test-ssl +++ b/vio/test-ssl |