mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Import changeset
This commit is contained in:
10
libmysql/.cvsignore
Normal file
10
libmysql/.cvsignore
Normal file
@ -0,0 +1,10 @@
|
||||
*.lo
|
||||
.deps
|
||||
.libs
|
||||
Makefile
|
||||
Makefile.in
|
||||
conf_to_src
|
||||
config.status
|
||||
configure
|
||||
ctype_extra_sources.c
|
||||
libmysqlclient.la
|
149
libmysql/Makefile.am
Normal file
149
libmysql/Makefile.am
Normal file
@ -0,0 +1,149 @@
|
||||
# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Library General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library 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
|
||||
# Library General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# License along with this library; if not, write to the Free
|
||||
# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
# MA 02111-1307, USA
|
||||
|
||||
# This file is public domain and comes with NO WARRANTY of any kind
|
||||
|
||||
MYSQLDATAdir = $(localstatedir)
|
||||
MYSQLSHAREdir = $(pkgdatadir)
|
||||
MYSQLBASEdir= $(prefix)
|
||||
INCLUDES = -I$(srcdir)/../include -I../include \
|
||||
-I$(srcdir)/.. -I$(top_srcdir) -I..
|
||||
LIBS = @CLIENT_LIBS@
|
||||
LDADD = @CLIENT_EXTRA_LDFLAGS@ libmysqlclient.la
|
||||
pkglib_LTLIBRARIES = libmysqlclient.la
|
||||
|
||||
noinst_PROGRAMS = conf_to_src
|
||||
|
||||
# We need .lo, not .o files for everything.
|
||||
CHARSET_OBJS=@CHARSET_OBJS@
|
||||
LTCHARSET_OBJS= ${CHARSET_OBJS:.o=.lo}
|
||||
|
||||
libmysqlclient_la_SOURCES = libmysql.c net.c violite.c password.c \
|
||||
get_password.c errmsg.c
|
||||
|
||||
mystringsobjects = strmov.lo strxmov.lo strnmov.lo strmake.lo strend.lo \
|
||||
strnlen.lo strfill.lo is_prefix.lo \
|
||||
int2str.lo str2int.lo strinstr.lo strcont.lo \
|
||||
strcend.lo \
|
||||
bchange.lo bmove.lo bmove_upp.lo longlong2str.lo \
|
||||
strtoull.lo strtoll.lo llstr.lo strto.lo \
|
||||
ctype.lo $(LTCHARSET_OBJS)
|
||||
mystringsextra= strto.c ctype_autoconf.c
|
||||
dbugobjects = dbug.lo # IT IS IN SAFEMALLOC.C sanity.lo
|
||||
mysysheaders = mysys_priv.h my_static.h
|
||||
mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \
|
||||
my_create.lo my_delete.lo my_tempnam.lo my_open.lo \
|
||||
mf_casecnv.lo my_read.lo my_write.lo errors.lo \
|
||||
my_error.lo my_getwd.lo my_div.lo \
|
||||
mf_pack.lo my_messnc.lo mf_dirname.lo mf_fn_ext.lo\
|
||||
mf_wcomp.lo typelib.lo safemalloc.lo my_alloc.lo \
|
||||
mf_format.lo mf_path.lo mf_unixpath.lo my_fopen.lo \
|
||||
mf_loadpath.lo my_pthread.lo my_thr_init.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
|
||||
# Not needed in the minimum library
|
||||
mysysobjects2 = getopt.lo getopt1.lo getvar.lo my_lib.lo
|
||||
mysysobjects = $(mysysobjects1) $(mysysobjects2)
|
||||
libmysqlclient_la_LIBADD = $(mysysobjects) $(mystringsobjects) $(dbugobjects)
|
||||
libmysqlclient_la_LDFLAGS = -version-info @SHARED_LIB_VERSION@
|
||||
CLEANFILES = $(libmysqlclient_la_LIBADD) $(SHLIBOBJS) \
|
||||
libmysqclient.la
|
||||
DEFS = -DUNDEF_THREADS_HACK \
|
||||
-DDEFAULT_CHARSET_HOME="\"$(MYSQLBASEdir)\"" \
|
||||
-DDATADIR="\"$(MYSQLDATAdir)\"" \
|
||||
-DSHAREDIR="\"$(MYSQLSHAREdir)\""
|
||||
|
||||
# The automatic dependencies miss this
|
||||
bmove_upp.lo: $(LTCHARSET_OBJS)
|
||||
ctype.c: ctype_extra_sources.c
|
||||
|
||||
# This is called from the toplevel makefile
|
||||
link_sources:
|
||||
set -x; \
|
||||
ss=`echo $(mystringsobjects) | sed "s;\.lo;.c;g"`; \
|
||||
ds=`echo $(dbugobjects) | sed "s;\.lo;.c;g"`; \
|
||||
ms=`echo $(mysysobjects) | sed "s;\.lo;.c;g"`; \
|
||||
for f in $$ss; do \
|
||||
rm -f $(srcdir)/$$f; \
|
||||
@LN_CP_F@ $(srcdir)/../strings/$$f $(srcdir)/$$f; \
|
||||
done; \
|
||||
for f in $(mystringsextra); do \
|
||||
rm -f $(srcdir)/$$f; \
|
||||
@LN_CP_F@ $(srcdir)/../strings/$$f $(srcdir)/$$f; \
|
||||
done; \
|
||||
for f in $$ds; do \
|
||||
rm -f $(srcdir)/$$f; \
|
||||
@LN_CP_F@ $(srcdir)/../dbug/$$f $(srcdir)/$$f; \
|
||||
done; \
|
||||
for f in $$ms $(mysysheaders); do \
|
||||
rm -f $(srcdir)/$$f; \
|
||||
@LN_CP_F@ $(srcdir)/../mysys/$$f $(srcdir)/$$f; \
|
||||
done;
|
||||
|
||||
clean-local:
|
||||
rm -f `echo $(mystringsobjects) | sed "s;\.lo;.c;g"` \
|
||||
`echo $(dbugobjects) | sed "s;\.lo;.c;g"` \
|
||||
`echo $(mysysobjects) | sed "s;\.lo;.c;g"` \
|
||||
$(mystringsextra) ctype_extra_sources.c \
|
||||
../linked_client_sources
|
||||
|
||||
ctype_extra_sources.c: conf_to_src
|
||||
./conf_to_src $(top_srcdir) @CHARSETS_NEED_SOURCE@ > \
|
||||
$(srcdir)/ctype_extra_sources.c
|
||||
conf_to_src_SOURCES = conf_to_src.c
|
||||
conf_to_src_LDADD=
|
||||
|
||||
# This part requires GNUmake
|
||||
#
|
||||
# This makes a distribution file with only the files needed to compile
|
||||
# a minimal MySQL client library
|
||||
#
|
||||
# For a really minimal distribution (without debugging code) we could
|
||||
# keep only the stubs for safemalloc.c and debug.c
|
||||
#
|
||||
# A list of needed headers collected from the deps information 000213
|
||||
nh = global.h config-win32.h dbug.h errmsg.h global.h \
|
||||
m_ctype.h m_string.h \
|
||||
my_alarm.h my_config.h my_dir.h my_list.h my_net.h my_sys.h \
|
||||
mysql.h mysql_com.h mysql_version.h mysqld_error.h mysys_err.h \
|
||||
my_pthread.h thr_alarm.h violite.h
|
||||
# Get a list of the needed objects
|
||||
lobjs = $(mysysobjects1) $(dbugobjects) $(mystringsobjects)
|
||||
|
||||
do-lib-dist:
|
||||
dir=libmysql-$(MYSQL_NO_DASH_VERSION); \
|
||||
srcs1=`echo $(lobjs) | sed "s;\.lo;.c;g"`; \
|
||||
srcs2=$(libmysqlclient_la_SOURCES); \
|
||||
srcs="$$srcs1 $$srcs2"; \
|
||||
objs1=`echo $(lobjs) | sed "s;\.lo;.o;g"`; \
|
||||
objs2=`echo $(libmysqlclient_la_SOURCES) | sed "s;\.c;.o;g"`; \
|
||||
objs="$$objs1 $$objs2"; \
|
||||
rm -rf $$dir; \
|
||||
mkdir $$dir; \
|
||||
cp $$srcs $(mysysheaders) $$dir; \
|
||||
for i in $(nh); do cp ../include/$$i $$dir; done; \
|
||||
echo "# A very minimal Makefile to compile" > $$dir/Makefile; \
|
||||
echo "# the minimized libmysql library" >> $$dir/Makefile; \
|
||||
echo "# This file is autogenerated from Makefile.am" >> $$dir/Makefile; \
|
||||
echo 'CFLAGS= -I. -DUNDEF_THREADS_HACK' >>$$dir/Makefile; \
|
||||
echo "obj=$$objs" >>$$dir/Makefile; \
|
||||
echo 'all: libmysql.a' >>$$dir/Makefile; \
|
||||
echo 'libmysql.a: $$(obj)' >>$$dir/Makefile; \
|
||||
echo ' $$(AR) r $$@ $$?' >>$$dir/Makefile; \
|
||||
gtar cvzf $$dir.tar.gz $$dir; \
|
||||
cd $$dir; gmake
|
91
libmysql/acinclude.m4
Normal file
91
libmysql/acinclude.m4
Normal file
@ -0,0 +1,91 @@
|
||||
# Local macros for automake & autoconf
|
||||
|
||||
AC_DEFUN(MYSQL_TYPE_ACCEPT,
|
||||
[ac_save_CXXFLAGS="$CXXFLAGS"
|
||||
AC_CACHE_CHECK([base type of last arg to accept], mysql_cv_btype_last_arg_accept,
|
||||
AC_LANG_SAVE
|
||||
AC_LANG_CPLUSPLUS
|
||||
if test "$ac_cv_prog_gxx" = "yes"
|
||||
then
|
||||
CXXFLAGS="$CXXFLAGS -Werror"
|
||||
fi
|
||||
mysql_cv_btype_last_arg_accept=none
|
||||
[AC_TRY_COMPILE([#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
],
|
||||
[int a = accept(1, (struct sockaddr *) 0, (socklen_t *) 0);],
|
||||
mysql_cv_btype_last_arg_accept=socklen_t)]
|
||||
if test $mysql_cv_btype_last_arg_accept = none; then
|
||||
[AC_TRY_COMPILE([#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
],
|
||||
[int a = accept(1, (struct sockaddr *) 0, (size_t *) 0);],
|
||||
mysql_cv_btype_last_arg_accept=size_t)]
|
||||
fi
|
||||
if test $mysql_cv_btype_last_arg_accept = none; then
|
||||
mysql_cv_btype_last_arg_accept=int
|
||||
fi)
|
||||
AC_LANG_RESTORE
|
||||
AC_DEFINE_UNQUOTED(SOCKET_SIZE_TYPE, $mysql_cv_btype_last_arg_accept)
|
||||
CXXFLAGS="$ac_save_CXXFLAGS"
|
||||
])
|
||||
|
||||
|
||||
#---START: Used in for client configure
|
||||
AC_DEFUN(MYSQL_CHECK_ULONG,
|
||||
[AC_MSG_CHECKING(for type ulong)
|
||||
AC_CACHE_VAL(ac_cv_ulong,
|
||||
[AC_TRY_RUN([#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
main()
|
||||
{
|
||||
ulong foo;
|
||||
foo++;
|
||||
exit(0);
|
||||
}], ac_cv_ulong=yes, ac_cv_ulong=no, ac_cv_ulong=no)])
|
||||
AC_MSG_RESULT($ac_cv_ulong)
|
||||
if test "$ac_cv_ulong" = "yes"
|
||||
then
|
||||
AC_DEFINE(HAVE_ULONG)
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN(MYSQL_CHECK_UCHAR,
|
||||
[AC_MSG_CHECKING(for type uchar)
|
||||
AC_CACHE_VAL(ac_cv_uchar,
|
||||
[AC_TRY_RUN([#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
main()
|
||||
{
|
||||
uchar foo;
|
||||
foo++;
|
||||
exit(0);
|
||||
}], ac_cv_uchar=yes, ac_cv_uchar=no, ac_cv_uchar=no)])
|
||||
AC_MSG_RESULT($ac_cv_uchar)
|
||||
if test "$ac_cv_uchar" = "yes"
|
||||
then
|
||||
AC_DEFINE(HAVE_UCHAR)
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN(MYSQL_CHECK_UINT,
|
||||
[AC_MSG_CHECKING(for type uint)
|
||||
AC_CACHE_VAL(ac_cv_uint,
|
||||
[AC_TRY_RUN([#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
main()
|
||||
{
|
||||
uint foo;
|
||||
foo++;
|
||||
exit(0);
|
||||
}], ac_cv_uint=yes, ac_cv_uint=no, ac_cv_uint=no)])
|
||||
AC_MSG_RESULT($ac_cv_uint)
|
||||
if test "$ac_cv_uint" = "yes"
|
||||
then
|
||||
AC_DEFINE(HAVE_UINT)
|
||||
fi
|
||||
])
|
||||
|
||||
#---END:
|
143
libmysql/conf_to_src.c
Normal file
143
libmysql/conf_to_src.c
Normal file
@ -0,0 +1,143 @@
|
||||
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA */
|
||||
|
||||
/* can't use -lmysys because this prog is used to create -lstrings */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define CHARSETS_SUBDIR "sql/share/charsets"
|
||||
#define CTYPE_TABLE_SIZE 257
|
||||
#define TO_LOWER_TABLE_SIZE 256
|
||||
#define TO_UPPER_TABLE_SIZE 256
|
||||
#define SORT_ORDER_TABLE_SIZE 256
|
||||
#define ROW_LEN 16
|
||||
|
||||
void print_arrays_for(char *set);
|
||||
|
||||
char *prog;
|
||||
char buf[1024], *p, *endptr;
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
prog = *argv;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "usage: %s source-dir [charset [, charset]]\n", prog);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
--argc; ++argv; /* skip program name */
|
||||
|
||||
if (chdir(*argv) != 0) {
|
||||
fprintf(stderr, "%s: can't cd to %s\n", prog, *argv);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
--argc; ++argv;
|
||||
|
||||
if (chdir(CHARSETS_SUBDIR) != 0) {
|
||||
fprintf(stderr, "%s: can't cd to %s\n", prog, CHARSETS_SUBDIR);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
while (argc--)
|
||||
print_arrays_for(*argv++);
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
void
|
||||
print_array(FILE *f, char *set, char *name, int n)
|
||||
{
|
||||
int i;
|
||||
char val[100];
|
||||
|
||||
printf("uchar %s_%s[] = {\n", name, set);
|
||||
|
||||
p = buf;
|
||||
*buf = '\0';
|
||||
for (i = 0; i < n; ++i)
|
||||
{
|
||||
/* get a word from f */
|
||||
endptr = p;
|
||||
for (;;)
|
||||
{
|
||||
while (isspace(*endptr))
|
||||
++endptr;
|
||||
if (*endptr && *endptr != '#') /* not comment */
|
||||
break;
|
||||
if ((fgets(buf, sizeof(buf), f)) == NULL)
|
||||
return; /* XXX: break silently */
|
||||
endptr = buf;
|
||||
}
|
||||
|
||||
p = val;
|
||||
while (!isspace(*endptr))
|
||||
*p++ = *endptr++;
|
||||
*p = '\0';
|
||||
p = endptr;
|
||||
|
||||
/* write the value out */
|
||||
|
||||
if (i == 0 || i % ROW_LEN == n % ROW_LEN)
|
||||
printf(" ");
|
||||
|
||||
printf("%3d", (unsigned char) strtol(val, (char **) NULL, 16));
|
||||
|
||||
if (i < n - 1)
|
||||
printf(",");
|
||||
|
||||
if ((i+1) % ROW_LEN == n % ROW_LEN)
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
printf("};\n\n");
|
||||
}
|
||||
|
||||
void
|
||||
print_arrays_for(char *set)
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
sprintf(buf, "%s.conf", set);
|
||||
|
||||
if ((f = fopen(buf, "r")) == NULL) {
|
||||
fprintf(stderr, "%s: can't read conf file for charset %s\n", prog, set);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf("\
|
||||
/* The %s character set. Generated automatically by configure and\n\
|
||||
* the %s program\n\
|
||||
*/\n\n",
|
||||
set, prog);
|
||||
|
||||
/* it would be nice if this used the code in mysys/charset.c, but... */
|
||||
print_array(f, set, "ctype", CTYPE_TABLE_SIZE);
|
||||
print_array(f, set, "to_lower", TO_LOWER_TABLE_SIZE);
|
||||
print_array(f, set, "to_upper", TO_UPPER_TABLE_SIZE);
|
||||
print_array(f, set, "sort_order", SORT_ORDER_TABLE_SIZE);
|
||||
printf("\n");
|
||||
|
||||
fclose(f);
|
||||
|
||||
return;
|
||||
}
|
230
libmysql/configure.in
Normal file
230
libmysql/configure.in
Normal file
@ -0,0 +1,230 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(libmysql.c)
|
||||
dnl The version number should be autogenerated from the toplevel configure.in
|
||||
AM_INIT_AUTOMAKE(libmysql, 3.23.11-alpha)
|
||||
AM_CONFIG_HEADER(my_config.h)
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_LN_S
|
||||
AC_PROG_RANLIB
|
||||
|
||||
# We use libtool
|
||||
AM_PROG_LIBTOOL
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(sgtty.h sys/ioctl.h)
|
||||
# Maybe some can be removed but I got sick of adding them on at a time
|
||||
# /David
|
||||
AC_CHECK_HEADERS(fcntl.h float.h floatingpoint.h ieeefp.h limits.h \
|
||||
memory.h pwd.h select.h \
|
||||
stdlib.h stddef.h \
|
||||
strings.h string.h synch.h sys/mman.h sys/socket.h \
|
||||
sys/timeb.h sys/types.h sys/un.h sys/vadvise.h sys/wait.h term.h \
|
||||
unistd.h utime.h sys/utime.h termio.h termios.h sched.h crypt.h alloca.h)
|
||||
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
AC_C_INLINE
|
||||
AC_CHECK_SIZEOF(char, 1)
|
||||
if test "$ac_cv_sizeof_char" -eq 0
|
||||
then
|
||||
AC_MSG_ERROR([No size for char type.
|
||||
A likely cause for this could be that there isn't any static libraries
|
||||
installed. You can verify this by checking if you have libm.a in /lib,
|
||||
/usr/lib or some other standard place. If this is the problem,
|
||||
install the static libraries and try again. If this isn't the
|
||||
problem, examine config.log for possible errors. If you want to
|
||||
report this include ALL system information and include at least the
|
||||
last 20 rows from config.log!])
|
||||
fi
|
||||
AC_CHECK_SIZEOF(int, 4)
|
||||
if test "$ac_cv_sizeof_int" -eq 0
|
||||
then
|
||||
AC_MSG_ERROR("No size for int type.")
|
||||
fi
|
||||
AC_CHECK_SIZEOF(long, 4)
|
||||
if test "$ac_cv_sizeof_long" -eq 0
|
||||
then
|
||||
AC_MSG_ERROR("No size for long type.")
|
||||
fi
|
||||
AC_CHECK_SIZEOF(long long, 8)
|
||||
if test "$ac_cv_sizeof_long_long" -eq 0
|
||||
then
|
||||
AC_MSG_ERROR("MySQL needs a long long type.")
|
||||
fi
|
||||
AC_TYPE_SIZE_T
|
||||
AC_HEADER_TIME
|
||||
AC_TYPE_UID_T
|
||||
|
||||
# Do the system files define ulong
|
||||
MYSQL_CHECK_ULONG
|
||||
# Do the system files define uchar
|
||||
MYSQL_CHECK_UCHAR
|
||||
# Do the system files define uint
|
||||
MYSQL_CHECK_UINT
|
||||
|
||||
#---START: Used in for client configure
|
||||
# Check base type of last arg to accept
|
||||
MYSQL_TYPE_ACCEPT
|
||||
#---END:
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_TYPE_SIGNAL
|
||||
# Standard MySQL list
|
||||
AC_CHECK_FUNCS(alarm bmove \
|
||||
chsize ftruncate rint finite fpsetmask fpresetsticky\
|
||||
cuserid fcntl fconvert \
|
||||
getrusage getpwuid getcwd getrlimit getwd index locking longjmp \
|
||||
perror pread realpath rename \
|
||||
socket strnlen madvise \
|
||||
strtoul strtoull snprintf tempnam thr_setconcurrency \
|
||||
gethostbyaddr_r gethostbyname_r getpwnam \
|
||||
bfill bzero bcmp strstr strpbrk strerror\
|
||||
tell atod memcpy memmove \
|
||||
setupterm strcasecmp sighold \
|
||||
vidattr setupterm lrand48 localtime_r \
|
||||
sigset sigthreadmask pthread_sigmask pthread_setprio pthread_setprio_np \
|
||||
pthread_setschedparam pthread_attr_setprio pthread_attr_setschedparam \
|
||||
pthread_attr_create pthread_getsequence_np pthread_attr_setstacksize \
|
||||
pthread_condattr_create rwlock_init \
|
||||
crypt dlopen dlerror fchmod getpass getpassphrase)
|
||||
|
||||
# This is special for libmysql
|
||||
AC_CHECK_FUNCS(strtok_r)
|
||||
|
||||
#---START: Used in for client configure
|
||||
|
||||
# Check definition of gethostbyname_r (glibc2.0.100 is different from Solaris)
|
||||
ac_save_CXXFLAGS="$CXXFLAGS"
|
||||
AC_CACHE_CHECK([style of gethostname_r routines], mysql_cv_gethostname_style,
|
||||
AC_LANG_SAVE
|
||||
AC_LANG_CPLUSPLUS
|
||||
if test "$ac_cv_prog_gxx" = "yes"
|
||||
then
|
||||
CXXFLAGS="$CXXFLAGS -Werror"
|
||||
fi
|
||||
AC_TRY_COMPILE(
|
||||
[#ifndef SCO
|
||||
#define _REENTRANT
|
||||
#endif
|
||||
#include <pthread.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>],
|
||||
[int skr;
|
||||
|
||||
int res = gethostbyname_r((const char *) 0,
|
||||
(struct hostent*) 0, (char*) 0, 0, (struct hostent **) 0, &skr);],
|
||||
mysql_cv_gethostname_style=glibc2, mysql_cv_gethostname_style=other))
|
||||
AC_LANG_RESTORE
|
||||
CXXFLAGS="$ac_save_CXXFLAGS"
|
||||
if test "$mysql_cv_gethostname_style" = "glibc2"
|
||||
then
|
||||
AC_DEFINE(HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R)
|
||||
fi
|
||||
|
||||
if test "$with_mit_threads" = "no"
|
||||
then
|
||||
# Check definition of pthread_getspecific
|
||||
AC_CACHE_CHECK("args to pthread_getspecific", mysql_cv_getspecific_args,
|
||||
AC_TRY_COMPILE(
|
||||
[#ifndef SCO
|
||||
#define _REENTRANT
|
||||
#endif
|
||||
#define _POSIX_PTHREAD_SEMANTICS
|
||||
#include <pthread.h> ],
|
||||
[ void *pthread_getspecific(pthread_key_t key);
|
||||
pthread_getspecific((pthread_key_t) NULL); ],
|
||||
mysql_cv_getspecific_args=POSIX, mysql_cv_getspecific_args=other))
|
||||
if test "$mysql_cv_getspecific_args" = "other"
|
||||
then
|
||||
AC_DEFINE(HAVE_NONPOSIX_PTHREAD_GETSPECIFIC)
|
||||
fi
|
||||
|
||||
# Check definition of pthread_mutex_init
|
||||
AC_CACHE_CHECK("args to pthread_mutex_init", mysql_cv_mutex_init_args,
|
||||
AC_TRY_COMPILE(
|
||||
[#ifndef SCO
|
||||
#define _REENTRANT
|
||||
#endif
|
||||
#define _POSIX_PTHREAD_SEMANTICS
|
||||
#include <pthread.h> ],
|
||||
[
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutex_t mp;
|
||||
pthread_mutex_init(&mp,&attr); ],
|
||||
mysql_cv_mutex_init_args=POSIX, mysql_cv_mutex_init_args=other))
|
||||
if test "$mysql_cv_mutex_init_args" = "other"
|
||||
then
|
||||
AC_DEFINE(HAVE_NONPOSIX_PTHREAD_MUTEX_INIT)
|
||||
fi
|
||||
fi
|
||||
#---END:
|
||||
|
||||
#---START: Used in for client configure
|
||||
# Check definition of readdir_r
|
||||
AC_CACHE_CHECK("args to readdir_r", mysql_cv_readdir_r,
|
||||
AC_TRY_LINK(
|
||||
[#ifndef SCO
|
||||
#define _REENTRANT
|
||||
#endif
|
||||
#define _POSIX_PTHREAD_SEMANTICS
|
||||
#include <pthread.h>
|
||||
#include <dirent.h>],
|
||||
[ int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
|
||||
readdir_r((DIR *) NULL, (struct dirent *) NULL, (struct dirent **) NULL); ],
|
||||
mysql_cv_readdir_r=POSIX, mysql_cv_readdir_r=other))
|
||||
if test "$mysql_cv_readdir_r" = "POSIX"
|
||||
then
|
||||
AC_DEFINE(HAVE_READDIR_R)
|
||||
fi
|
||||
|
||||
# Check definition av posix sigwait()
|
||||
AC_CACHE_CHECK("style of sigwait", mysql_cv_sigwait,
|
||||
AC_TRY_LINK(
|
||||
[#ifndef SCO
|
||||
#define _REENTRANT
|
||||
#endif
|
||||
#define _POSIX_PTHREAD_SEMANTICS
|
||||
#include <pthread.h>
|
||||
#include <signal.h>],
|
||||
[#ifndef _AIX
|
||||
sigset_t set;
|
||||
int sig;
|
||||
sigwait(&set,&sig);
|
||||
#endif],
|
||||
mysql_cv_sigwait=POSIX, mysql_cv_sigwait=other))
|
||||
if test "$mysql_cv_sigwait" = "POSIX"
|
||||
then
|
||||
AC_DEFINE(HAVE_SIGWAIT)
|
||||
fi
|
||||
|
||||
if test "$mysql_cv_sigwait" != "POSIX"
|
||||
then
|
||||
unset mysql_cv_sigwait
|
||||
# Check definition av posix sigwait()
|
||||
AC_CACHE_CHECK("style of sigwait", mysql_cv_sigwait,
|
||||
AC_TRY_LINK(
|
||||
[#ifndef SCO
|
||||
#define _REENTRANT
|
||||
#endif
|
||||
#define _POSIX_PTHREAD_SEMANTICS
|
||||
#include <pthread.h>
|
||||
#include <signal.h>],
|
||||
[sigset_t set;
|
||||
int sig;
|
||||
sigwait(&set);],
|
||||
mysql_cv_sigwait=NONPOSIX, mysql_cv_sigwait=other))
|
||||
if test "$mysql_cv_sigwait" = "NONPOSIX"
|
||||
then
|
||||
AC_DEFINE(HAVE_NONPOSIX_SIGWAIT)
|
||||
fi
|
||||
fi
|
||||
#---END:
|
||||
|
||||
AC_OUTPUT(Makefile)
|
112
libmysql/dll.c
Normal file
112
libmysql/dll.c
Normal file
@ -0,0 +1,112 @@
|
||||
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA */
|
||||
|
||||
/*
|
||||
** Handling initialization of the dll library
|
||||
*/
|
||||
|
||||
#include <global.h>
|
||||
#include <my_sys.h>
|
||||
#include <my_pthread.h>
|
||||
|
||||
static bool libmysql_inited=0;
|
||||
|
||||
void libmysql_init(void)
|
||||
{
|
||||
if (libmysql_inited)
|
||||
return;
|
||||
libmysql_inited=1;
|
||||
my_init();
|
||||
{
|
||||
DBUG_ENTER("libmysql_init");
|
||||
#ifdef LOG_ALL
|
||||
DBUG_PUSH("d:t:S:O,c::\\tmp\\libmysql.log");
|
||||
#else
|
||||
if (getenv("LIBMYSQL_LOG") != NULL)
|
||||
DBUG_PUSH(getenv("LIBMYSQL_LOG"));
|
||||
#endif
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __WIN__
|
||||
|
||||
static int inited=0,threads=0;
|
||||
HINSTANCE NEAR s_hModule; /* Saved module handle */
|
||||
DWORD main_thread;
|
||||
|
||||
BOOL APIENTRY LibMain(HANDLE hInst,DWORD ul_reason_being_called,
|
||||
LPVOID lpReserved)
|
||||
{
|
||||
switch (ul_reason_being_called) {
|
||||
case DLL_PROCESS_ATTACH: /* case of libentry call in win 3.x */
|
||||
if (!inited++)
|
||||
{
|
||||
s_hModule=hInst;
|
||||
libmysql_init();
|
||||
main_thread=GetCurrentThreadId();
|
||||
}
|
||||
break;
|
||||
case DLL_THREAD_ATTACH:
|
||||
threads++;
|
||||
my_thread_init();
|
||||
break;
|
||||
case DLL_PROCESS_DETACH: /* case of wep call in win 3.x */
|
||||
if (!--inited) /* Safety */
|
||||
{
|
||||
/* my_thread_init() */ /* This may give extra safety */
|
||||
my_end(0);
|
||||
}
|
||||
break;
|
||||
case DLL_THREAD_DETACH:
|
||||
/* Main thread will free by my_end() */
|
||||
threads--;
|
||||
if (main_thread != GetCurrentThreadId())
|
||||
my_thread_end();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
} /* switch */
|
||||
|
||||
return TRUE;
|
||||
|
||||
UNREFERENCED_PARAMETER(lpReserved);
|
||||
} /* LibMain */
|
||||
|
||||
int __stdcall DllMain(HANDLE hInst,DWORD ul_reason_being_called,LPVOID lpReserved)
|
||||
{
|
||||
return LibMain(hInst,ul_reason_being_called,lpReserved);
|
||||
}
|
||||
|
||||
#elif defined(WINDOWS)
|
||||
|
||||
/****************************************************************************
|
||||
** This routine is called by LIBSTART.ASM at module load time. All it
|
||||
** does in this sample is remember the DLL module handle. The module
|
||||
** handle is needed if you want to do things like load stuff from the
|
||||
** resource file (for instance string resources).
|
||||
****************************************************************************/
|
||||
|
||||
int _export FAR PASCAL libmain(HANDLE hModule,short cbHeapSize,
|
||||
UCHAR FAR *lszCmdLine)
|
||||
{
|
||||
s_hModule = hModule;
|
||||
libmysql_init();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif
|
82
libmysql/errmsg.c
Normal file
82
libmysql/errmsg.c
Normal file
@ -0,0 +1,82 @@
|
||||
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA */
|
||||
|
||||
/* Error messages for MySQL clients */
|
||||
/* error messages for the demon is in share/language/errmsg.sys */
|
||||
|
||||
#include <global.h>
|
||||
#include <my_sys.h>
|
||||
#include "errmsg.h"
|
||||
|
||||
#ifdef GERMAN
|
||||
const char *client_errors[]=
|
||||
{
|
||||
"Unbekannter MySQL Fehler",
|
||||
"Kann UNIX-Socket nicht anlegen (%d)",
|
||||
"Keine Verbindung zu lokalem MySQL Server, socket: '%-.64s' (%d)",
|
||||
"Keine Verbindung zu MySQL Server auf %-.64s (%d)",
|
||||
"Kann TCP/IP-Socket nicht anlegen (%d)",
|
||||
"Unbekannter MySQL Server Host (%-.64s) (%d)",
|
||||
"MySQL Server nicht vorhanden",
|
||||
"Protokolle ungleich. Server Version = % d Client Version = %d",
|
||||
"MySQL client got out of memory",
|
||||
"Wrong host info",
|
||||
"Localhost via UNIX socket",
|
||||
"%s via TCP/IP",
|
||||
"Error in server handshake",
|
||||
"Lost connection to MySQL server during query",
|
||||
"Commands out of sync; You can't run this command now",
|
||||
"Verbindung ueber Named Pipe; Host: %-.64s",
|
||||
"Kann nicht auf Named Pipe warten. Host: %-.64s pipe: %-.32s (%lu)",
|
||||
"Kann Named Pipe nicht oeffnen. Host: %-.64s pipe: %-.32s (%lu)",
|
||||
"Kann den Status der Named Pipe nicht setzen. Host: %-.64s pipe: %-.32s (%lu)",
|
||||
"Can't initialize character set %-.64s (path: %-.64s)",
|
||||
"Got packet bigger than 'max_allowed_packet'"
|
||||
};
|
||||
|
||||
#else /* ENGLISH */
|
||||
const char *client_errors[]=
|
||||
{
|
||||
"Unknown MySQL error",
|
||||
"Can't create UNIX socket (%d)",
|
||||
"Can't connect to local MySQL server through socket '%-.64s' (%d)",
|
||||
"Can't connect to MySQL server on '%-.64s' (%d)",
|
||||
"Can't create TCP/IP socket (%d)",
|
||||
"Unknown MySQL Server Host '%-.64s' (%d)",
|
||||
"MySQL server has gone away",
|
||||
"Protocol mismatch. Server Version = %d Client Version = %d",
|
||||
"MySQL client run out of memory",
|
||||
"Wrong host info",
|
||||
"Localhost via UNIX socket",
|
||||
"%s via TCP/IP",
|
||||
"Error in server handshake",
|
||||
"Lost connection to MySQL server during query",
|
||||
"Commands out of sync; You can't run this command now",
|
||||
"%s via named pipe",
|
||||
"Can't wait for named pipe to host: %-.64s pipe: %-.32s (%lu)",
|
||||
"Can't open named pipe to host: %-.64s pipe: %-.32s (%lu)",
|
||||
"Can't set state of named pipe to host: %-.64s pipe: %-.32s (%lu)",
|
||||
"Can't initialize character set %-.64s (path: %-.64s)",
|
||||
"Got packet bigger than 'max_allowed_packet'"
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
void init_client_errs(void)
|
||||
{
|
||||
errmsg[CLIENT_ERRMAP] = &client_errors[0];
|
||||
}
|
212
libmysql/get_password.c
Normal file
212
libmysql/get_password.c
Normal file
@ -0,0 +1,212 @@
|
||||
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA */
|
||||
|
||||
/*
|
||||
** Ask for a password from tty
|
||||
** This is an own file to avoid conflicts with curses
|
||||
*/
|
||||
#include <global.h>
|
||||
#include <my_sys.h>
|
||||
#include "mysql.h"
|
||||
#include <m_string.h>
|
||||
#include <m_ctype.h>
|
||||
#include <dbug.h>
|
||||
|
||||
#if defined(HAVE_BROKEN_GETPASS) && !defined(HAVE_GETPASSPHRASE)
|
||||
#undef HAVE_GETPASS
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETPASS
|
||||
#ifdef HAVE_PWD_H
|
||||
#include <pwd.h>
|
||||
#endif /* HAVE_PWD_H */
|
||||
#else /* ! HAVE_GETPASS */
|
||||
#ifndef __WIN__
|
||||
#include <sys/ioctl.h>
|
||||
#ifdef HAVE_TERMIOS_H /* For tty-password */
|
||||
#include <termios.h>
|
||||
#define TERMIO struct termios
|
||||
#else
|
||||
#ifdef HAVE_TERMIO_H /* For tty-password */
|
||||
#include <termio.h>
|
||||
#define TERMIO struct termio
|
||||
#else
|
||||
#include <sgtty.h>
|
||||
#define TERMIO struct sgttyb
|
||||
#endif
|
||||
#endif
|
||||
#ifdef alpha_linux_port
|
||||
#include <asm/ioctls.h> /* QQ; Fix this in configure */
|
||||
#include <asm/termiobits.h>
|
||||
#endif
|
||||
#else
|
||||
#include <conio.h>
|
||||
#endif /* __WIN__ */
|
||||
#endif /* HAVE_GETPASS */
|
||||
|
||||
#ifdef HAVE_GETPASSPHRASE /* For Solaris */
|
||||
#define getpass(A) getpassphrase(A)
|
||||
#endif
|
||||
|
||||
#ifdef __WIN__
|
||||
/* were just going to fake it here and get input from
|
||||
the keyboard */
|
||||
|
||||
char *get_tty_password(char *opt_message)
|
||||
{
|
||||
char to[80];
|
||||
char *pos=to,*end=to+sizeof(to)-1;
|
||||
int i=0;
|
||||
DBUG_ENTER("get_tty_password");
|
||||
fprintf(stdout,opt_message ? opt_message : "Enter password: ");
|
||||
for (;;)
|
||||
{
|
||||
char tmp;
|
||||
tmp=_getch();
|
||||
if (tmp == '\b' || (int) tmp == 127)
|
||||
{
|
||||
if (pos != to)
|
||||
{
|
||||
_cputs("\b \b");
|
||||
pos--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (tmp == '\n' || tmp == '\r' || tmp == 3)
|
||||
break;
|
||||
if (iscntrl(tmp) || pos == end)
|
||||
continue;
|
||||
_cputs("*");
|
||||
*(pos++) = tmp;
|
||||
}
|
||||
while (pos != to && isspace(pos[-1]) == ' ')
|
||||
pos--; /* Allow dummy space at end */
|
||||
*pos=0;
|
||||
_cputs("\n");
|
||||
DBUG_RETURN(my_strdup(to,MYF(MY_FAE)));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
||||
#ifndef HAVE_GETPASS
|
||||
/*
|
||||
** Can't use fgets, because readline will get confused
|
||||
** length is max number of chars in to, not counting \0
|
||||
* to will not include the eol characters.
|
||||
*/
|
||||
|
||||
static void get_password(char *to,uint length,int fd,bool echo)
|
||||
{
|
||||
char *pos=to,*end=to+length;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
char tmp;
|
||||
if (my_read(fd,&tmp,1,MYF(0)) != 1)
|
||||
break;
|
||||
if (tmp == '\b' || (int) tmp == 127)
|
||||
{
|
||||
if (pos != to)
|
||||
{
|
||||
if (echo)
|
||||
{
|
||||
fputs("\b \b",stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
pos--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (tmp == '\n' || tmp == '\r' || tmp == 3)
|
||||
break;
|
||||
if (iscntrl(tmp) || pos == end)
|
||||
continue;
|
||||
if (echo)
|
||||
{
|
||||
fputc('*',stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
*(pos++) = tmp;
|
||||
}
|
||||
while (pos != to && isspace(pos[-1]) == ' ')
|
||||
pos--; /* Allow dummy space at end */
|
||||
*pos=0;
|
||||
return;
|
||||
}
|
||||
#endif /* ! HAVE_GETPASS */
|
||||
|
||||
|
||||
char *get_tty_password(char *opt_message)
|
||||
{
|
||||
#ifdef HAVE_GETPASS
|
||||
char *passbuff;
|
||||
#else /* ! HAVE_GETPASS */
|
||||
TERMIO org,tmp;
|
||||
#endif /* HAVE_GETPASS */
|
||||
char buff[80];
|
||||
|
||||
DBUG_ENTER("get_tty_password");
|
||||
|
||||
#ifdef HAVE_GETPASS
|
||||
passbuff = getpass(opt_message ? opt_message : "Enter password: ");
|
||||
|
||||
/* copy the password to buff and clear original (static) buffer */
|
||||
strnmov(buff, passbuff, sizeof(buff) - 1);
|
||||
#ifdef _PASSWORD_LEN
|
||||
memset(passbuff, 0, _PASSWORD_LEN);
|
||||
#endif
|
||||
#else
|
||||
if (isatty(fileno(stdout)))
|
||||
{
|
||||
fputs(opt_message ? opt_message : "Enter password: ",stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
#if defined(HAVE_TERMIOS_H)
|
||||
tcgetattr(fileno(stdin), &org);
|
||||
tmp = org;
|
||||
tmp.c_lflag &= ~(ECHO | ISIG | ICANON);
|
||||
tmp.c_cc[VMIN] = 1;
|
||||
tmp.c_cc[VTIME] = 0;
|
||||
tcsetattr(fileno(stdin), TCSADRAIN, &tmp);
|
||||
get_password(buff, sizeof(buff)-1, fileno(stdin), isatty(fileno(stdout)));
|
||||
tcsetattr(fileno(stdin), TCSADRAIN, &org);
|
||||
#elif defined(HAVE_TERMIO_H)
|
||||
ioctl(fileno(stdin), (int) TCGETA, &org);
|
||||
tmp=org;
|
||||
tmp.c_lflag &= ~(ECHO | ISIG | ICANON);
|
||||
tmp.c_cc[VMIN] = 1;
|
||||
tmp.c_cc[VTIME]= 0;
|
||||
ioctl(fileno(stdin),(int) TCSETA, &tmp);
|
||||
get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stdout)));
|
||||
ioctl(fileno(stdin),(int) TCSETA, &org);
|
||||
#else
|
||||
gtty(fileno(stdin), &org);
|
||||
tmp=org;
|
||||
tmp.sg_flags &= ~ECHO;
|
||||
tmp.sg_flags |= RAW;
|
||||
stty(fileno(stdin), &tmp);
|
||||
get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stdout)));
|
||||
stty(fileno(stdin), &org);
|
||||
#endif
|
||||
if (isatty(fileno(stdout)))
|
||||
fputc('\n',stdout);
|
||||
#endif /* HAVE_GETPASS */
|
||||
|
||||
DBUG_RETURN(my_strdup(buff,MYF(MY_FAE)));
|
||||
}
|
||||
#endif /*__WIN__*/
|
2533
libmysql/libmysql.c
Normal file
2533
libmysql/libmysql.c
Normal file
File diff suppressed because it is too large
Load Diff
680
libmysql/net.c
Normal file
680
libmysql/net.c
Normal file
@ -0,0 +1,680 @@
|
||||
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA */
|
||||
|
||||
/* Write and read of logical packets to/from socket
|
||||
** Writes are cached into net_buffer_length big packets.
|
||||
** Read packets are reallocated dynamicly when reading big packets.
|
||||
** Each logical packet has the following pre-info:
|
||||
** 3 byte length & 1 byte package-number.
|
||||
*/
|
||||
|
||||
#ifdef __WIN__
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#include <global.h>
|
||||
#include <violite.h>
|
||||
#include <my_sys.h>
|
||||
#include <m_string.h>
|
||||
#include "mysql.h"
|
||||
#include "mysqld_error.h"
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <violite.h>
|
||||
|
||||
#ifdef MYSQL_SERVER
|
||||
ulong max_allowed_packet=65536;
|
||||
extern ulong net_read_timeout,net_write_timeout;
|
||||
extern uint test_flags;
|
||||
#else
|
||||
ulong max_allowed_packet=16*1024*1024L;
|
||||
ulong net_read_timeout= NET_READ_TIMEOUT;
|
||||
ulong net_write_timeout= NET_WRITE_TIMEOUT;
|
||||
#endif
|
||||
ulong net_buffer_length=8192; /* Default length. Enlarged if necessary */
|
||||
|
||||
#if !defined(__WIN__) && !defined(MSDOS)
|
||||
#include <sys/socket.h>
|
||||
#else
|
||||
#undef MYSQL_SERVER // Win32 can't handle interrupts
|
||||
#endif
|
||||
#if !defined(MSDOS) && !defined(__WIN__) && !defined(HAVE_BROKEN_NETINET_INCLUDES) && !defined(__BEOS__)
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip.h>
|
||||
#if !defined(alpha_linux_port)
|
||||
#include <netinet/tcp.h>
|
||||
#endif
|
||||
#endif
|
||||
#include "mysqld_error.h"
|
||||
#ifdef MYSQL_SERVER
|
||||
#include "my_pthread.h"
|
||||
#include "thr_alarm.h"
|
||||
void sql_print_error(const char *format,...);
|
||||
#define RETRY_COUNT mysqld_net_retry_count
|
||||
extern ulong mysqld_net_retry_count;
|
||||
#else
|
||||
typedef my_bool thr_alarm_t;
|
||||
typedef my_bool ALARM;
|
||||
#define thr_alarm_init(A) (*A)=0
|
||||
#define thr_alarm_in_use(A) (A)
|
||||
#define thr_end_alarm(A)
|
||||
#define thr_alarm(A,B,C) local_thr_alarm((A),(B),(C))
|
||||
static inline int local_thr_alarm(my_bool *A,int B __attribute__((unused)),ALARM *C __attribute__((unused)))
|
||||
{
|
||||
*A=1;
|
||||
return 0;
|
||||
}
|
||||
#define thr_got_alarm(A) 0
|
||||
#define RETRY_COUNT 1
|
||||
#endif
|
||||
|
||||
#ifdef MYSQL_SERVER
|
||||
extern ulong bytes_sent, bytes_received;
|
||||
extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received;
|
||||
#else
|
||||
#undef statistic_add
|
||||
#define statistic_add(A,B,C)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Give error if a too big packet is found
|
||||
** The server can change this with the -O switch, but because the client
|
||||
** can't normally do this the client should have a bigger max-buffer.
|
||||
*/
|
||||
|
||||
#define TEST_BLOCKING 8
|
||||
static int net_write_buff(NET *net,const char *packet,uint len);
|
||||
|
||||
|
||||
/* Init with packet info */
|
||||
|
||||
int my_net_init(NET *net, Vio* vio)
|
||||
{
|
||||
if (!(net->buff=(uchar*) my_malloc(net_buffer_length,MYF(MY_WME))))
|
||||
return 1;
|
||||
if (net_buffer_length > max_allowed_packet)
|
||||
max_allowed_packet=net_buffer_length;
|
||||
net->buff_end=net->buff+(net->max_packet=net_buffer_length);
|
||||
net->vio = vio;
|
||||
net->no_send_ok = 0;
|
||||
net->error=0; net->return_errno=0; net->return_status=0;
|
||||
net->timeout=(uint) net_read_timeout; /* Timeout for read */
|
||||
net->pkt_nr=0;
|
||||
net->write_pos=net->read_pos = net->buff;
|
||||
net->last_error[0]=0;
|
||||
net->compress=0; net->reading_or_writing=0;
|
||||
net->where_b = net->remain_in_buf=0;
|
||||
net->last_errno=0;
|
||||
|
||||
if (vio != 0) /* If real connection */
|
||||
{
|
||||
net->fd = vio_fd(vio); /* For perl DBI/DBD */
|
||||
#if defined(MYSQL_SERVER) && !defined(___WIN__) && !defined(__EMX__)
|
||||
if (!(test_flags & TEST_BLOCKING))
|
||||
vio_blocking(vio, FALSE);
|
||||
#endif
|
||||
vio_fastsend(vio,TRUE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void net_end(NET *net)
|
||||
{
|
||||
my_free((gptr) net->buff,MYF(MY_ALLOW_ZERO_PTR));
|
||||
net->buff=0;
|
||||
}
|
||||
|
||||
/* Realloc the packet buffer */
|
||||
|
||||
static my_bool net_realloc(NET *net, ulong length)
|
||||
{
|
||||
uchar *buff;
|
||||
ulong pkt_length;
|
||||
if (length >= max_allowed_packet)
|
||||
{
|
||||
DBUG_PRINT("error",("Packet too large (%lu)", length));
|
||||
net->error=1;
|
||||
net->last_errno=ER_NET_PACKET_TOO_LARGE;
|
||||
return 1;
|
||||
}
|
||||
pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
|
||||
if (!(buff=(uchar*) my_realloc((char*) net->buff, pkt_length, MYF(MY_WME))))
|
||||
{
|
||||
net->error=1;
|
||||
#ifdef MYSQL_SERVER
|
||||
net->last_errno=ER_OUT_OF_RESOURCES;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
net->buff=net->write_pos=buff;
|
||||
net->buff_end=buff+(net->max_packet=pkt_length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Remove unwanted characters from connection */
|
||||
|
||||
void net_clear(NET *net)
|
||||
{
|
||||
#ifndef EXTRA_DEBUG
|
||||
int count;
|
||||
bool is_blocking=vio_is_blocking(net->vio);
|
||||
if (is_blocking)
|
||||
vio_blocking(net->vio, FALSE);
|
||||
if (!vio_is_blocking(net->vio)) /* Safety if SSL */
|
||||
{
|
||||
while ( (count = vio_read(net->vio, (char*) (net->buff),
|
||||
net->max_packet)) > 0)
|
||||
DBUG_PRINT("info",("skipped %d bytes from file: %s",
|
||||
count,vio_description(net->vio)));
|
||||
if (is_blocking)
|
||||
vio_blocking(net->vio, TRUE);
|
||||
}
|
||||
#endif /* EXTRA_DEBUG */
|
||||
net->pkt_nr=0; /* Ready for new command */
|
||||
net->write_pos=net->buff;
|
||||
}
|
||||
|
||||
/* Flush write_buffer if not empty. */
|
||||
|
||||
int net_flush(NET *net)
|
||||
{
|
||||
int error=0;
|
||||
DBUG_ENTER("net_flush");
|
||||
if (net->buff != net->write_pos)
|
||||
{
|
||||
error=net_real_write(net,(char*) net->buff,
|
||||
(uint) (net->write_pos - net->buff));
|
||||
net->write_pos=net->buff;
|
||||
}
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Write something to server/client buffer
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
** Write a logical packet with packet header
|
||||
** Format: Packet length (3 bytes), packet number(1 byte)
|
||||
** When compression is used a 3 byte compression length is added
|
||||
** NOTE: If compression is used the original package is destroyed!
|
||||
*/
|
||||
|
||||
int
|
||||
my_net_write(NET *net,const char *packet,ulong len)
|
||||
{
|
||||
uchar buff[NET_HEADER_SIZE];
|
||||
int3store(buff,len);
|
||||
buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++);
|
||||
if (net_write_buff(net,(char*) buff,NET_HEADER_SIZE))
|
||||
return 1;
|
||||
return net_write_buff(net,packet,len);
|
||||
}
|
||||
|
||||
int
|
||||
net_write_command(NET *net,uchar command,const char *packet,ulong len)
|
||||
{
|
||||
uchar buff[NET_HEADER_SIZE+1];
|
||||
uint length=len+1; /* 1 extra byte for command */
|
||||
|
||||
int3store(buff,length);
|
||||
buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++);
|
||||
buff[4]=command;
|
||||
if (net_write_buff(net,(char*) buff,5))
|
||||
return 1;
|
||||
return test(net_write_buff(net,packet,len) || net_flush(net));
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
net_write_buff(NET *net,const char *packet,uint len)
|
||||
{
|
||||
uint left_length=(uint) (net->buff_end - net->write_pos);
|
||||
|
||||
while (len > left_length)
|
||||
{
|
||||
memcpy((char*) net->write_pos,packet,left_length);
|
||||
if (net_real_write(net,(char*) net->buff,net->max_packet))
|
||||
return 1;
|
||||
net->write_pos=net->buff;
|
||||
packet+=left_length;
|
||||
len-=left_length;
|
||||
left_length=net->max_packet;
|
||||
}
|
||||
memcpy((char*) net->write_pos,packet,len);
|
||||
net->write_pos+=len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read and write using timeouts */
|
||||
|
||||
int
|
||||
net_real_write(NET *net,const char *packet,ulong len)
|
||||
{
|
||||
int length;
|
||||
char *pos,*end;
|
||||
thr_alarm_t alarmed;
|
||||
#if (!defined(__WIN__) && !defined(__EMX__))
|
||||
ALARM alarm_buff;
|
||||
#endif
|
||||
uint retry_count=0;
|
||||
my_bool net_blocking = vio_is_blocking(net->vio);
|
||||
DBUG_ENTER("net_real_write");
|
||||
|
||||
if (net->error == 2)
|
||||
DBUG_RETURN(-1); /* socket can't be used */
|
||||
|
||||
net->reading_or_writing=2;
|
||||
#ifdef HAVE_COMPRESS
|
||||
if (net->compress)
|
||||
{
|
||||
ulong complen;
|
||||
uchar *b;
|
||||
uint header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE;
|
||||
if (!(b=(uchar*) my_malloc(len + NET_HEADER_SIZE + COMP_HEADER_SIZE,
|
||||
MYF(MY_WME))))
|
||||
{
|
||||
#ifdef MYSQL_SERVER
|
||||
net->last_errno=ER_OUT_OF_RESOURCES;
|
||||
net->error=2;
|
||||
#endif
|
||||
net->reading_or_writing=0;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
memcpy(b+header_length,packet,len);
|
||||
|
||||
if (my_compress((byte*) b+header_length,&len,&complen))
|
||||
{
|
||||
DBUG_PRINT("warning",
|
||||
("Compression error; Continuing without compression"));
|
||||
complen=0;
|
||||
}
|
||||
int3store(&b[NET_HEADER_SIZE],complen);
|
||||
int3store(b,len);
|
||||
b[3]=(uchar) (net->pkt_nr++);
|
||||
len+= header_length;
|
||||
packet= (char*) b;
|
||||
}
|
||||
#endif /* HAVE_COMPRESS */
|
||||
|
||||
/* DBUG_DUMP("net",packet,len); */
|
||||
#ifdef MYSQL_SERVER
|
||||
thr_alarm_init(&alarmed);
|
||||
if (net_blocking)
|
||||
thr_alarm(&alarmed,(uint) net_write_timeout,&alarm_buff);
|
||||
#else
|
||||
alarmed=0;
|
||||
#endif /* MYSQL_SERVER */
|
||||
|
||||
pos=(char*) packet; end=pos+len;
|
||||
while (pos != end)
|
||||
{
|
||||
if ((int) (length=vio_write(net->vio,pos,(size_t) (end-pos))) <= 0)
|
||||
{
|
||||
my_bool interrupted = vio_should_retry(net->vio);
|
||||
#if (!defined(__WIN__) && !defined(__EMX__))
|
||||
if ((interrupted || length==0) && !thr_alarm_in_use(alarmed))
|
||||
{
|
||||
if (!thr_alarm(&alarmed,(uint) net_write_timeout,&alarm_buff))
|
||||
{ /* Always true for client */
|
||||
if (!vio_is_blocking(net->vio))
|
||||
{
|
||||
while (vio_blocking(net->vio, TRUE) < 0)
|
||||
{
|
||||
if (vio_should_retry(net->vio) && retry_count++ < RETRY_COUNT)
|
||||
continue;
|
||||
#ifdef EXTRA_DEBUG
|
||||
fprintf(stderr,
|
||||
"%s: my_net_write: fcntl returned error %d, aborting thread\n",
|
||||
my_progname,vio_errno(net->vio));
|
||||
#endif /* EXTRA_DEBUG */
|
||||
net->error=2; /* Close socket */
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
retry_count=0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* (!defined(__WIN__) && !defined(__EMX__)) */
|
||||
if (thr_alarm_in_use(alarmed) && !thr_got_alarm(alarmed) &&
|
||||
interrupted)
|
||||
{
|
||||
if (retry_count++ < RETRY_COUNT)
|
||||
continue;
|
||||
#ifdef EXTRA_DEBUG
|
||||
fprintf(stderr, "%s: write looped, aborting thread\n",
|
||||
my_progname);
|
||||
#endif /* EXTRA_DEBUG */
|
||||
}
|
||||
#if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER)
|
||||
if (vio_errno(net->vio) == EINTR)
|
||||
{
|
||||
DBUG_PRINT("warning",("Interrupted write. Retrying..."));
|
||||
continue;
|
||||
}
|
||||
#endif /* defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) */
|
||||
net->error=2; /* Close socket */
|
||||
#ifdef MYSQL_SERVER
|
||||
net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED :
|
||||
ER_NET_ERROR_ON_WRITE);
|
||||
#endif /* MYSQL_SERVER */
|
||||
break;
|
||||
}
|
||||
pos+=length;
|
||||
statistic_add(bytes_sent,length,&LOCK_bytes_sent);
|
||||
}
|
||||
#ifndef __WIN__
|
||||
end:
|
||||
#endif
|
||||
#ifdef HAVE_COMPRESS
|
||||
if (net->compress)
|
||||
my_free((char*) packet,MYF(0));
|
||||
#endif
|
||||
if (thr_alarm_in_use(alarmed))
|
||||
{
|
||||
thr_end_alarm(&alarmed);
|
||||
vio_blocking(net->vio, net_blocking);
|
||||
}
|
||||
net->reading_or_writing=0;
|
||||
DBUG_RETURN(((int) (pos != end)));
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Read something from server/clinet
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef MYSQL_SERVER
|
||||
|
||||
/*
|
||||
Help function to clear the commuication buffer when we get a too
|
||||
big packet
|
||||
*/
|
||||
|
||||
static void my_net_skip_rest(NET *net, ulong remain, thr_alarm_t *alarmed)
|
||||
{
|
||||
char buff[1024];
|
||||
ALARM alarm_buff;
|
||||
uint retry_count=0;
|
||||
if (!thr_alarm_in_use(alarmed))
|
||||
{
|
||||
if (!thr_alarm(alarmed,net->timeout,&alarm_buff) ||
|
||||
(!vio_is_blocking(net->vio) && vio_blocking(net->vio,TRUE) < 0))
|
||||
return; // Can't setup, abort
|
||||
}
|
||||
while (remain > 0)
|
||||
{
|
||||
ulong length;
|
||||
if ((int) (length=vio_read(net->vio,(char*) net->buff,remain)) <= 0L)
|
||||
{
|
||||
my_bool interrupted = vio_should_retry(net->vio);
|
||||
if (!thr_got_alarm(alarmed) && interrupted)
|
||||
{ /* Probably in MIT threads */
|
||||
if (retry_count++ < RETRY_COUNT)
|
||||
continue;
|
||||
}
|
||||
return;
|
||||
}
|
||||
remain -=(ulong) length;
|
||||
statistic_add(bytes_received,(ulong) length,&LOCK_bytes_received);
|
||||
}
|
||||
}
|
||||
#endif /* MYSQL_SERVER */
|
||||
|
||||
|
||||
static uint
|
||||
my_real_read(NET *net, ulong *complen)
|
||||
{
|
||||
uchar *pos;
|
||||
long length;
|
||||
uint i,retry_count=0;
|
||||
ulong len=packet_error;
|
||||
thr_alarm_t alarmed;
|
||||
#if (!defined(__WIN__) && !defined(__EMX__)) || defined(MYSQL_SERVER)
|
||||
ALARM alarm_buff;
|
||||
#endif
|
||||
my_bool net_blocking=vio_is_blocking(net->vio);
|
||||
ulong remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE :
|
||||
NET_HEADER_SIZE);
|
||||
*complen = 0;
|
||||
|
||||
net->reading_or_writing=1;
|
||||
thr_alarm_init(&alarmed);
|
||||
#ifdef MYSQL_SERVER
|
||||
if (net_blocking)
|
||||
thr_alarm(&alarmed,net->timeout,&alarm_buff);
|
||||
#endif /* MYSQL_SERVER */
|
||||
|
||||
pos = net->buff + net->where_b; /* net->packet -4 */
|
||||
for (i=0 ; i < 2 ; i++)
|
||||
{
|
||||
while (remain > 0)
|
||||
{
|
||||
/* First read is done with non blocking mode */
|
||||
if ((int) (length=vio_read(net->vio,(char*) pos,remain)) <= 0L)
|
||||
{
|
||||
my_bool interrupted = vio_should_retry(net->vio);
|
||||
|
||||
DBUG_PRINT("info",("vio_read returned %d, errno: %d",
|
||||
length, vio_errno(net->vio)));
|
||||
#if (!defined(__WIN__) && !defined(__EMX__)) || defined(MYSQL_SERVER)
|
||||
/*
|
||||
We got an error that there was no data on the socket. We now set up
|
||||
an alarm to not 'read forever', change the socket to non blocking
|
||||
mode and try again
|
||||
*/
|
||||
if ((interrupted || length == 0) && !thr_alarm_in_use(alarmed))
|
||||
{
|
||||
if (!thr_alarm(&alarmed,net->timeout,&alarm_buff)) /* Don't wait too long */
|
||||
{
|
||||
if (!vio_is_blocking(net->vio))
|
||||
{
|
||||
while (vio_blocking(net->vio,TRUE) < 0)
|
||||
{
|
||||
if (vio_should_retry(net->vio) &&
|
||||
retry_count++ < RETRY_COUNT)
|
||||
continue;
|
||||
DBUG_PRINT("error",
|
||||
("fcntl returned error %d, aborting thread",
|
||||
vio_errno(net->vio)));
|
||||
#ifdef EXTRA_DEBUG
|
||||
fprintf(stderr,
|
||||
"%s: read: fcntl returned error %d, aborting thread\n",
|
||||
my_progname,vio_errno(net->vio));
|
||||
#endif /* EXTRA_DEBUG */
|
||||
len= packet_error;
|
||||
net->error=2; /* Close socket */
|
||||
#ifdef MYSQL_SERVER
|
||||
net->last_errno=ER_NET_FCNTL_ERROR;
|
||||
#endif
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
retry_count=0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif /* (!defined(__WIN__) && !defined(__EMX__)) || defined(MYSQL_SERVER) */
|
||||
if (thr_alarm_in_use(alarmed) && !thr_got_alarm(alarmed) &&
|
||||
interrupted)
|
||||
{ /* Probably in MIT threads */
|
||||
if (retry_count++ < RETRY_COUNT)
|
||||
continue;
|
||||
#ifdef EXTRA_DEBUG
|
||||
fprintf(stderr, "%s: read looped with error %d, aborting thread\n",
|
||||
my_progname,vio_errno(net->vio));
|
||||
#endif /* EXTRA_DEBUG */
|
||||
}
|
||||
#if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER)
|
||||
if (vio_should_retry(net->vio))
|
||||
{
|
||||
DBUG_PRINT("warning",("Interrupted read. Retrying..."));
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
DBUG_PRINT("error",("Couldn't read packet: remain: %d errno: %d length: %d alarmed: %d", remain,vio_errno(net->vio),length,alarmed));
|
||||
len= packet_error;
|
||||
net->error=2; /* Close socket */
|
||||
#ifdef MYSQL_SERVER
|
||||
net->last_errno= (interrupted ? ER_NET_READ_INTERRUPTED :
|
||||
ER_NET_READ_ERROR);
|
||||
#endif
|
||||
goto end;
|
||||
}
|
||||
remain -= (ulong) length;
|
||||
pos+= (ulong) length;
|
||||
statistic_add(bytes_received,(ulong) length,&LOCK_bytes_received);
|
||||
}
|
||||
if (i == 0)
|
||||
{ /* First parts is packet length */
|
||||
ulong helping;
|
||||
if (net->buff[net->where_b + 3] != (uchar) net->pkt_nr)
|
||||
{
|
||||
if (net->buff[net->where_b] != (uchar) 255)
|
||||
{
|
||||
DBUG_PRINT("error",
|
||||
("Packets out of order (Found: %d, expected %d)",
|
||||
(int) net->buff[net->where_b + 3],
|
||||
(uint) (uchar) net->pkt_nr));
|
||||
#ifdef EXTRA_DEBUG
|
||||
fprintf(stderr,"Packets out of order (Found: %d, expected %d)\n",
|
||||
(int) net->buff[net->where_b + 3],
|
||||
(uint) (uchar) net->pkt_nr);
|
||||
#endif
|
||||
}
|
||||
len= packet_error;
|
||||
#ifdef MYSQL_SERVER
|
||||
net->last_errno=ER_NET_PACKETS_OUT_OF_ORDER;
|
||||
#endif
|
||||
goto end;
|
||||
}
|
||||
net->pkt_nr++;
|
||||
#ifdef HAVE_COMPRESS
|
||||
if (net->compress)
|
||||
{
|
||||
/* complen is > 0 if package is really compressed */
|
||||
*complen=uint3korr(&(net->buff[net->where_b + NET_HEADER_SIZE]));
|
||||
}
|
||||
#endif
|
||||
|
||||
len=uint3korr(net->buff+net->where_b);
|
||||
helping = max(len,*complen) + net->where_b;
|
||||
/* The necessary size of net->buff */
|
||||
if (helping >= net->max_packet)
|
||||
{
|
||||
/* We must allocate one extra byte for the end null */
|
||||
if (net_realloc(net,helping+1))
|
||||
{
|
||||
#ifdef MYSQL_SERVER
|
||||
if (i == 1)
|
||||
my_net_skip_rest(net, len, &alarmed);
|
||||
#endif
|
||||
len= packet_error; /* Return error */
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
pos=net->buff + net->where_b;
|
||||
remain = len;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
if (thr_alarm_in_use(alarmed))
|
||||
{
|
||||
thr_end_alarm(&alarmed);
|
||||
vio_blocking(net->vio, net_blocking);
|
||||
}
|
||||
net->reading_or_writing=0;
|
||||
return(len);
|
||||
}
|
||||
|
||||
uint
|
||||
my_net_read(NET *net)
|
||||
{
|
||||
ulong len,complen;
|
||||
|
||||
#ifdef HAVE_COMPRESS
|
||||
if (!net->compress)
|
||||
{
|
||||
#endif
|
||||
len = my_real_read (net,&complen);
|
||||
net->read_pos = net->buff + net->where_b;
|
||||
if (len != packet_error)
|
||||
net->read_pos[len]=0; /* Safeguard for mysql_use_result */
|
||||
return len;
|
||||
#ifdef HAVE_COMPRESS
|
||||
}
|
||||
if (net->remain_in_buf)
|
||||
net->buff[net->buf_length - net->remain_in_buf]=net->save_char;
|
||||
for (;;)
|
||||
{
|
||||
if (net->remain_in_buf)
|
||||
{
|
||||
uchar *pos = net->buff + net->buf_length - net->remain_in_buf;
|
||||
if (net->remain_in_buf >= 4)
|
||||
{
|
||||
net->length = uint3korr(pos);
|
||||
if (net->length <= net->remain_in_buf - 4)
|
||||
{
|
||||
/* We have a full packet */
|
||||
len=net->length;
|
||||
net->remain_in_buf -= net->length + 4;
|
||||
net->read_pos=pos + 4;
|
||||
break; /* We have a full packet */
|
||||
}
|
||||
}
|
||||
/* Move data down to read next data packet after current one */
|
||||
if (net->buf_length != net->remain_in_buf)
|
||||
{
|
||||
memmove(net->buff,pos,net->remain_in_buf);
|
||||
net->buf_length=net->remain_in_buf;
|
||||
}
|
||||
net->where_b=net->buf_length;
|
||||
}
|
||||
else
|
||||
{
|
||||
net->where_b=0;
|
||||
net->buf_length=0;
|
||||
}
|
||||
|
||||
if ((len = my_real_read(net,&complen)) == packet_error)
|
||||
break;
|
||||
if (my_uncompress((byte*) net->buff + net->where_b, &len, &complen))
|
||||
{
|
||||
len= packet_error;
|
||||
net->error=2; /* caller will close socket */
|
||||
#ifdef MYSQL_SERVER
|
||||
net->last_errno=ER_NET_UNCOMPRESS_ERROR;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
net->buf_length+=len;
|
||||
net->remain_in_buf+=len;
|
||||
}
|
||||
if (len != packet_error)
|
||||
{
|
||||
net->save_char= net->read_pos[len]; /* Must be saved */
|
||||
net->read_pos[len]=0; /* Safeguard for mysql_use_result */
|
||||
}
|
||||
return len;
|
||||
#endif
|
||||
}
|
192
libmysql/password.c
Normal file
192
libmysql/password.c
Normal file
@ -0,0 +1,192 @@
|
||||
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA */
|
||||
|
||||
/* password checking routines */
|
||||
/*****************************************************************************
|
||||
The main idea is that no password are sent between client & server on
|
||||
connection and that no password are saved in mysql in a decodable form.
|
||||
|
||||
On connection a random string is generated and sent to the client.
|
||||
The client generates a new string with a random generator inited with
|
||||
the hash values from the password and the sent string.
|
||||
This 'check' string is sent to the server where it is compared with
|
||||
a string generated from the stored hash_value of the password and the
|
||||
random string.
|
||||
|
||||
The password is saved (in user.password) by using the PASSWORD() function in
|
||||
mysql.
|
||||
|
||||
Example:
|
||||
update user set password=PASSWORD("hello") where user="test"
|
||||
This saves a hashed number as a string in the password field.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <global.h>
|
||||
#include <my_sys.h>
|
||||
#include <m_string.h>
|
||||
#include "mysql.h"
|
||||
|
||||
|
||||
void randominit(struct rand_struct *rand_st,ulong seed1, ulong seed2)
|
||||
{ /* For mysql 3.21.# */
|
||||
#ifdef HAVE_purify
|
||||
bzero((char*) rand_st,sizeof(*rand_st)); /* Avoid UMC varnings */
|
||||
#endif
|
||||
rand_st->max_value= 0x3FFFFFFFL;
|
||||
rand_st->max_value_dbl=(double) rand_st->max_value;
|
||||
rand_st->seed1=seed1%rand_st->max_value ;
|
||||
rand_st->seed2=seed2%rand_st->max_value;
|
||||
}
|
||||
|
||||
static void old_randominit(struct rand_struct *rand_st,ulong seed1)
|
||||
{ /* For mysql 3.20.# */
|
||||
rand_st->max_value= 0x01FFFFFFL;
|
||||
rand_st->max_value_dbl=(double) rand_st->max_value;
|
||||
seed1%=rand_st->max_value;
|
||||
rand_st->seed1=seed1 ; rand_st->seed2=seed1/2;
|
||||
}
|
||||
|
||||
double rnd(struct rand_struct *rand_st)
|
||||
{
|
||||
rand_st->seed1=(rand_st->seed1*3+rand_st->seed2) % rand_st->max_value;
|
||||
rand_st->seed2=(rand_st->seed1+rand_st->seed2+33) % rand_st->max_value;
|
||||
return (((double) rand_st->seed1)/rand_st->max_value_dbl);
|
||||
}
|
||||
|
||||
void hash_password(ulong *result, const char *password)
|
||||
{
|
||||
register ulong nr=1345345333L, add=7, nr2=0x12345671L;
|
||||
ulong tmp;
|
||||
for (; *password ; password++)
|
||||
{
|
||||
if (*password == ' ' || *password == '\t')
|
||||
continue; /* skipp space in password */
|
||||
tmp= (ulong) (uchar) *password;
|
||||
nr^= (((nr & 63)+add)*tmp)+ (nr << 8);
|
||||
nr2+=(nr2 << 8) ^ nr;
|
||||
add+=tmp;
|
||||
}
|
||||
result[0]=nr & (((ulong) 1L << 31) -1L); /* Don't use sign bit (str2int) */;
|
||||
result[1]=nr2 & (((ulong) 1L << 31) -1L);
|
||||
return;
|
||||
}
|
||||
|
||||
void make_scrambled_password(char *to,const char *password)
|
||||
{
|
||||
ulong hash_res[2];
|
||||
hash_password(hash_res,password);
|
||||
sprintf(to,"%08lx%08lx",hash_res[0],hash_res[1]);
|
||||
}
|
||||
|
||||
static inline uint char_val(char X)
|
||||
{
|
||||
return (uint) (X >= '0' && X <= '9' ? X-'0' :
|
||||
X >= 'A' && X <= 'Z' ? X-'A'+10 :
|
||||
X-'a'+10);
|
||||
}
|
||||
|
||||
/*
|
||||
** This code assumes that len(password) is divideable with 8 and that
|
||||
** res is big enough (2 in mysql)
|
||||
*/
|
||||
|
||||
void get_salt_from_password(ulong *res,const char *password)
|
||||
{
|
||||
res[0]=res[1]=0;
|
||||
if (password)
|
||||
{
|
||||
while (*password)
|
||||
{
|
||||
ulong val=0;
|
||||
uint i;
|
||||
for (i=0 ; i < 8 ; i++)
|
||||
val=(val << 4)+char_val(*password++);
|
||||
*res++=val;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void make_password_from_salt(char *to, ulong *hash_res)
|
||||
{
|
||||
sprintf(to,"%08lx%08lx",hash_res[0],hash_res[1]);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Genererate a new message based on message and password
|
||||
* The same thing is done in client and server and the results are checked.
|
||||
*/
|
||||
|
||||
char *scramble(char *to,const char *message,const char *password,
|
||||
my_bool old_ver)
|
||||
{
|
||||
struct rand_struct rand_st;
|
||||
ulong hash_pass[2],hash_message[2];
|
||||
if (password && password[0])
|
||||
{
|
||||
char *to_start=to;
|
||||
hash_password(hash_pass,password);
|
||||
hash_password(hash_message,message);
|
||||
if (old_ver)
|
||||
old_randominit(&rand_st,hash_pass[0] ^ hash_message[0]);
|
||||
else
|
||||
randominit(&rand_st,hash_pass[0] ^ hash_message[0],
|
||||
hash_pass[1] ^ hash_message[1]);
|
||||
while (*message++)
|
||||
*to++= (char) (floor(rnd(&rand_st)*31)+64);
|
||||
if (!old_ver)
|
||||
{ /* Make it harder to break */
|
||||
char extra=(char) (floor(rnd(&rand_st)*31));
|
||||
while (to_start != to)
|
||||
*(to_start++)^=extra;
|
||||
}
|
||||
}
|
||||
*to=0;
|
||||
return to;
|
||||
}
|
||||
|
||||
|
||||
my_bool check_scramble(const char *scrambled, const char *message,
|
||||
ulong *hash_pass, my_bool old_ver)
|
||||
{
|
||||
struct rand_struct rand_st;
|
||||
ulong hash_message[2];
|
||||
char buff[16],*to,extra; /* Big enough for check */
|
||||
const char *pos;
|
||||
|
||||
hash_password(hash_message,message);
|
||||
if (old_ver)
|
||||
old_randominit(&rand_st,hash_pass[0] ^ hash_message[0]);
|
||||
else
|
||||
randominit(&rand_st,hash_pass[0] ^ hash_message[0],
|
||||
hash_pass[1] ^ hash_message[1]);
|
||||
to=buff;
|
||||
for (pos=scrambled ; *pos ; pos++)
|
||||
*to++=(char) (floor(rnd(&rand_st)*31)+64);
|
||||
if (old_ver)
|
||||
extra=0;
|
||||
else
|
||||
extra=(char) (floor(rnd(&rand_st)*31));
|
||||
to=buff;
|
||||
while (*scrambled)
|
||||
{
|
||||
if (*scrambled++ != (char) (*to++ ^ extra))
|
||||
return 1; /* Wrong password */
|
||||
}
|
||||
return 0;
|
||||
}
|
400
libmysql/violite.c
Normal file
400
libmysql/violite.c
Normal file
@ -0,0 +1,400 @@
|
||||
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA */
|
||||
|
||||
/*
|
||||
Note that we can't have assertion on file descriptors; The reason for
|
||||
this is that during mysql shutdown, another thread can close a file
|
||||
we are working on. In this case we should just return read errors from
|
||||
the file descriptior.
|
||||
*/
|
||||
|
||||
#include <global.h>
|
||||
|
||||
#ifndef HAVE_VIO /* is Vio suppored by the Vio lib ? */
|
||||
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <violite.h>
|
||||
#include <my_sys.h>
|
||||
#include <my_net.h>
|
||||
#include <m_string.h>
|
||||
|
||||
#if defined(__EMX__)
|
||||
#include <sys/ioctl.h>
|
||||
#define ioctlsocket(A,B,C) ioctl((A),(B),(void *)(C),sizeof(*(C)))
|
||||
#undef HAVE_FCNTL
|
||||
#endif /* defined(__EMX__) */
|
||||
|
||||
#if defined(MSDOS) || defined(__WIN__)
|
||||
#ifdef __WIN__
|
||||
#undef errno
|
||||
#undef EINTR
|
||||
#undef EAGAIN
|
||||
#define errno WSAGetLastError()
|
||||
#define EINTR WSAEINTR
|
||||
#define EAGAIN WSAEINPROGRESS
|
||||
#endif /* __WIN__ */
|
||||
#define O_NONBLOCK 1 /* For emulation of fcntl() */
|
||||
#endif
|
||||
#ifndef EWOULDBLOCK
|
||||
#define EWOULDBLOCK EAGAIN
|
||||
#endif
|
||||
|
||||
#ifndef __WIN__
|
||||
#define HANDLE void *
|
||||
#endif
|
||||
|
||||
struct st_vio
|
||||
{
|
||||
my_socket sd; /* my_socket - real or imaginary */
|
||||
HANDLE hPipe;
|
||||
my_bool localhost; /* Are we from localhost? */
|
||||
int fcntl_mode; /* Buffered fcntl(sd,F_GETFL) */
|
||||
struct sockaddr_in local; /* Local internet address */
|
||||
struct sockaddr_in remote; /* Remote internet address */
|
||||
enum enum_vio_type type; /* Type of connection */
|
||||
char desc[30]; /* String description */
|
||||
};
|
||||
|
||||
typedef void *vio_ptr;
|
||||
typedef char *vio_cstring;
|
||||
|
||||
/*
|
||||
* Helper to fill most of the Vio* with defaults.
|
||||
*/
|
||||
|
||||
static void vio_reset(Vio* vio, enum enum_vio_type type,
|
||||
my_socket sd, HANDLE hPipe,
|
||||
my_bool localhost)
|
||||
{
|
||||
bzero((char*) vio, sizeof(*vio));
|
||||
vio->type = type;
|
||||
vio->sd = sd;
|
||||
vio->hPipe = hPipe;
|
||||
vio->localhost= localhost;
|
||||
}
|
||||
|
||||
/* Open the socket or TCP/IP connection and read the fnctl() status */
|
||||
|
||||
Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost)
|
||||
{
|
||||
Vio *vio;
|
||||
DBUG_ENTER("vio_new");
|
||||
DBUG_PRINT("enter", ("sd=%d", sd));
|
||||
if ((vio = (Vio*) my_malloc(sizeof(*vio),MYF(MY_WME))))
|
||||
{
|
||||
vio_reset(vio, type, sd, 0, localhost);
|
||||
sprintf(vio->desc, "socket (%d)", vio->sd);
|
||||
#if !defined(___WIN__) && !defined(__EMX__)
|
||||
#if !defined(NO_FCNTL_NONBLOCK)
|
||||
vio->fcntl_mode = fcntl(sd, F_GETFL);
|
||||
#endif
|
||||
#else /* !defined(__WIN__) && !defined(__EMX__) */
|
||||
{
|
||||
/* set to blocking mode by default */
|
||||
ulong arg=0;
|
||||
r = ioctlsocket(vio->sd,FIONBIO,(void*) &arg, sizeof(arg));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
DBUG_RETURN(vio);
|
||||
}
|
||||
|
||||
|
||||
#ifdef __WIN__
|
||||
|
||||
Vio *vio_new_win32pipe(HANDLE hPipe)
|
||||
{
|
||||
Vio *vio;
|
||||
DBUG_ENTER("vio_new_handle");
|
||||
if ((vio = (Vio*) my_malloc(sizeof(Vio),MYF(MY_WME))))
|
||||
{
|
||||
vio_reset(vio, VIO_TYPE_NAMEDPIPE, 0, hPipe, TRUE);
|
||||
strmov(vio->desc, "named pipe");
|
||||
}
|
||||
DBUG_RETURN(vio);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void vio_delete(Vio * vio)
|
||||
{
|
||||
/* It must be safe to delete null pointers. */
|
||||
/* This matches the semantics of C++'s delete operator. */
|
||||
if (vio)
|
||||
{
|
||||
if (vio->type != VIO_CLOSED)
|
||||
vio_close(vio);
|
||||
my_free((gptr) vio,MYF(0));
|
||||
}
|
||||
}
|
||||
|
||||
int vio_errno(Vio *vio __attribute__((unused)))
|
||||
{
|
||||
return errno; /* On Win32 this mapped to WSAGetLastError() */
|
||||
}
|
||||
|
||||
|
||||
int vio_read(Vio * vio, gptr buf, int size)
|
||||
{
|
||||
int r;
|
||||
DBUG_ENTER("vio_read");
|
||||
DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d", vio->sd, buf, size));
|
||||
#ifdef __WIN__
|
||||
if (vio->type == VIO_TYPE_NAMEDPIPE)
|
||||
{
|
||||
DWORD length;
|
||||
if (!ReadFile(vio->hPipe, buf, size, &length, NULL))
|
||||
DBUG_RETURN(-1);
|
||||
DBUG_RETURN(length);
|
||||
}
|
||||
r = recv(vio->sd, buf, size,0);
|
||||
#else
|
||||
errno=0; /* For linux */
|
||||
r = read(vio->sd, buf, size);
|
||||
#endif /* __WIN__ */
|
||||
#ifndef DBUG_OFF
|
||||
if (r < 0)
|
||||
{
|
||||
DBUG_PRINT("error", ("Got error %d during read",errno));
|
||||
}
|
||||
#endif /* DBUG_OFF */
|
||||
DBUG_PRINT("exit", ("%d", r));
|
||||
DBUG_RETURN(r);
|
||||
}
|
||||
|
||||
|
||||
int vio_write(Vio * vio, const gptr buf, int size)
|
||||
{
|
||||
int r;
|
||||
DBUG_ENTER("vio_write");
|
||||
DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d", vio->sd, buf, size));
|
||||
#ifdef __WIN__
|
||||
if ( vio->type == VIO_TYPE_NAMEDPIPE)
|
||||
{
|
||||
DWORD length;
|
||||
if (!WriteFile(vio->hPipe, (char*) buf, size, &length, NULL))
|
||||
DBUG_RETURN(-1);
|
||||
DBUG_RETURN(length);
|
||||
}
|
||||
r = send(vio->sd, buf, size,0);
|
||||
#else
|
||||
r = write(vio->sd, buf, size);
|
||||
#endif /* __WIN__ */
|
||||
#ifndef DBUG_OFF
|
||||
if (r < 0)
|
||||
{
|
||||
DBUG_PRINT("error", ("Got error on write: %d",errno));
|
||||
}
|
||||
#endif /* DBUG_OFF */
|
||||
DBUG_PRINT("exit", ("%d", r));
|
||||
DBUG_RETURN(r);
|
||||
}
|
||||
|
||||
|
||||
int vio_blocking(Vio * vio, my_bool set_blocking_mode)
|
||||
{
|
||||
int r=0;
|
||||
DBUG_ENTER("vio_blocking");
|
||||
DBUG_PRINT("enter", ("set_blocking_mode: %d", (int) set_blocking_mode));
|
||||
|
||||
#if !defined(___WIN__) && !defined(__EMX__)
|
||||
#if !defined(NO_FCNTL_NONBLOCK)
|
||||
|
||||
if (vio->sd >= 0)
|
||||
{
|
||||
int old_fcntl=vio->fcntl_mode;
|
||||
if (set_blocking_mode)
|
||||
vio->fcntl_mode &= ~O_NONBLOCK; /* clear bit */
|
||||
else
|
||||
vio->fcntl_mode |= O_NONBLOCK; /* set bit */
|
||||
if (old_fcntl != vio->fcntl_mode)
|
||||
r = fcntl(vio->sd, F_SETFL, vio->fcntl_mode);
|
||||
}
|
||||
#endif /* !defined(NO_FCNTL_NONBLOCK) */
|
||||
#else /* !defined(__WIN__) && !defined(__EMX__) */
|
||||
#ifndef __EMX__
|
||||
if (vio->type != VIO_TYPE_NAMEDPIPE)
|
||||
#endif
|
||||
{
|
||||
ulong arg;
|
||||
int old_fcntl=vio->fcntl_mode;
|
||||
if (set_blocking_mode)
|
||||
{
|
||||
arg = 0;
|
||||
vio->fcntl_mode &= ~O_NONBLOCK; /* clear bit */
|
||||
}
|
||||
else
|
||||
{
|
||||
arg = 1;
|
||||
vio->fcntl_mode |= O_NONBLOCK; /* set bit */
|
||||
}
|
||||
if (old_fcntl != vio->fcntl_mode)
|
||||
r = ioctlsocket(vio->sd,FIONBIO,(void*) &arg, sizeof(arg));
|
||||
}
|
||||
#endif /* !defined(__WIN__) && !defined(__EMX__) */
|
||||
DBUG_RETURN(r);
|
||||
}
|
||||
|
||||
my_bool
|
||||
vio_is_blocking(Vio * vio)
|
||||
{
|
||||
my_bool r;
|
||||
DBUG_ENTER("vio_is_blocking");
|
||||
r = !(vio->fcntl_mode & O_NONBLOCK);
|
||||
DBUG_PRINT("exit", ("%d", (int) r));
|
||||
DBUG_RETURN(r);
|
||||
}
|
||||
|
||||
|
||||
int vio_fastsend(Vio * vio, my_bool onoff)
|
||||
{
|
||||
int r=0;
|
||||
DBUG_ENTER("vio_fastsend");
|
||||
DBUG_PRINT("enter", ("onoff:%d", (int) onoff));
|
||||
|
||||
#ifdef IPTOS_THROUGHPUT
|
||||
{
|
||||
#ifndef __EMX__
|
||||
int tos = IPTOS_THROUGHPUT;
|
||||
if (!setsockopt(vio->sd, IPPROTO_IP, IP_TOS, (void *) &tos, sizeof(tos)))
|
||||
#endif /* !__EMX__ */
|
||||
{
|
||||
int nodelay = 1;
|
||||
if (setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY, (void *) &nodelay,
|
||||
sizeof(nodelay))) {
|
||||
DBUG_PRINT("warning",
|
||||
("Couldn't set socket option for fast send"));
|
||||
r= -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* IPTOS_THROUGHPUT */
|
||||
DBUG_PRINT("exit", ("%d", r));
|
||||
DBUG_RETURN(r);
|
||||
}
|
||||
|
||||
int vio_keepalive(Vio* vio, my_bool set_keep_alive)
|
||||
{
|
||||
int r=0;
|
||||
uint opt = 0;
|
||||
DBUG_ENTER("vio_keepalive");
|
||||
DBUG_PRINT("enter", ("sd=%d, set_keep_alive=%d", vio->sd, (int)
|
||||
set_keep_alive));
|
||||
if (vio->type != VIO_TYPE_NAMEDPIPE)
|
||||
{
|
||||
if (set_keep_alive)
|
||||
opt = 1;
|
||||
r = setsockopt(vio->sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt,
|
||||
sizeof(opt));
|
||||
}
|
||||
DBUG_RETURN(r);
|
||||
}
|
||||
|
||||
|
||||
my_bool
|
||||
vio_should_retry(Vio * vio __attribute__((unused)))
|
||||
{
|
||||
int en = errno;
|
||||
return en == EAGAIN || en == EINTR || en == EWOULDBLOCK;
|
||||
}
|
||||
|
||||
|
||||
int vio_close(Vio * vio)
|
||||
{
|
||||
int r;
|
||||
DBUG_ENTER("vio_close");
|
||||
#ifdef __WIN__
|
||||
if (vio->type == VIO_TYPE_NAMEDPIPE)
|
||||
{
|
||||
#if defined(__NT__) && defined(MYSQL_SERVER)
|
||||
CancelIO(vio->hPipe);
|
||||
DisconnectNamedPipe(vio->hPipe);
|
||||
#endif
|
||||
r=CloseHandle(vio->hPipe);
|
||||
}
|
||||
else if (vio->type != VIO_CLOSED)
|
||||
#endif /* __WIN__ */
|
||||
{
|
||||
r=0;
|
||||
if (shutdown(vio->sd,2))
|
||||
r= -1;
|
||||
if (closesocket(vio->sd))
|
||||
r= -1;
|
||||
}
|
||||
if (r)
|
||||
{
|
||||
DBUG_PRINT("error", ("close() failed, error: %d",errno));
|
||||
/* FIXME: error handling (not critical for MySQL) */
|
||||
}
|
||||
vio->type= VIO_CLOSED;
|
||||
vio->sd= -1;
|
||||
DBUG_RETURN(r);
|
||||
}
|
||||
|
||||
|
||||
const char *vio_description(Vio * vio)
|
||||
{
|
||||
return vio->desc;
|
||||
}
|
||||
|
||||
enum enum_vio_type vio_type(Vio* vio)
|
||||
{
|
||||
return vio->type;
|
||||
}
|
||||
|
||||
my_socket vio_fd(Vio* vio)
|
||||
{
|
||||
return vio->sd;
|
||||
}
|
||||
|
||||
|
||||
my_bool vio_peer_addr(Vio * vio, char *buf)
|
||||
{
|
||||
DBUG_ENTER("vio_peer_addr");
|
||||
DBUG_PRINT("enter", ("sd=%d", vio->sd));
|
||||
if (vio->localhost)
|
||||
{
|
||||
strmov(buf,"127.0.0.1");
|
||||
}
|
||||
else
|
||||
{
|
||||
size_socket addrLen = sizeof(struct sockaddr);
|
||||
if (getpeername(vio->sd, (struct sockaddr *) (& (vio->remote)),
|
||||
&addrLen) != 0)
|
||||
{
|
||||
DBUG_PRINT("exit", ("getpeername, error: %d", errno));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
my_inet_ntoa(vio->remote.sin_addr,buf);
|
||||
}
|
||||
DBUG_PRINT("exit", ("addr=%s", buf));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
void vio_in_addr(Vio *vio, struct in_addr *in)
|
||||
{
|
||||
DBUG_ENTER("vio_in_addr");
|
||||
if (vio->localhost)
|
||||
bzero((char*) in, sizeof(*in)); /* This should never be executed */
|
||||
else
|
||||
*in=vio->remote.sin_addr;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
#endif /* HAVE_VIO */
|
Reference in New Issue
Block a user