mirror of
https://github.com/mariadb-corporation/mariadb-connector-c.git
synced 2025-04-18 21:24:07 +03:00
First implementation based on libmysql 3.23.58 and php's mysqlnd extension
This commit is contained in:
parent
18cb6a1407
commit
dd3d0d6f52
13
.bzrignore
Normal file
13
.bzrignore
Normal file
@ -0,0 +1,13 @@
|
||||
CMakeCache.txt
|
||||
CMakeFiles/*
|
||||
*.cmake
|
||||
Makefile
|
||||
include/my_config.h
|
||||
include/mysql_version.h
|
||||
CMakeFiles
|
||||
mysql_config/mysql_config.c
|
||||
examples/mysql_affected_rows
|
||||
examples/mysql_debug
|
||||
examples/test_output
|
||||
libmysql.so.*
|
||||
mysql_config/mysql_config
|
117
CMakeLists.txt
117
CMakeLists.txt
@ -25,15 +25,44 @@ ENDIF(CMAKE_COMPILER_IS_GNUCXX)
|
||||
|
||||
# various defines for generating include/mysql_version.h
|
||||
SET(PROTOCOL_VERSION 10) # we adapted new password option from PHP's mysqlnd !
|
||||
SET(MYSQL_CLIENT_VERSION "3.23.59")
|
||||
SET(MYSQL_VERSION_ID "32359")
|
||||
SET(MYSQL_CLIENT_VERSION_MAJOR "5")
|
||||
SET(MYSQL_CLIENT_VERSION_MINOR "3")
|
||||
SET(MYSQL_CLIENT_VERSION_PATCH "1")
|
||||
SET(MYSQL_CLIENT_VERSION "${MYSQL_CLIENT_VERSION_MAJOR}.${MYSQL_CLIENT_VERSION_MINOR}.${MYSQL_CLIENT_VERSION_PATCH}")
|
||||
MATH(EXPR MYSQL_VERSION_ID "${MYSQL_CLIENT_VERSION_MAJOR} * 10000 +
|
||||
${MYSQL_CLIENT_VERSION_MINOR} * 100 +
|
||||
${MYSQL_CLIENT_VERSION_PATCH}")
|
||||
IF (NOT MYSQL_PORT)
|
||||
SET(MYSQL_PORT 3306)
|
||||
ENDIF (NOT MYSQL_PORT)
|
||||
IF(NOT MYSQL_UNIX_ADDR)
|
||||
SET(MYSQL_UNIX_ADDR "/tmp/mysql.sock")
|
||||
ENDIF(NOT MYSQL_UNIX_ADDR)
|
||||
|
||||
# todo: we don't character sets in share - all is compiled in
|
||||
SET(SHAREDIR "share")
|
||||
SET(DEFAULT_CHARSET_HOME "${CMAKE_INSTALL_PREFIX}")
|
||||
|
||||
FIND_PACKAGE(Threads)
|
||||
|
||||
IF(${CMAKE_HAVE_PTHREAD_H})
|
||||
SET(CMAKE_REQUIRED_INCLUDES pthread.h)
|
||||
ENDIF(${CMAKE_HAVE_PTHREAD_H})
|
||||
#Check for threads
|
||||
IF(WIN32)
|
||||
SET(HAVE_THREADS 1)
|
||||
ADD_DEFINITIONS(-DHAVE_DLOPEN)
|
||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4996" )
|
||||
ELSEIF(WIN32)
|
||||
SET(HAVE_THREADS ${CMAKE_USE_PTHREADS})
|
||||
ENDIF(WIN32)
|
||||
|
||||
FIND_LIBRARY(DL_LIBRARY dl)
|
||||
IF(DL_LIBRARY)
|
||||
SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${CMAKE_DL_LIBS})
|
||||
ENDIF(DL_LIBRARY)
|
||||
|
||||
# check for various include files
|
||||
INCLUDE(LibmysqlIncludeFiles.txt)
|
||||
# check for various functions
|
||||
@ -41,12 +70,14 @@ INCLUDE(LibmysqlFunctions.txt)
|
||||
# check for various types
|
||||
INCLUDE(LibmysqlTypes.txt)
|
||||
|
||||
#Check for threads
|
||||
IF(WIN32)
|
||||
SET(HAVE_THREADS 1)
|
||||
ELSEIF(WIN32)
|
||||
SET(HAVE_THREADS ${CMAKE_USE_PTHREADS})
|
||||
ENDIF(WIN32)
|
||||
|
||||
|
||||
#Check for OpenSSL
|
||||
#INCLUDE(FindOpenSSL)
|
||||
#IF(OPENSSL_FOUND)
|
||||
# ADD_DEFINITIONS(-DHAVE_OPENSSL)
|
||||
# FIND_LIBRARY(SSL_LIBRARIES NAMES libeay32 crypto)
|
||||
#ENDIF(OPENSSL_FOUND)
|
||||
|
||||
|
||||
MESSAGE(STATUS "writing configuration files")
|
||||
@ -57,9 +88,69 @@ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/include/my_config.h.in
|
||||
|
||||
ADD_SUBDIRECTORY(zlib)
|
||||
ADD_SUBDIRECTORY(libmysql)
|
||||
ADD_SUBDIRECTORY(examples)
|
||||
IF(NOT WIN32)
|
||||
ADD_SUBDIRECTORY(mysql_config)
|
||||
ENDIF(NOT WIN32)
|
||||
|
||||
IF(IS_DIRECTORY unittest)
|
||||
MESSAGE(STATUS "found unittests")
|
||||
ADD_SUBDIRECTORY(unittest/mytap)
|
||||
ADD_SUBDIRECTORY(unittest/libmysql)
|
||||
ENDIF(IS_DIRECTORY unittest)
|
||||
IF(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/unittest)
|
||||
MESSAGE(STATUS "found unittests")
|
||||
ADD_SUBDIRECTORY(unittest/mytap)
|
||||
ADD_SUBDIRECTORY(unittest/libmysql)
|
||||
ENDIF(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/unittest)
|
||||
|
||||
IF(WIN32)
|
||||
SET(CMAKE_INSTALL_PREFIX "")
|
||||
ENDIF(WIN32)
|
||||
|
||||
|
||||
SET(CPACK_VERSION_MAJOR ${MYSQL_CLIENT_VERSION_MAJOR})
|
||||
SET(CPACK_VERSION_MINOR ${MYSQL_CLIENT_VERSION_MINOR})
|
||||
SET(CPACK_VERSION_PATCH ${MYSQL_CLIENT_VERSION_PATCH})
|
||||
|
||||
SET(CPACK_PACKAGE_VENDOR "Monty Program AB")
|
||||
SET(CPACK_PACKAGE_DESCRIPTION "MariaDB client library. A library for connecting to MariaDB and MySQL servers")
|
||||
SET(CPACK_PACKAGE_NAME "mariadb_client")
|
||||
SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING.LIB")
|
||||
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README")
|
||||
SET(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${MYSQL_CLIENT_VERSION}-src")
|
||||
|
||||
SET(CPACK_SOURCE_IGNORE_FILES
|
||||
.bzr/
|
||||
CMakeCache.txt
|
||||
cmake_dist.cmake
|
||||
CPackSourceConfig.cmake
|
||||
CPackConfig.cmake
|
||||
.build/
|
||||
html/
|
||||
unittest
|
||||
/cmake_install.cmake
|
||||
/CTestTestfile.cmake
|
||||
/CMakeFiles/
|
||||
/version_resources/
|
||||
/_CPack_Packages/
|
||||
.*gz$
|
||||
.*zip$
|
||||
.*so$
|
||||
.*so.*$
|
||||
.*dll$
|
||||
.*a$
|
||||
.*pdb$
|
||||
/CMakeFiles/
|
||||
/version_resources/
|
||||
/_CPack_Packages/
|
||||
Makefile$
|
||||
include/my_config.h$
|
||||
/autom4te.cache/
|
||||
errmsg.sys$
|
||||
)
|
||||
|
||||
IF(NOT WIN32)
|
||||
SET(CPACK_GENERATOR "TGZ")
|
||||
SET(CPACK_SOURCE_GENERATOR "TGZ")
|
||||
ELSEIF(NOT WIN32)
|
||||
SET(CPACK_GENERATOR "ZIP")
|
||||
SET(CPACK_SOURCE_GENERATOR "ZIP")
|
||||
ENDIF(NOT WIN32)
|
||||
|
||||
INCLUDE(CPack)
|
||||
|
193
COPYING.LIB
193
COPYING.LIB
@ -1,13 +1,14 @@
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the library GPL. It is
|
||||
numbered 2 because it goes with version 2 of the ordinary GPL.]
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
@ -16,97 +17,109 @@ freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Library General Public License, applies to some
|
||||
specially designated Free Software Foundation software, and to any
|
||||
other libraries whose authors decide to use it. You can use it for
|
||||
your libraries, too.
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if
|
||||
you distribute copies of the library, or if you modify it.
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link a program with the library, you must provide
|
||||
complete object files to the recipients so that they can relink them
|
||||
with the library, after making changes to the library and recompiling
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
Our method of protecting your rights has two steps: (1) copyright
|
||||
the library, and (2) offer you this license which gives you legal
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
Also, for each distributor's protection, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
library. If the library is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original
|
||||
version, so that any problems introduced by others will not reflect on
|
||||
the original authors' reputations.
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that companies distributing free
|
||||
software will individually obtain patent licenses, thus in effect
|
||||
transforming the program into proprietary software. To prevent this,
|
||||
we have made it clear that any patent must be licensed for everyone's
|
||||
free use or not licensed at all.
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the ordinary
|
||||
GNU General Public License, which was designed for utility programs. This
|
||||
license, the GNU Library General Public License, applies to certain
|
||||
designated libraries. This license is quite different from the ordinary
|
||||
one; be sure to read it in full, and don't assume that anything in it is
|
||||
the same as in the ordinary license.
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
The reason we have a separate public license for some libraries is that
|
||||
they blur the distinction we usually make between modifying or adding to a
|
||||
program and simply using it. Linking a program with a library, without
|
||||
changing the library, is in some sense simply using the library, and is
|
||||
analogous to running a utility program or application program. However, in
|
||||
a textual and legal sense, the linked executable is a combined work, a
|
||||
derivative of the original library, and the ordinary General Public License
|
||||
treats it as such.
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
Because of this blurred distinction, using the ordinary General
|
||||
Public License for libraries did not effectively promote software
|
||||
sharing, because most developers did not use the libraries. We
|
||||
concluded that weaker conditions might promote sharing better.
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
However, unrestricted linking of non-free programs would deprive the
|
||||
users of those programs of all benefit from the free status of the
|
||||
libraries themselves. This Library General Public License is intended to
|
||||
permit developers of non-free programs to use free libraries, while
|
||||
preserving your freedom as a user of such programs to change the free
|
||||
libraries that are incorporated in them. (We have not seen how to achieve
|
||||
this as regards changes in header files, but we have achieved it as regards
|
||||
changes in the actual functions of the Library.) The hope is that this
|
||||
will lead to faster development of free libraries.
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, while the latter only
|
||||
works together with the library.
|
||||
|
||||
Note that it is possible for a library to be covered by the ordinary
|
||||
General Public License rather than by this special one.
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library which
|
||||
contains a notice placed by the copyright holder or other authorized
|
||||
party saying it may be distributed under the terms of this Library
|
||||
General Public License (also called "this License"). Each licensee is
|
||||
addressed as "you".
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
@ -133,7 +146,7 @@ such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
@ -255,7 +268,7 @@ distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also compile or
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
@ -282,23 +295,31 @@ of these things:
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Accompany the work with a written offer, valid for at
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
c) If distribution of the work is made by offering access to copy
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
d) Verify that the user has already received a copy of these
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the source code distributed need not include anything that is normally
|
||||
distributed (in either source or binary form) with the major
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
@ -347,7 +368,7 @@ Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
@ -390,7 +411,7 @@ excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Library General Public License from time to time.
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
@ -453,16 +474,16 @@ convey the exclusion of warranty; and each file should have at least the
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
version 2.1 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.
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
# You will find the appropiate defines in
|
||||
# include/my_config.h.in
|
||||
INCLUDE (CheckTypeSize)
|
||||
INCLUDE (CheckCXXSourceCompiles)
|
||||
|
||||
SET(CMAKE_EXTRA_INCLUDE_FILES signal.h)
|
||||
CHECK_TYPE_SIZE(sigset_t SIZEOF_SIGSET_T)
|
||||
@ -81,3 +82,26 @@ IF(IS_VOID_QSORT)
|
||||
ELSE(IS_VOID_QSORT)
|
||||
SET(RETQSORTTYPE "int")
|
||||
ENDIF(IS_VOID_QSORT)
|
||||
|
||||
#
|
||||
# SOCKET_SIZE
|
||||
#
|
||||
IF(WIN32)
|
||||
SET(SOCKET_SIZE_TYPE int)
|
||||
ELSE(WIN32)
|
||||
FOREACH(CHECK_TYPE "socklen_t" "size_t" "int")
|
||||
IF (NOT SOCKET_SIZE_TYPE)
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <sys/socket.h>
|
||||
int main()
|
||||
{
|
||||
getsockname(0, 0, (${CHECK_TYPE} *)0);
|
||||
return 0;
|
||||
}"
|
||||
SOCKET_SIZE_FOUND_${CHECK_TYPE})
|
||||
IF(SOCKET_SIZE_FOUND_${CHECK_TYPE})
|
||||
SET(SOCKET_SIZE_TYPE ${CHECK_TYPE})
|
||||
ENDIF(SOCKET_SIZE_FOUND_${CHECK_TYPE})
|
||||
ENDIF (NOT SOCKET_SIZE_TYPE)
|
||||
ENDFOREACH()
|
||||
ENDIF(WIN32)
|
||||
|
4
README
4
README
@ -8,8 +8,8 @@ The following are the main known limitations:
|
||||
|
||||
- float to string conversion for prepared statements
|
||||
doesn't work correctly
|
||||
- It doesn't compile on windows (should not be hard to fix; It's mainly
|
||||
the compiler environment files that is missing)
|
||||
- SSL support
|
||||
- Win64 support not yet ready
|
||||
|
||||
If you want to be part of this development effort, you can discuss this at
|
||||
maria-developers@lists.launchpad.org.
|
||||
|
18
examples/CMakeLists.txt
Normal file
18
examples/CMakeLists.txt
Normal file
@ -0,0 +1,18 @@
|
||||
SET(EXAMPLE_FILES "mysql_affected_rows"
|
||||
"mysql_debug")
|
||||
|
||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
|
||||
|
||||
ENABLE_TESTING()
|
||||
|
||||
# this will be the main tests which saves output
|
||||
# from example files
|
||||
ADD_EXECUTABLE(test_output test_output.c)
|
||||
|
||||
FOREACH(EXAMPLE_FILE ${EXAMPLE_FILES})
|
||||
SET(XML_EXAMPLE_FILES $XML_EXAMPLE_FILES "examples/${EXAMPLE_FILE}.c")
|
||||
ADD_EXECUTABLE(${EXAMPLE_FILE} ${EXAMPLE_FILE}.c)
|
||||
TARGET_LINK_LIBRARIES(${EXAMPLE_FILE} mysqlclient)
|
||||
ADD_TEST(TEST_${EXAMPLE_FILE} ./${EXECUTABLE_OUTPUT_PATH}/test_output ./${EXAMPLE_FILE} ${CMAKE_SOURCE_DIR}/examples/${EXAMPLE_FILE}.out ${CMAKE_SOURCE_DIR}/examples/${EXAMPLE_FILE}.exp)
|
||||
|
||||
ENDFOREACH(EXAMPLE_FILE ${EXAMPLE_FILES})
|
82
examples/mysql_affected_rows.c
Normal file
82
examples/mysql_affected_rows.c
Normal file
@ -0,0 +1,82 @@
|
||||
#include <mysql.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void show_error(MYSQL *mysql)
|
||||
{
|
||||
printf("Error(%d) [%s] \"%s\"", mysql_errno(mysql),
|
||||
mysql_sqlstate(mysql),
|
||||
mysql_error(mysql));
|
||||
mysql_close(mysql);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
MYSQL *mysql;
|
||||
const char *query;
|
||||
MYSQL_RES *result;
|
||||
|
||||
mysql= mysql_init(NULL);
|
||||
if (!mysql_real_connect(mysql, "localhost", "example", "example_pw",
|
||||
"example_db", 0, "/tmp/mysql.sock", 0))
|
||||
show_error(mysql);
|
||||
|
||||
query= "DROP TABLE IF EXISTS affected_rows";
|
||||
if (mysql_real_query(mysql, query, strlen(query)))
|
||||
show_error(mysql);
|
||||
|
||||
query= "CREATE TABLE affected_rows (id int not null, my_name varchar(50),"
|
||||
"PRIMARY KEY(id))";
|
||||
if (mysql_real_query(mysql, query, strlen(query)))
|
||||
show_error(mysql);
|
||||
|
||||
/* Affected rows with INSERT statement */
|
||||
query= "INSERT INTO affected_rows VALUES (1, \"First value\"),"
|
||||
"(2, \"Second value\")";
|
||||
if (mysql_real_query(mysql, query, strlen(query)))
|
||||
show_error(mysql);
|
||||
printf("Affected_rows after INSERT: %lu\n",
|
||||
(unsigned long) mysql_affected_rows(mysql));
|
||||
|
||||
/* Affected rows with REPLACE statement */
|
||||
query= "REPLACE INTO affected_rows VALUES (1, \"First value\"),"
|
||||
"(2, \"Second value\")";
|
||||
if (mysql_real_query(mysql, query, strlen(query)))
|
||||
show_error(mysql);
|
||||
printf("Affected_rows after REPLACE: %lu\n",
|
||||
(unsigned long) mysql_affected_rows(mysql));
|
||||
|
||||
/* Affected rows with UPDATE statement */
|
||||
query= "UPDATE affected_rows SET id=1 WHERE id=1";
|
||||
if (mysql_real_query(mysql, query, strlen(query)))
|
||||
show_error(mysql);
|
||||
printf("Affected_rows after UPDATE: %lu\n",
|
||||
(unsigned long) mysql_affected_rows(mysql));
|
||||
|
||||
query= "UPDATE affected_rows SET my_name=\"Monty\" WHERE id=1";
|
||||
if (mysql_real_query(mysql, query, strlen(query)))
|
||||
show_error(mysql);
|
||||
printf("Affected_rows after UPDATE: %lu\n",
|
||||
(unsigned long) mysql_affected_rows(mysql));
|
||||
|
||||
/* Affected rows after select */
|
||||
query= "SELECT id, my_name FROM affected_rows";
|
||||
if (mysql_real_query(mysql, query, strlen(query)))
|
||||
show_error(mysql);
|
||||
result= mysql_store_result(mysql);
|
||||
printf("Affected_rows after SELECT and storing result set: %lu\n",
|
||||
(unsigned long) mysql_affected_rows(mysql));
|
||||
mysql_free_result(result);
|
||||
|
||||
/* Affected rows with DELETE statment */
|
||||
query= "DELETE FROM affected_rows";
|
||||
if (mysql_real_query(mysql, query, strlen(query)))
|
||||
show_error(mysql);
|
||||
printf("Affected_rows after DELETE: %lu\n",
|
||||
(unsigned long) mysql_affected_rows(mysql));
|
||||
|
||||
mysql_close(mysql);
|
||||
return 0;
|
||||
}
|
40
examples/mysql_debug.c
Normal file
40
examples/mysql_debug.c
Normal file
@ -0,0 +1,40 @@
|
||||
#include <mysql.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void show_error(MYSQL *mysql)
|
||||
{
|
||||
printf("Error(%d) [%s] \"%s\"", mysql_errno(mysql),
|
||||
mysql_sqlstate(mysql),
|
||||
mysql_error(mysql));
|
||||
mysql_close(mysql);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
MYSQL *mysql;
|
||||
const char *query;
|
||||
|
||||
mysql_debug("d:t:O");
|
||||
|
||||
mysql= mysql_init(NULL);
|
||||
|
||||
if (!mysql_real_connect(mysql, "localhost", "example", "example_pw",
|
||||
"example_db", 0, "/tmp/mysql.sock", 0))
|
||||
show_error(mysql);
|
||||
|
||||
query= "DROP TABLE IF EXISTS debug_example";
|
||||
if (mysql_real_query(mysql, query, strlen(query)))
|
||||
show_error(mysql);
|
||||
|
||||
query= "CREATE TABLE debug_example (id int not null, my_name varchar(50),"
|
||||
"PRIMARY KEY(id))";
|
||||
if (mysql_real_query(mysql, query, strlen(query)))
|
||||
show_error(mysql);
|
||||
|
||||
mysql_close(mysql);
|
||||
|
||||
return 0;
|
||||
}
|
72
examples/test_output.c
Normal file
72
examples/test_output.c
Normal file
@ -0,0 +1,72 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef _WIN32
|
||||
#define popen _popen
|
||||
#define pclose _pclose
|
||||
#endif
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char cmd_output[1024];
|
||||
char cmd_exp[1024];
|
||||
FILE *fp_exec, *fp_out, *fp_exp;
|
||||
|
||||
if (argc < 3)
|
||||
{
|
||||
printf("Syntax: test_output test output expected");
|
||||
exit(-1);
|
||||
}
|
||||
if (!(fp_exec= popen(argv[1], "r")))
|
||||
{
|
||||
printf("Failed to run %s\n", argv[1]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (!(fp_out= fopen(argv[2], "w")))
|
||||
{
|
||||
printf("Failed to open %s for write\n", argv[2]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
while (NULL != fgets(cmd_output, sizeof(cmd_output-1), fp_exec))
|
||||
{
|
||||
fputs(cmd_output, fp_out);
|
||||
}
|
||||
pclose(fp_exec);
|
||||
fflush(fp_out);
|
||||
fclose(fp_out);
|
||||
|
||||
if (argc == 3)
|
||||
return 0;
|
||||
|
||||
if (!(fp_exp= fopen(argv[3], "r")))
|
||||
{
|
||||
/* if no exp file exists, we just return
|
||||
without an error = skip check */
|
||||
return(0);
|
||||
}
|
||||
if (!(fp_out= fopen(argv[2], "r")))
|
||||
{
|
||||
printf("Failed to open %s for read\n", argv[2]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
while (fgets(cmd_exp, sizeof(cmd_exp)-1, fp_exp))
|
||||
{
|
||||
if (!fgets(cmd_output, sizeof(cmd_output)-1, fp_out))
|
||||
{
|
||||
printf("Can't read from output file\n");
|
||||
goto error;
|
||||
}
|
||||
if (strcmp(cmd_output, cmd_exp))
|
||||
{
|
||||
printf("output and expected output are different\n");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
error:
|
||||
fclose(fp_exp);
|
||||
fclose(fp_out);
|
||||
return 1;
|
||||
}
|
@ -17,19 +17,21 @@
|
||||
|
||||
/* Defines for Win32 to make it compatible for MySQL */
|
||||
|
||||
#ifndef _config_win_h_
|
||||
#define _config_win_h_
|
||||
|
||||
#include <sys/locking.h>
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <math.h> /* Because of rint() */
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#include <malloc.h>
|
||||
#include <sys/stat.h>
|
||||
#include <process.h>
|
||||
|
||||
#if defined(__NT__)
|
||||
#define SYSTEM_TYPE "NT"
|
||||
#elif defined(__WIN2000__)
|
||||
#define SYSTEM_TYPE "WIN2000"
|
||||
#else
|
||||
#define SYSTEM_TYPE "Win95/Win98"
|
||||
#ifndef THREAD
|
||||
#define THREAD
|
||||
#endif
|
||||
|
||||
#ifdef _WIN64
|
||||
@ -37,9 +39,6 @@
|
||||
#else
|
||||
#define MACHINE_TYPE "i32" /* Define to machine type name */
|
||||
#endif /* _WIN64 */
|
||||
#ifndef __WIN__
|
||||
#define __WIN__ /* To make it easier in VC++ */
|
||||
#endif
|
||||
|
||||
/* File and lock constants */
|
||||
#define O_SHARE 0x1000 /* Open file in sharing mode */
|
||||
@ -97,7 +96,6 @@ typedef __int64 os_off_t;
|
||||
#ifdef _WIN64
|
||||
typedef UINT_PTR rf_SetTimer;
|
||||
#else
|
||||
typedef unsigned int size_t;
|
||||
typedef uint rf_SetTimer;
|
||||
#endif
|
||||
|
||||
@ -115,9 +113,6 @@ typedef uint rf_SetTimer;
|
||||
#define HUGE_PTR
|
||||
#define STDCALL __stdcall /* Used by libmysql.dll */
|
||||
|
||||
#ifndef UNDEF_THREAD_HACK
|
||||
#define THREAD
|
||||
#endif
|
||||
#define VOID_SIGHANDLER
|
||||
#define SIZEOF_CHAR 1
|
||||
#define SIZEOF_LONG 4
|
||||
@ -170,6 +165,8 @@ inline double ulonglong2double(ulonglong value)
|
||||
#define inline __inline
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define __attribute(A)
|
||||
|
||||
#if SIZEOF_OFF_T > 4
|
||||
#define lseek(A,B,C) _lseeki64((A),(longlong) (B),(C))
|
||||
#define tell(A) _telli64(A)
|
||||
@ -177,49 +174,17 @@ inline double ulonglong2double(ulonglong value)
|
||||
|
||||
#define STACK_DIRECTION -1
|
||||
|
||||
/* Optimized store functions for Intel x86 */
|
||||
|
||||
#define sint2korr(A) (*((int16 *) (A)))
|
||||
#define sint3korr(A) ((int32) ((((uchar) (A)[2]) & 128) ? \
|
||||
(((uint32) 255L << 24) | \
|
||||
(((uint32) (uchar) (A)[2]) << 16) |\
|
||||
(((uint32) (uchar) (A)[1]) << 8) | \
|
||||
((uint32) (uchar) (A)[0])) : \
|
||||
(((uint32) (uchar) (A)[2]) << 16) |\
|
||||
(((uint32) (uchar) (A)[1]) << 8) | \
|
||||
((uint32) (uchar) (A)[0])))
|
||||
#define sint4korr(A) (*((long *) (A)))
|
||||
#define uint2korr(A) (*((uint16 *) (A)))
|
||||
#define uint3korr(A) (long) (*((unsigned long *) (A)) & 0xFFFFFF)
|
||||
#define uint4korr(A) (*((unsigned long *) (A)))
|
||||
#define uint5korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) +\
|
||||
(((uint32) ((uchar) (A)[1])) << 8) +\
|
||||
(((uint32) ((uchar) (A)[2])) << 16) +\
|
||||
(((uint32) ((uchar) (A)[3])) << 24)) +\
|
||||
(((ulonglong) ((uchar) (A)[4])) << 32))
|
||||
#define uint8korr(A) (*((ulonglong *) (A)))
|
||||
#define sint8korr(A) (*((longlong *) (A)))
|
||||
#define int2store(T,A) *((uint16*) (T))= (uint16) (A)
|
||||
#define int3store(T,A) { *(T)= (uchar) ((A));\
|
||||
*(T+1)=(uchar) (((uint) (A) >> 8));\
|
||||
*(T+2)=(uchar) (((A) >> 16)); }
|
||||
#define int4store(T,A) *((long *) (T))= (long) (A)
|
||||
#define int5store(T,A) { *(T)= (uchar)((A));\
|
||||
*((T)+1)=(uchar) (((A) >> 8));\
|
||||
*((T)+2)=(uchar) (((A) >> 16));\
|
||||
*((T)+3)=(uchar) (((A) >> 24)); \
|
||||
*((T)+4)=(uchar) (((A) >> 32)); }
|
||||
#define int8store(T,A) *((ulonglong *) (T))= (ulonglong) (A)
|
||||
|
||||
#define doubleget(V,M) { *((long *) &V) = *((long*) M); \
|
||||
*(((long *) &V)+1) = *(((long*) M)+1); }
|
||||
#define doublestore(T,V) { *((long *) T) = *((long*) &V); \
|
||||
*(((long *) T)+1) = *(((long*) &V)+1); }
|
||||
#define float4get(V,M) { *((long *) &(V)) = *((long*) (M)); }
|
||||
#define float8get(V,M) doubleget((V),(M))
|
||||
#define float4store(V,M) memcpy((byte*) V,(byte*) (&M),sizeof(float))
|
||||
#define float8store(V,M) doublestore((V),(M))
|
||||
|
||||
/* redefine deprecated functions
|
||||
#define sprintf sprintf_s
|
||||
#define strcpy strcpy_s
|
||||
#define strcat strcat_s
|
||||
#define fopen fopen_r
|
||||
#define freopen freopen_r
|
||||
#define getenv _dupenv_s
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#define HAVE_PERROR
|
||||
#define HAVE_VFPRINT
|
||||
@ -247,7 +212,6 @@ inline double ulonglong2double(ulonglong value)
|
||||
#define HAVE_ALLOCA
|
||||
#define HAVE_STRPBRK
|
||||
#define HAVE_STRSTR
|
||||
#define HAVE_COMPRESS
|
||||
|
||||
#ifdef NOT_USED
|
||||
#define HAVE_SNPRINTF /* Gave link error */
|
||||
@ -298,3 +262,6 @@ inline double ulonglong2double(ulonglong value)
|
||||
#define statistic_add(V,C,L) (V)+=(C)
|
||||
#endif
|
||||
#define statistic_increment(V,L) thread_safe_increment((V),(L))
|
||||
#define strcasecmp(A,B) _stricmp((A),(B))
|
||||
|
||||
#endif
|
||||
|
@ -27,6 +27,7 @@ extern const char *client_errors[]; /* Error messages */
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#define CR_MIN_ERROR 2000 /* For easier client code */
|
||||
#define CR_MAX_ERROR 2999
|
||||
#if defined(OS2) && defined( MYSQL_SERVER)
|
||||
@ -57,6 +58,7 @@ extern const char *client_errors[]; /* Error messages */
|
||||
#define CR_NAMEDPIPESETSTATE_ERROR 2018
|
||||
#define CR_CANT_READ_CHARSET 2019
|
||||
#define CR_NET_PACKET_TOO_LARGE 2020
|
||||
#define CR_MALFORMED_PACKET 2027
|
||||
#define CR_NO_PREPARE_STMT 2030
|
||||
#define CR_PARAMS_NOT_BOUND 2031
|
||||
#define CR_INVALID_PARAMETER_NO 2034
|
||||
@ -64,7 +66,9 @@ extern const char *client_errors[]; /* Error messages */
|
||||
#define CR_NO_DATA 2051
|
||||
#define CR_NO_STMT_METADATA 2052
|
||||
#define CR_NOT_IMPLEMENTED 2054
|
||||
#define CR_SERVER_LOST_EXTENDED 2055
|
||||
#define CR_NEW_STMT_METADATA 2057
|
||||
#define CR_ALREADY_CONNECTED 2058
|
||||
#define CR_AUTH_PLUGIN_CANNOT_LOAD 2058
|
||||
#define CR_ALREADY_CONNECTED 2059
|
||||
|
||||
#define SQLSTATE_UNKNOWN "HY000"
|
||||
|
@ -21,30 +21,8 @@
|
||||
#ifndef _global_h
|
||||
#define _global_h
|
||||
|
||||
#if defined( __EMX__) && !defined( MYSQL_SERVER)
|
||||
/* moved here to use below VOID macro redefinition */
|
||||
#define INCL_BASE
|
||||
#define INCL_NOPMAPI
|
||||
#include <os2.h>
|
||||
#endif /* __EMX__ */
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
/* We use a Unix API, so pretend it's not Windows */
|
||||
#undef WIN
|
||||
#undef WIN32
|
||||
#undef _WIN
|
||||
#undef _WIN32
|
||||
#undef _WIN64
|
||||
#undef __WIN__
|
||||
#undef __WIN32__
|
||||
#define HAVE_ERRNO_AS_DEFINE
|
||||
#endif /* __CYGWIN__ */
|
||||
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
|
||||
#ifdef _WIN32
|
||||
#include <config-win.h>
|
||||
#elif defined(OS2)
|
||||
#include <config-os2.h>
|
||||
#else
|
||||
#include <my_config.h>
|
||||
#if defined(__cplusplus) && defined(inline)
|
||||
@ -76,7 +54,7 @@
|
||||
#define __STDC_EXT__ 1 /* To get large file support on hpux */
|
||||
#endif
|
||||
|
||||
#if defined(THREAD) && !defined(__WIN__) && !defined(OS2)
|
||||
#if defined(THREAD) && !defined(_WIN32)
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
#define _POSIX_PTHREAD_SEMANTICS /* We want posix threads */
|
||||
#endif
|
||||
@ -225,9 +203,7 @@
|
||||
#define POSIX_MISTAKE 1 /* regexp: Fix stupid spec error */
|
||||
#define USE_REGEX 1 /* We want the use the regex library */
|
||||
/* Do not define for ultra sparcs */
|
||||
#ifndef OS2
|
||||
#define USE_BMOVE512 1 /* Use this unless the system bmove is faster */
|
||||
#endif
|
||||
|
||||
/* Paranoid settings. Define I_AM_PARANOID if you are paranoid */
|
||||
#ifdef I_AM_PARANOID
|
||||
@ -270,11 +246,6 @@ int __void__;
|
||||
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#if defined(__EMX__) || !defined(HAVE_UINT)
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned short ushort;
|
||||
#endif
|
||||
|
||||
#define sgn(a) (((a) < 0) ? -1 : ((a) > 0) ? 1 : 0)
|
||||
#define swap(t,a,b) { register t dummy; dummy = a; a = b; b = dummy; }
|
||||
#define test(a) ((a) ? 1 : 0)
|
||||
@ -416,13 +387,8 @@ typedef SOCKET_SIZE_TYPE size_socket;
|
||||
#define FN_DEVCHAR ':'
|
||||
|
||||
#ifndef FN_LIBCHAR
|
||||
#ifdef __EMX__
|
||||
#define FN_LIBCHAR '\\'
|
||||
#define FN_ROOTDIR "\\"
|
||||
#else
|
||||
#define FN_LIBCHAR '/'
|
||||
#define FN_ROOTDIR "/"
|
||||
#endif
|
||||
#define MY_NFILE 1024 /* This is only used to save filenames */
|
||||
#endif
|
||||
|
||||
@ -454,7 +420,7 @@ typedef SOCKET_SIZE_TYPE size_socket;
|
||||
#define NO_PISAM /* Not needed anymore */
|
||||
#define NO_MISAM /* Not needed anymore */
|
||||
#define NO_HASH /* Not needed anymore */
|
||||
#ifdef __WIN__
|
||||
#ifdef _WIN32
|
||||
#define NO_DIR_LIBRARY /* Not standar dir-library */
|
||||
#define USE_MY_STAT_STRUCT /* For my_lib */
|
||||
#endif
|
||||
@ -476,7 +442,7 @@ extern void init_my_atof(void);
|
||||
extern double my_atof(const char*);
|
||||
#endif
|
||||
#undef remove /* Crashes MySQL on SCO 5.0.0 */
|
||||
#ifndef __WIN__
|
||||
#ifndef _WIN32
|
||||
#ifdef OS2
|
||||
#define closesocket(A) soclose(A)
|
||||
#else
|
||||
@ -644,11 +610,11 @@ typedef ulonglong my_off_t;
|
||||
typedef unsigned long my_off_t;
|
||||
#endif
|
||||
#define MY_FILEPOS_ERROR (~(my_off_t) 0)
|
||||
#if !defined(__WIN__) && !defined(OS2)
|
||||
#if !defined(_WIN32) && !defined(OS2)
|
||||
typedef off_t os_off_t;
|
||||
#endif
|
||||
|
||||
#if defined(__WIN__)
|
||||
#if defined(_WIN32)
|
||||
#define socket_errno WSAGetLastError()
|
||||
#define SOCKET_EINTR WSAEINTR
|
||||
#define SOCKET_EAGAIN WSAEINPROGRESS
|
||||
|
@ -37,14 +37,15 @@ extern "C" {
|
||||
typedef struct charset_info_st
|
||||
{
|
||||
uint nr; /* so far only 1 byte for charset */
|
||||
uint state;
|
||||
char *csname;
|
||||
char *name;
|
||||
char *collation;
|
||||
char *comment;
|
||||
char *dir;
|
||||
uint char_minlen;
|
||||
uint char_maxlen;
|
||||
uint (*mb_charlen)(uint c);
|
||||
uint (*mb_valid)(const char *start, const char *end);
|
||||
uchar *ctype;
|
||||
uint mbmaxlen;
|
||||
} CHARSET_INFO;
|
||||
|
||||
extern const CHARSET_INFO compiled_charsets[];
|
||||
@ -53,6 +54,6 @@ extern CHARSET_INFO *default_charset_info;
|
||||
CHARSET_INFO *find_compiled_charset(uint cs_number);
|
||||
CHARSET_INFO *find_compiled_charset_by_name(const char *name);
|
||||
|
||||
unsigned long mysql_cset_escape_quotes(const CHARSET_INFO *cset, char *newstr, const char *escapestr, size_t escapestr_len);
|
||||
unsigned long mysql_cset_escape_slashes(const CHARSET_INFO *cset, char *newstr, const char *escapestr, size_t escapestr_len);
|
||||
size_t mysql_cset_escape_quotes(const CHARSET_INFO *cset, char *newstr, const char *escapestr, size_t escapestr_len);
|
||||
size_t mysql_cset_escape_slashes(const CHARSET_INFO *cset, char *newstr, const char *escapestr, size_t escapestr_len);
|
||||
#endif
|
||||
|
@ -82,7 +82,7 @@
|
||||
# define bmove_allign(A,B,C) memcpy((A),(B),(C))
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus) && !defined(OS2)
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@ -108,14 +108,6 @@ extern char NEAR _dig_vec[]; /* Declared in int2str() */
|
||||
#define memcpy_fixed(A,B,C) memcpy((A),(B),(C))
|
||||
#endif
|
||||
|
||||
#ifdef MSDOS
|
||||
#undef bmove_allign
|
||||
#define bmove512(A,B,C) bmove_allign(A,B,C)
|
||||
#define my_itoa(A,B,C) itoa(A,B,C)
|
||||
#define my_ltoa(A,B,C) ltoa(A,B,C)
|
||||
extern void bmove_allign(gptr dst,const gptr src,uint len);
|
||||
#endif
|
||||
|
||||
#if (!defined(USE_BMOVE512) || defined(HAVE_purify)) && !defined(bmove512)
|
||||
#define bmove512(A,B,C) memcpy(A,B,C)
|
||||
#endif
|
||||
@ -123,44 +115,44 @@ extern void bmove_allign(gptr dst,const gptr src,uint len);
|
||||
/* Prototypes for string functions */
|
||||
|
||||
#if !defined(bfill) && !defined(HAVE_BFILL)
|
||||
extern void bfill(gptr dst,uint len,pchar fill);
|
||||
extern void bfill(gptr dst, size_t len, pchar fill);
|
||||
#endif
|
||||
|
||||
#if !defined(bzero) && !defined(HAVE_BZERO)
|
||||
extern void bzero(gptr dst,uint len);
|
||||
extern void bzero(gptr dst, size_t len);
|
||||
#endif
|
||||
|
||||
#if !defined(bcmp) && !defined(HAVE_BCMP)
|
||||
extern int bcmp(const char *s1,const char *s2,uint len);
|
||||
extern int bcmp(const char *s1,const char *s2, size_t len);
|
||||
#ifdef HAVE_purify
|
||||
extern int my_bcmp(const char *s1,const char *s2,uint len);
|
||||
extern int my_bcmp(const char *s1,const char *s2, size_t len);
|
||||
#define bcmp(A,B,C) my_bcmp((A),(B),(C))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef bmove512
|
||||
extern void bmove512(gptr dst,const gptr src,uint len);
|
||||
extern void bmove512(gptr dst,const gptr src, size_t len);
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_BMOVE) && !defined(bmove)
|
||||
extern void bmove(char *dst, const char *src,uint len);
|
||||
extern void bmove(char *dst, const char *src, size_t len);
|
||||
#endif
|
||||
|
||||
extern void bmove_upp(char *dst,const char *src,uint len);
|
||||
extern void bchange(char *dst,uint old_len,const char *src,
|
||||
uint new_len,uint tot_len);
|
||||
extern void strappend(char *s,uint len,pchar fill);
|
||||
extern void bmove_upp(char *dst,const char *src, size_t len);
|
||||
extern void bchange(char *dst, size_t old_len, const char *src,
|
||||
size_t new_len, size_t tot_len);
|
||||
extern void strappend(char *s,size_t len,pchar fill);
|
||||
extern char *strend(const char *s);
|
||||
extern char *strcend(const char *, pchar);
|
||||
extern char *strcend(const char *, char);
|
||||
extern char *strfield(char *src,int fields,int chars,int blanks,
|
||||
int tabch);
|
||||
extern char *strfill(my_string s,uint len,pchar fill);
|
||||
extern char *strfill(my_string s, size_t len, pchar fill);
|
||||
extern uint strinstr(const char *str,const char *search);
|
||||
extern uint r_strinstr(reg1 my_string str,int from, reg4 my_string search);
|
||||
extern char *strkey(char *dst,char *head,char *tail,char *flags);
|
||||
extern char *strmake(char *dst,const char *src,uint length);
|
||||
extern char *strmake(char *dst,const char *src, size_t length);
|
||||
#ifndef strmake_overlapp
|
||||
extern char *strmake_overlapp(char *dst,const char *src, uint length);
|
||||
extern char *strmake_overlapp(char *dst,const char *src, size_t length);
|
||||
#endif
|
||||
|
||||
#ifndef strmov
|
||||
@ -172,9 +164,9 @@ extern char *strcont(const char *src,const char *set);
|
||||
extern char *strxcat _VARARGS((char *dst,const char *src, ...));
|
||||
extern char *strxmov _VARARGS((char *dst,const char *src, ...));
|
||||
extern char *strxcpy _VARARGS((char *dst,const char *src, ...));
|
||||
extern char *strxncat _VARARGS((char *dst,uint len, const char *src, ...));
|
||||
extern char *strxnmov _VARARGS((char *dst,uint len, const char *src, ...));
|
||||
extern char *strxncpy _VARARGS((char *dst,uint len, const char *src, ...));
|
||||
extern char *strxncat _VARARGS((char *dst, size_t len, const char *src, ...));
|
||||
extern char *strxnmov _VARARGS((char *dst, size_t len, const char *src, ...));
|
||||
extern char *strxncpy _VARARGS((char *dst, size_t len, const char *src, ...));
|
||||
|
||||
/* Prototypes of normal stringfunctions (with may ours) */
|
||||
|
||||
@ -188,9 +180,6 @@ extern int strcmp(const char *, const char *);
|
||||
extern size_t strlen(const char *);
|
||||
#endif
|
||||
#endif
|
||||
#ifndef HAVE_STRNLEN
|
||||
extern uint strnlen(const char *s, uint n);
|
||||
#endif
|
||||
|
||||
#if !defined(__cplusplus)
|
||||
#ifndef HAVE_STRPBRK
|
||||
@ -238,7 +227,7 @@ extern ulonglong strtoull(const char *str, char **ptr, int base);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus) && !defined(OS2)
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1,275 +0,0 @@
|
||||
|
||||
#define HAVE_GETHOSTBYNAME_R_GLIBC2_STYLE 1
|
||||
|
||||
/*
|
||||
* Include file constants (processed in LibmysqlIncludeFiles.txt 1
|
||||
*/
|
||||
#define HAVE_ALLOCA_H 1
|
||||
#define HAVE_ARPA_INET_H 1
|
||||
#define HAVE_CRYPT_H 1
|
||||
#define HAVE_DIRENT_H 1
|
||||
#define HAVE_DLFCN_H 1
|
||||
#define HAVE_EXECINFO_H 1
|
||||
#define HAVE_FCNTL_H 1
|
||||
#define HAVE_FENV_H 1
|
||||
#define HAVE_FLOAT_H 1
|
||||
/* #undef HAVE_FPU_CONTROL_H */
|
||||
#define HAVE_GRP_H 1
|
||||
/* #undef HAVE_IEEEFP_H */
|
||||
#define HAVE_LIMITS_H 1
|
||||
#define HAVE_MALLOC_H 1
|
||||
#define HAVE_MEMORY_H 1
|
||||
#define HAVE_NETINET_IN_H 1
|
||||
#define HAVE_PATHS_H 1
|
||||
#define HAVE_PWD_H 1
|
||||
#define HAVE_SCHED_H 1
|
||||
/* #undef HAVE_SELECT_H */
|
||||
#define HAVE_STDDEF_H 1
|
||||
#define HAVE_STDINT_H 1
|
||||
#define HAVE_STDLIB_H 1
|
||||
#define HAVE_STRING_H 1
|
||||
#define HAVE_STRINGS_H 1
|
||||
/* #undef HAVE_SYNCH_H */
|
||||
/* #undef HAVE_SYS_FPU_H */
|
||||
#define HAVE_SYS_IOCTL_H 1
|
||||
#define HAVE_SYS_IPC_H 1
|
||||
#define HAVE_SYS_MMAN_H 1
|
||||
#define HAVE_SYS_PRCTL_H 1
|
||||
#define HAVE_SYS_SELECT_H 1
|
||||
#define HAVE_SYS_SHM_H 1
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
/* #undef HAVE_SYS_STREAM_H */
|
||||
#define HAVE_SYS_TIMEB_H 1
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
#define HAVE_SYS_UN_H 1
|
||||
/* #undef HAVE_SYSENT_H */
|
||||
#define HAVE_TERMIO_H 1
|
||||
#define HAVE_TERMIOS_H 1
|
||||
#define HAVE_UNISTD_H 1
|
||||
#define HAVE_UTIME_H 1
|
||||
|
||||
/*
|
||||
* function definitions - processed in LibmysqlFunctions.txt
|
||||
*/
|
||||
#define HAVE_ACCESS 1
|
||||
/* #undef HAVE_AIOWAIT */
|
||||
#define HAVE_ALARM 1
|
||||
/* #undef HAVE_ALLOCA */
|
||||
#define HAVE_BCMP 1
|
||||
/* #undef HAVE_BFILL */
|
||||
/* #undef HAVE_BMOVE */
|
||||
#define HAVE_BZERO 1
|
||||
/* #undef HAVE_CLOCK_GETTIME */
|
||||
/* #undef HAVE_COMPRESS */
|
||||
/* #undef HAVE_CRYPT */
|
||||
/* #undef HAVE_DLERROR */
|
||||
/* #undef HAVE_DLOPEN */
|
||||
#define HAVE_FCHMOD 1
|
||||
#define HAVE_FCNTL 1
|
||||
/* #undef HAVE_FCONVERT */
|
||||
#define HAVE_FDATASYNC 1
|
||||
/* #undef HAVE_FESETROUND */
|
||||
#define HAVE_FINITE 1
|
||||
#define HAVE_FSEEKO 1
|
||||
#define HAVE_FSYNC 1
|
||||
#define HAVE_GETADDRINFO 1
|
||||
#define HAVE_GETCWD 1
|
||||
#define HAVE_GETHOSTBYADDR_R 1
|
||||
#define HAVE_GETHOSTBYNAME_R 1
|
||||
/* #undef HAVE_GETHRTIME */
|
||||
#define HAVE_GETNAMEINFO 1
|
||||
#define HAVE_GETPAGESIZE 1
|
||||
#define HAVE_GETPASS 1
|
||||
/* #undef HAVE_GETPASSPHRASE */
|
||||
#define HAVE_GETPWNAM 1
|
||||
#define HAVE_GETPWUID 1
|
||||
#define HAVE_GETRLIMIT 1
|
||||
#define HAVE_GETRUSAGE 1
|
||||
#define HAVE_GETWD 1
|
||||
#define HAVE_GMTIME_R 1
|
||||
#define HAVE_INITGROUPS 1
|
||||
#define HAVE_LDIV 1
|
||||
#define HAVE_LOCALTIME_R 1
|
||||
/* #undef HAVE_LOG2 */
|
||||
#define HAVE_LONGJMP 1
|
||||
#define HAVE_LSTAT 1
|
||||
#define HAVE_MADVISE 1
|
||||
#define HAVE_MALLINFO 1
|
||||
#define HAVE_MEMALIGN 1
|
||||
#define HAVE_MEMCPY 1
|
||||
#define HAVE_MEMMOVE 1
|
||||
#define HAVE_MKSTEMP 1
|
||||
#define HAVE_MLOCK 1
|
||||
#define HAVE_MLOCKALL 1
|
||||
#define HAVE_MMAP 1
|
||||
#define HAVE_MMAP64 1
|
||||
#define HAVE_PERROR 1
|
||||
#define HAVE_POLL 1
|
||||
#define HAVE_PREAD 1
|
||||
/* #undef HAVE_PTHREAD_ATTR_CREATE */
|
||||
/* #undef HAVE_PTHREAD_ATTR_GETSTACKSIZE */
|
||||
/* #undef HAVE_PTHREAD_ATTR_SETPRIO */
|
||||
#define HAVE_PTHREAD_ATTR_SETSCHEDPARAM 1
|
||||
#define HAVE_PTHREAD_ATTR_SETSCOPE 1
|
||||
/* #undef HAVE_PTHREAD_ATTR_SETSTACKSIZE */
|
||||
/* #undef HAVE_PTHREAD_CONDATTR_CREATE */
|
||||
/* #undef HAVE_PTHREAD_INIT */
|
||||
/* #undef HAVE_PTHREAD_KEY_DELETE */
|
||||
/* #undef HAVE_PTHREAD_KILL */
|
||||
/* #undef HAVE_PTHREAD_RWLOCK_RDLOCK */
|
||||
/* #undef HAVE_PTHREAD_SETPRIO_NP */
|
||||
#define HAVE_PTHREAD_SETSCHEDPARAM 1
|
||||
/* #undef HAVE_PTHREAD_SIGMASK */
|
||||
/* #undef HAVE_PTHREAD_THREADMASK */
|
||||
/* #undef HAVE_PTHREAD_YIELD_NP */
|
||||
#define HAVE_READDIR_R 1
|
||||
#define HAVE_READLINK 1
|
||||
#define HAVE_REALPATH 1
|
||||
#define HAVE_RENAME 1
|
||||
#define HAVE_SCHED_YIELD 1
|
||||
#define HAVE_SELECT 1
|
||||
/* #undef HAVE_SETFD */
|
||||
/* #undef HAVE_SETFILEPOINTER */
|
||||
#define HAVE_SIGNAL 1
|
||||
#define HAVE_SIGACTION 1
|
||||
/* #undef HAVE_SIGTHREADMASK */
|
||||
#define HAVE_SIGWAIT 1
|
||||
#define HAVE_SLEEP 1
|
||||
#define HAVE_SNPRINTF 1
|
||||
#define HAVE_STPCPY 1
|
||||
#define HAVE_STRERROR 1
|
||||
/* #undef HAVE_STRLCPY */
|
||||
#define HAVE_STRNLEN 1
|
||||
#define HAVE_STRPBRK 1
|
||||
#define HAVE_STRSEP 1
|
||||
#define HAVE_STRSTR 1
|
||||
#define HAVE_STRTOK_R 1
|
||||
#define HAVE_STRTOL 1
|
||||
#define HAVE_STRTOLL 1
|
||||
#define HAVE_STRTOUL 1
|
||||
#define HAVE_STRTOULL 1
|
||||
/* #undef HAVE_TELL */
|
||||
/* #undef HAVE_THR_SETCONCURRENCY */
|
||||
/* #undef HAVE_THR_YIELD */
|
||||
#define HAVE_VASPRINTF 1
|
||||
#define HAVE_VSNPRINTF 1
|
||||
|
||||
/*
|
||||
* types and sizes
|
||||
*/
|
||||
/* Types we may use */
|
||||
#define SIZEOF_CHAR 1
|
||||
#if SIZEOF_CHAR
|
||||
# define HAVE_CHAR 1
|
||||
#endif
|
||||
|
||||
#define SIZEOF_CHARP 8
|
||||
#if SIZEOF_CHARP
|
||||
# define HAVE_CHARP 1
|
||||
#endif
|
||||
|
||||
#define SIZEOF_SHORT 2
|
||||
#if SIZEOF_SHORT
|
||||
# define HAVE_SHORT 1
|
||||
#endif
|
||||
|
||||
#define SIZEOF_INT 4
|
||||
#if SIZEOF_INT
|
||||
# define HAVE_INT 1
|
||||
#endif
|
||||
|
||||
#define SIZEOF_LONG 8
|
||||
#if SIZEOF_LONG
|
||||
# define HAVE_LONG 1
|
||||
#endif
|
||||
|
||||
#define SIZEOF_LONG_LONG 8
|
||||
#if SIZEOF_LONG_LONG
|
||||
# define HAVE_LONG_LONG 1
|
||||
#endif
|
||||
|
||||
#define SIZEOF_OFF_T 8
|
||||
#if SIZEOF_OFF_T
|
||||
# define HAVE_OFF_T 1
|
||||
#endif
|
||||
|
||||
#define SIZEOF_SIGSET_T 128
|
||||
#if SIZEOF_SIGSET_T
|
||||
# define HAVE_SIGSET_T 1
|
||||
#endif
|
||||
|
||||
#define SIZEOF_SIZE_T 8
|
||||
#if SIZEOF_SIZE_T
|
||||
# define HAVE_SIZE_T 1
|
||||
#endif
|
||||
|
||||
/* #undef SIZEOF_UCHAR */
|
||||
#if SIZEOF_UCHAR
|
||||
# define HAVE_UCHAR 1
|
||||
#endif
|
||||
|
||||
#define SIZEOF_UINT 4
|
||||
#if SIZEOF_UINT
|
||||
# define HAVE_UINT 1
|
||||
#endif
|
||||
|
||||
#define SIZEOF_ULONG 8
|
||||
#if SIZEOF_ULONG
|
||||
# define HAVE_ULONG 1
|
||||
#endif
|
||||
|
||||
/* #undef SIZEOF_INT8 */
|
||||
#if SIZEOF_INT8
|
||||
# define HAVE_INT8 1
|
||||
#endif
|
||||
/* #undef SIZEOF_UINT8 */
|
||||
#if SIZEOF_UINT8
|
||||
# define HAVE_UINT8 1
|
||||
#endif
|
||||
|
||||
/* #undef SIZEOF_INT16 */
|
||||
#if SIZEOF_INT16
|
||||
# define HAVE_INT16 1
|
||||
#endif
|
||||
/* #undef SIZEOF_UINT16 */
|
||||
#if SIZEOF_UINT16
|
||||
# define HAVE_UINT16 1
|
||||
#endif
|
||||
|
||||
/* #undef SIZEOF_INT32 */
|
||||
#if SIZEOF_INT32
|
||||
# define HAVE_INT32 1
|
||||
#endif
|
||||
/* #undef SIZEOF_UINT32 */
|
||||
#if SIZEOF_UINT32
|
||||
# define HAVE_UINT32 1
|
||||
#endif
|
||||
/* #undef SIZEOF_U_INT32_T */
|
||||
#if SIZEOF_U_INT32_T
|
||||
# define HAVE_U_INT32_T 1
|
||||
#endif
|
||||
|
||||
/* #undef SIZEOF_INT64 */
|
||||
#if SIZEOF_INT64
|
||||
# define HAVE_INT64 1
|
||||
#endif
|
||||
/* #undef SIZEOF_UINT64 */
|
||||
#if SIZEOF_UINT64
|
||||
# define HAVE_UINT64 1
|
||||
#endif
|
||||
|
||||
/* #undef SIZEOF_SOCKLEN_T */
|
||||
#if SIZEOF_SOCKLEN_T
|
||||
# define HAVE_SOCKLEN_T 1
|
||||
#endif
|
||||
|
||||
#define RETSIGTYPE void
|
||||
#define RETQSORTTYPE void
|
||||
|
||||
/*
|
||||
* various other defines
|
||||
*/
|
||||
/* #undef HAVE_THREADS */
|
||||
#define SHAREDIR "share"
|
||||
#define DEFAULT_CHARSET_HOME "/usr/local"
|
@ -264,6 +264,8 @@
|
||||
# define HAVE_SOCKLEN_T 1
|
||||
#endif
|
||||
|
||||
#cmakedefine SOCKET_SIZE_TYPE @SOCKET_SIZE_TYPE@
|
||||
|
||||
#cmakedefine RETSIGTYPE @RETSIGTYPE@
|
||||
#cmakedefine RETQSORTTYPE @RETQSORTTYPE@
|
||||
|
||||
|
@ -21,30 +21,9 @@
|
||||
#ifndef _global_h
|
||||
#define _global_h
|
||||
|
||||
#if defined( __EMX__) && !defined( MYSQL_SERVER)
|
||||
/* moved here to use below VOID macro redefinition */
|
||||
#define INCL_BASE
|
||||
#define INCL_NOPMAPI
|
||||
#include <os2.h>
|
||||
#endif /* __EMX__ */
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
/* We use a Unix API, so pretend it's not Windows */
|
||||
#undef WIN
|
||||
#undef WIN32
|
||||
#undef _WIN
|
||||
#undef _WIN32
|
||||
#undef _WIN64
|
||||
#undef __WIN__
|
||||
#undef __WIN32__
|
||||
#define HAVE_ERRNO_AS_DEFINE
|
||||
#endif /* __CYGWIN__ */
|
||||
|
||||
|
||||
#ifdef __WIN__
|
||||
#ifdef _WIN32
|
||||
#include <config-win.h>
|
||||
#elif defined(OS2)
|
||||
#include <config-os2.h>
|
||||
#else
|
||||
#include <my_config.h>
|
||||
#if defined(__cplusplus) && defined(inline)
|
||||
@ -76,7 +55,7 @@
|
||||
#define __STDC_EXT__ 1 /* To get large file support on hpux */
|
||||
#endif
|
||||
|
||||
#if defined(THREAD) && !defined(__WIN__) && !defined(OS2)
|
||||
#if defined(THREAD) && !defined(_WIN32)
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
#define _POSIX_PTHREAD_SEMANTICS /* We want posix threads */
|
||||
#endif
|
||||
@ -224,6 +203,7 @@ double my_ulonglong2double(unsigned long long A);
|
||||
#include <asm/atomic.h>
|
||||
#endif
|
||||
#include <errno.h> /* Recommended by debian */
|
||||
#include <assert.h>
|
||||
|
||||
/* Go around some bugs in different OS and compilers */
|
||||
#if defined(_HPUX_SOURCE) && defined(HAVE_SYS_STREAM_H)
|
||||
@ -247,9 +227,7 @@ double my_ulonglong2double(unsigned long long A);
|
||||
#define POSIX_MISTAKE 1 /* regexp: Fix stupid spec error */
|
||||
#define USE_REGEX 1 /* We want the use the regex library */
|
||||
/* Do not define for ultra sparcs */
|
||||
#ifndef OS2
|
||||
#define USE_BMOVE512 1 /* Use this unless the system bmove is faster */
|
||||
#endif
|
||||
|
||||
/* Paranoid settings. Define I_AM_PARANOID if you are paranoid */
|
||||
#ifdef I_AM_PARANOID
|
||||
@ -279,8 +257,10 @@ int __void__;
|
||||
|
||||
#if defined(_lint) || defined(FORCE_INIT_OF_VARS)
|
||||
#define LINT_INIT(var) var=0 /* No uninitialize-warning */
|
||||
#define LINT_INIT_STRUCT(var) bzero(&var, sizeof(var)) /* No uninitialize-warning */
|
||||
#else
|
||||
#define LINT_INIT(var)
|
||||
#define LINT_INIT_STRUCT(var)
|
||||
#endif
|
||||
|
||||
/* Define some useful general macros */
|
||||
@ -360,8 +340,9 @@ typedef unsigned short ushort;
|
||||
/* Some types that is different between systems */
|
||||
|
||||
typedef int File; /* File descriptor */
|
||||
#ifndef Socket_defined
|
||||
#ifndef my_socket_defined
|
||||
typedef int my_socket; /* File descriptor for sockets */
|
||||
#define my_socket_defined
|
||||
#define INVALID_SOCKET -1
|
||||
#endif
|
||||
/* Type for fuctions that handles signals */
|
||||
@ -394,7 +375,7 @@ typedef int (*qsort_cmp)(const void *,const void *);
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
/* typedef SOCKET_SIZE_TYPE size_socket; */
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef SOCKOPT_OPTLEN_TYPE
|
||||
@ -483,7 +464,7 @@ typedef int (*qsort_cmp)(const void *,const void *);
|
||||
#define NO_PISAM /* Not needed anymore */
|
||||
#define NO_MISAM /* Not needed anymore */
|
||||
#define NO_HASH /* Not needed anymore */
|
||||
#ifdef __WIN__
|
||||
#ifdef _WIN32
|
||||
#define NO_DIR_LIBRARY /* Not standar dir-library */
|
||||
#define USE_MY_STAT_STRUCT /* For my_lib */
|
||||
#endif
|
||||
@ -505,17 +486,14 @@ extern void init_my_atof(void);
|
||||
extern double my_atof(const char*);
|
||||
#endif
|
||||
#undef remove /* Crashes MySQL on SCO 5.0.0 */
|
||||
#ifndef __WIN__
|
||||
#ifdef OS2
|
||||
#define closesocket(A) soclose(A)
|
||||
#else
|
||||
#ifndef _WIN32
|
||||
#define closesocket(A) close(A)
|
||||
#endif
|
||||
#ifndef ulonglong2double
|
||||
#define ulonglong2double(A) ((double) (A))
|
||||
#define my_off_t2double(A) ((double) (A))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef offsetof
|
||||
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
|
||||
@ -684,24 +662,17 @@ typedef ulonglong my_off_t;
|
||||
typedef unsigned long my_off_t;
|
||||
#endif
|
||||
#define MY_FILEPOS_ERROR (~(my_off_t) 0)
|
||||
#if !defined(__WIN__) && !defined(OS2)
|
||||
#ifndef _WIN32
|
||||
typedef off_t os_off_t;
|
||||
#endif
|
||||
|
||||
#if defined(__WIN__)
|
||||
#if defined(_WIN32)
|
||||
#define socket_errno WSAGetLastError()
|
||||
#define SOCKET_EINTR WSAEINTR
|
||||
#define SOCKET_EAGAIN WSAEINPROGRESS
|
||||
#define SOCKET_ENFILE ENFILE
|
||||
#define SOCKET_EMFILE EMFILE
|
||||
#elif defined(OS2)
|
||||
#define socket_errno sock_errno()
|
||||
#define SOCKET_EINTR SOCEINTR
|
||||
#define SOCKET_EAGAIN SOCEINPROGRESS
|
||||
#define SOCKET_EWOULDBLOCK SOCEWOULDBLOCK
|
||||
#define SOCKET_ENFILE SOCENFILE
|
||||
#define SOCKET_EMFILE SOCEMFILE
|
||||
#define closesocket(A) soclose(A)
|
||||
#define SOCKET_EWOULDBLOCK WSAEWOULDBLOCK
|
||||
#else /* Unix */
|
||||
#define socket_errno errno
|
||||
#define closesocket(A) close(A)
|
||||
@ -761,7 +732,7 @@ typedef char bool; /* Ordinary boolean values 0 1 */
|
||||
|
||||
#define NOT_FIXED_DEC 31
|
||||
|
||||
#ifdef __WIN__
|
||||
#ifdef _WIN32
|
||||
#define MYSQLND_LLU_SPEC "%I64u"
|
||||
#define MYSQLND_LL_SPEC "%I64d"
|
||||
#ifndef L64
|
||||
@ -773,7 +744,7 @@ typedef char bool; /* Ordinary boolean values 0 1 */
|
||||
#ifndef L64
|
||||
#define L64(x) x##LL
|
||||
#endif /* L64 */
|
||||
#endif /* __WIN__ */
|
||||
#endif /* _WIN32 */
|
||||
/*
|
||||
** Define-funktions for reading and storing in machine independent format
|
||||
** (low byte first)
|
||||
@ -782,7 +753,7 @@ typedef char bool; /* Ordinary boolean values 0 1 */
|
||||
/* Optimized store functions for Intel x86 */
|
||||
#define int1store(T,A) *((int8*) (T)) = (A)
|
||||
#define uint1korr(A) (*(((uint8*)(A))))
|
||||
#if defined(__i386__) || defined(__WIN__)
|
||||
#if defined(__i386__) || defined(_WIN32)
|
||||
#define sint2korr(A) (*((int16 *) (A)))
|
||||
#define sint3korr(A) ((int32) ((((uchar) (A)[2]) & 128) ? \
|
||||
(((uint32) 255L << 24) | \
|
||||
@ -794,7 +765,7 @@ typedef char bool; /* Ordinary boolean values 0 1 */
|
||||
((uint32) (uchar) (A)[0])))
|
||||
#define sint4korr(A) (*((long *) (A)))
|
||||
#define uint2korr(A) (*((uint16 *) (A)))
|
||||
#if defined(HAVE_purify) && !defined(__WIN__)
|
||||
#if defined(HAVE_purify) && !defined(_WIN32)
|
||||
#define uint3korr(A) (uint32) (((uint32) ((uchar) (A)[0])) +\
|
||||
(((uint32) ((uchar) (A)[1])) << 8) +\
|
||||
(((uint32) ((uchar) (A)[2])) << 16))
|
||||
@ -1075,4 +1046,29 @@ do { doubleget_union _tmp; \
|
||||
#define statistic_add(V,C,L) (V)+=(C)
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define SO_EXT ".dll"
|
||||
#elif defined(__APPLE__)
|
||||
#define SO_EXT ".dylib"
|
||||
#else
|
||||
#define SO_EXT ".so"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DLOPEN
|
||||
#ifdef _WIN32
|
||||
#define dlsym(lib, name) GetProcAddress((HMODULE)lib, name)
|
||||
#define dlopen(libname, unused) LoadLibraryEx(libname, NULL, 0)
|
||||
#define dlclose(lib) FreeLibrary((HMODULE)lib)
|
||||
#elif defined(HAVE_DLFCN_H)
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
#if HAVE_DLERROR
|
||||
#define dlerror() ""
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef RTLD_NOW
|
||||
#define RTLD_NOW 1
|
||||
#endif
|
||||
|
||||
#endif /* _global_h */
|
||||
|
@ -34,7 +34,7 @@ extern LIST *list_delete(LIST *root,LIST *element);
|
||||
extern LIST *list_cons(void *data,LIST *root);
|
||||
extern LIST *list_reverse(LIST *root);
|
||||
extern void list_free(LIST *root,unsigned int free_data);
|
||||
extern uint list_length(LIST *list);
|
||||
extern unsigned int list_length(LIST *list);
|
||||
extern int list_walk(LIST *list,list_walk_action action,gptr argument);
|
||||
|
||||
#define rest(a) ((a)->next)
|
||||
|
@ -22,7 +22,7 @@
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if !defined(MSDOS) && !defined(__WIN__) && !defined(__BEOS__)
|
||||
#if !defined(MSDOS) && !defined(_WIN32) && !defined(__BEOS__)
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
@ -32,7 +32,7 @@ extern "C" {
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#endif /* !defined(MSDOS) && !defined(__WIN__) */
|
||||
#endif /* !defined(MSDOS) && !defined(_WIN32) */
|
||||
|
||||
void my_inet_ntoa(struct in_addr in, char *buf);
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if defined(__WIN__) || defined(OS2)
|
||||
#if defined(_WIN32) || defined(OS2)
|
||||
|
||||
#ifdef OS2
|
||||
typedef ULONG HANDLE;
|
||||
@ -60,20 +60,20 @@ typedef struct st_pthread_link {
|
||||
|
||||
typedef struct {
|
||||
uint32 waiting;
|
||||
#ifdef OS2
|
||||
HEV semaphore;
|
||||
#else
|
||||
HANDLE semaphore;
|
||||
#endif
|
||||
|
||||
enum {
|
||||
SIGNAL = 0,
|
||||
BROADCAST = 1,
|
||||
MAX_EVENTS = 2
|
||||
} EVENTS;
|
||||
HANDLE events[MAX_EVENTS];
|
||||
CRITICAL_SECTION waiters_count_lock;
|
||||
} pthread_cond_t;
|
||||
|
||||
|
||||
#ifndef OS2
|
||||
struct timespec { /* For pthread_cond_timedwait() */
|
||||
time_t tv_sec;
|
||||
long tv_nsec;
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef int pthread_mutexattr_t;
|
||||
#define win_pthread_self my_thread_var->pthread_self
|
||||
@ -104,7 +104,6 @@ struct tm *localtime_r(const time_t *timep,struct tm *tmp);
|
||||
void pthread_exit(void *a); /* was #define pthread_exit(A) ExitThread(A)*/
|
||||
|
||||
#ifndef OS2
|
||||
#define ETIMEDOUT 145 /* Win32 doesn't have this */
|
||||
#define getpid() GetCurrentThreadId()
|
||||
#endif
|
||||
#define pthread_self() win_pthread_self
|
||||
@ -132,15 +131,7 @@ void pthread_exit(void *a); /* was #define pthread_exit(A) ExitThread(A)*/
|
||||
#endif /* USE_TLS */
|
||||
|
||||
#define pthread_equal(A,B) ((A) == (B))
|
||||
#ifdef OS2
|
||||
extern int pthread_mutex_init (pthread_mutex_t *, const pthread_mutexattr_t *);
|
||||
extern int pthread_mutex_lock (pthread_mutex_t *);
|
||||
extern int pthread_mutex_unlock (pthread_mutex_t *);
|
||||
extern int pthread_mutex_destroy (pthread_mutex_t *);
|
||||
#define my_pthread_setprio(A,B) DosSetPriority(PRTYS_THREAD,PRTYC_NOCHANGE, B, A)
|
||||
#define pthread_kill(A,B) raise(B)
|
||||
#define pthread_exit(A) pthread_dummy()
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
#define pthread_mutex_init(A,B) InitializeCriticalSection(A)
|
||||
#define pthread_mutex_lock(A) (EnterCriticalSection(A),0)
|
||||
#define pthread_mutex_trylock(A) (WaitForSingleObject((A), 0) == WAIT_TIMEOUT)
|
||||
@ -148,7 +139,7 @@ extern int pthread_mutex_destroy (pthread_mutex_t *);
|
||||
#define pthread_mutex_destroy(A) DeleteCriticalSection(A)
|
||||
#define my_pthread_setprio(A,B) SetThreadPriority(GetCurrentThread(), (B))
|
||||
#define pthread_kill(A,B) pthread_dummy(0)
|
||||
#endif /* OS2 */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/* Dummy defines for easier code */
|
||||
#define pthread_attr_setdetachstate(A,B) pthread_dummy(0)
|
||||
@ -427,7 +418,7 @@ struct tm *localtime_r(const time_t *clock, struct tm *res);
|
||||
#define HAVE_PTHREAD_KILL
|
||||
#endif
|
||||
|
||||
#endif /* defined(__WIN__) */
|
||||
#endif /* defined(_WIN32) */
|
||||
|
||||
#if defined(HPUX) && !defined(DONT_REMAP_PTHREAD_FUNCTIONS)
|
||||
#undef pthread_cond_timedwait
|
||||
|
@ -23,21 +23,21 @@
|
||||
|
||||
#define MYSQL_NO_DATA 100
|
||||
#define MYSQL_DATA_TRUNCATED 101
|
||||
#define MYSQL_DEFAULT_PREFETCH_ROWS (ulong) 1
|
||||
#define MYSQL_DEFAULT_PREFETCH_ROWS (unsigned long) 1
|
||||
|
||||
|
||||
#define SET_CLIENT_STMT_ERROR(a, b, c, d) \
|
||||
{ \
|
||||
(a).error_no= (b);\
|
||||
strncpy((a).sqlstate, (c), sizeof((a).sqlstate));\
|
||||
strncpy((a).error, (d) ? (d) : ER((b)), sizeof((a).error));\
|
||||
(a)->last_errno= (b);\
|
||||
strncpy((a)->sqlstate, (c), sizeof((a)->sqlstate));\
|
||||
strncpy((a)->last_error, (d) ? (d) : ER((b)), sizeof((a)->last_error));\
|
||||
}
|
||||
|
||||
#define CLEAR_CLIENT_STMT_ERROR(a) \
|
||||
{ \
|
||||
(a).error_no= 0;\
|
||||
strcpy((a).sqlstate, "00000");\
|
||||
(a).error[0]= 0;\
|
||||
(a)->last_errno= 0;\
|
||||
strcpy((a)->sqlstate, "00000");\
|
||||
(a)->last_error[0]= 0;\
|
||||
}
|
||||
|
||||
#define MYSQL_PS_SKIP_RESULT_W_LEN -1
|
||||
@ -48,13 +48,7 @@
|
||||
typedef struct st_mysql_stmt MYSQL_STMT;
|
||||
|
||||
typedef MYSQL_RES* (*mysql_stmt_use_or_store_func)(MYSQL_STMT *);
|
||||
/*
|
||||
enum enum_mysql_stmt_state
|
||||
{
|
||||
MYSQL_STMT_INIT_DONE= 1, MYSQL_STMT_PREPARE_DONE, MYSQL_STMT_EXECUTE_DONE,
|
||||
MYSQL_STMT_FETCH_DONE
|
||||
};
|
||||
*/
|
||||
|
||||
enum enum_stmt_attr_type
|
||||
{
|
||||
STMT_ATTR_UPDATE_MAX_LENGTH,
|
||||
@ -142,7 +136,7 @@ struct st_mysqlnd_stmt_methods
|
||||
MYSQL_RES * (*store_result)(const MYSQL_STMT * stmt);
|
||||
MYSQL_RES * (*get_result)(const MYSQL_STMT * stmt);
|
||||
my_bool (*free_result)(const MYSQL_STMT * stmt);
|
||||
my_bool (*seek_data)(const const MYSQL_STMT * stmt, my_ulonglong row);
|
||||
my_bool (*seek_data)(const MYSQL_STMT * stmt, my_ulonglong row);
|
||||
my_bool (*reset)(const MYSQL_STMT * stmt);
|
||||
my_bool (*close)(const MYSQL_STMT * stmt); /* private */
|
||||
my_bool (*dtor)(const MYSQL_STMT * stmt); /* use this for mysqlnd_stmt_close */
|
||||
@ -156,17 +150,17 @@ struct st_mysqlnd_stmt_methods
|
||||
const char * const data, unsigned long length);
|
||||
MYSQL_RES *(*get_parameter_metadata)(const MYSQL_STMT * stmt);
|
||||
MYSQL_RES *(*get_result_metadata)(const MYSQL_STMT * stmt);
|
||||
my_ulonglong (*get_last_insert_id)(const const MYSQL_STMT * stmt);
|
||||
my_ulonglong (*get_affected_rows)(const const MYSQL_STMT * stmt);
|
||||
my_ulonglong (*get_num_rows)(const const MYSQL_STMT * stmt);
|
||||
my_ulonglong (*get_last_insert_id)(const MYSQL_STMT * stmt);
|
||||
my_ulonglong (*get_affected_rows)(const MYSQL_STMT * stmt);
|
||||
my_ulonglong (*get_num_rows)(const MYSQL_STMT * stmt);
|
||||
|
||||
unsigned int (*get_param_count)(const const MYSQL_STMT * stmt);
|
||||
unsigned int (*get_field_count)(const const MYSQL_STMT * stmt);
|
||||
unsigned int (*get_warning_count)(const const MYSQL_STMT * stmt);
|
||||
unsigned int (*get_param_count)(const MYSQL_STMT * stmt);
|
||||
unsigned int (*get_field_count)(const MYSQL_STMT * stmt);
|
||||
unsigned int (*get_warning_count)(const MYSQL_STMT * stmt);
|
||||
|
||||
unsigned int (*get_error_no)(const const MYSQL_STMT * stmt);
|
||||
const char * (*get_error_str)(const const MYSQL_STMT * stmt);
|
||||
const char * (*get_sqlstate)(const const MYSQL_STMT * stmt);
|
||||
unsigned int (*get_error_no)(const MYSQL_STMT * stmt);
|
||||
const char * (*get_error_str)(const MYSQL_STMT * stmt);
|
||||
const char * (*get_sqlstate)(const MYSQL_STMT * stmt);
|
||||
|
||||
my_bool (*get_attribute)(const MYSQL_STMT * stmt, enum enum_stmt_attr_type attr_type, const void * value);
|
||||
my_bool (*set_attribute)(const MYSQL_STMT * stmt, enum enum_stmt_attr_type attr_type, const void * value);
|
||||
@ -177,7 +171,7 @@ typedef int (*mysql_stmt_fetch_row_func)(MYSQL_STMT *stmt, unsigned char **row)
|
||||
struct st_mysql_stmt
|
||||
{
|
||||
MEM_ROOT mem_root;
|
||||
MYSQL *conn;
|
||||
MYSQL *mysql;
|
||||
unsigned long stmt_id;
|
||||
unsigned long flags;/* cursor is set here */
|
||||
enum_mysqlnd_stmt_state state;
|
||||
@ -185,15 +179,18 @@ struct st_mysql_stmt
|
||||
unsigned int field_count;
|
||||
unsigned int param_count;
|
||||
unsigned char send_types_to_server;
|
||||
MYSQL_BIND *param_bind;
|
||||
MYSQL_BIND *result_bind;
|
||||
MYSQL_BIND *params;
|
||||
MYSQL_BIND *bind;
|
||||
MYSQL_DATA result; /* we don't use mysqlnd's result set logic */
|
||||
MYSQL_ROWS *result_cursor;
|
||||
my_bool bind_result_done;
|
||||
my_bool bind_param_done;
|
||||
|
||||
mysql_upsert_status upsert_status;
|
||||
|
||||
mysql_error_info error_info;
|
||||
unsigned int last_errno;
|
||||
char last_error[MYSQL_ERRMSG_SIZE+1];
|
||||
char sqlstate[SQLSTATE_LENGTH + 1];
|
||||
|
||||
my_bool update_max_length;
|
||||
unsigned long prefetch_rows;
|
||||
@ -213,14 +210,14 @@ struct st_mysql_perm_bind {
|
||||
ps_field_fetch_func func;
|
||||
/* should be signed int */
|
||||
int pack_len;
|
||||
ulong max_len;
|
||||
unsigned long max_len;
|
||||
};
|
||||
|
||||
extern struct st_mysql_perm_bind mysql_ps_fetch_functions[MYSQL_TYPE_GEOMETRY + 1];
|
||||
ulong net_safe_read(MYSQL *mysql);
|
||||
unsigned long net_safe_read(MYSQL *mysql);
|
||||
void mysql_init_ps_subsystem(void);
|
||||
ulong net_field_length(unsigned char **packet);
|
||||
int simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg, uint length, my_bool skipp_check);
|
||||
unsigned long net_field_length(unsigned char **packet);
|
||||
int simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg, size_t length, my_bool skipp_check);
|
||||
/*
|
||||
* function prototypes
|
||||
*/
|
||||
@ -255,4 +252,6 @@ my_bool STDCALL mysql_stmt_reset(MYSQL_STMT *stmt);
|
||||
MYSQL_ROW_OFFSET STDCALL mysql_stmt_row_tell(MYSQL_STMT *stmt);
|
||||
MYSQL_ROW_OFFSET STDCALL mysql_stmt_row_seek(MYSQL_STMT *stmt, MYSQL_ROW_OFFSET new_row);
|
||||
unsigned long STDCALL mysql_stmt_param_count(MYSQL_STMT *stmt);
|
||||
my_bool STDCALL mysql_stmt_send_long_data(MYSQL_STMT *stmt, uint param_number, const char *data, ulong length);
|
||||
my_bool STDCALL mysql_stmt_send_long_data(MYSQL_STMT *stmt, unsigned int param_number, const char *data, unsigned long length);
|
||||
my_ulonglong STDCALL mysql_stmt_insert_id(MYSQL_STMT *stmt);
|
||||
my_ulonglong STDCALL mysql_stmt_num_rows(MYSQL_STMT *stmt);
|
@ -135,11 +135,11 @@ extern ulonglong safemalloc_mem_limit;
|
||||
#define TERMINATE(A) {}
|
||||
#define QUICK_SAFEMALLOC
|
||||
#define NORMAL_SAFEMALLOC
|
||||
extern gptr my_malloc(uint Size,myf MyFlags);
|
||||
extern gptr my_malloc(size_t Size,myf MyFlags);
|
||||
#define my_malloc_ci(SZ,FLAG) my_malloc( SZ, FLAG )
|
||||
extern gptr my_realloc(gptr oldpoint,uint Size,myf MyFlags);
|
||||
extern gptr my_realloc(gptr oldpoint, size_t Size,myf MyFlags);
|
||||
extern void my_no_flags_free(gptr ptr);
|
||||
extern gptr my_memdup(const byte *from,uint length,myf MyFlags);
|
||||
extern gptr my_memdup(const byte *from, size_t length,myf MyFlags);
|
||||
extern my_string my_strdup(const char *from,myf MyFlags);
|
||||
extern my_string my_strndup(const char *from, size_t length, myf MyFlags);
|
||||
#define my_free(PTR,FG) my_no_flags_free(PTR)
|
||||
@ -197,7 +197,8 @@ extern uint get_charset_number(const char *cs_name);
|
||||
extern const char *get_charset_name(uint cs_number);
|
||||
extern CHARSET_INFO *get_charset(uint cs_number, myf flags);
|
||||
extern my_bool set_default_charset(uint cs, myf flags);
|
||||
extern CHARSET_INFO *get_charset_by_name(const char *cs_name, myf flags);
|
||||
extern CHARSET_INFO *get_charset_by_name(const char *cs_name);
|
||||
extern CHARSET_INFO *get_charset_by_nr(uint cs_number);
|
||||
extern my_bool set_default_charset_by_name(const char *cs_name, myf flags);
|
||||
extern void free_charsets(void);
|
||||
extern char *list_charsets(myf want_flags); /* my_free() this string... */
|
||||
@ -223,7 +224,7 @@ extern int NEAR my_umask, /* Default creation mask */
|
||||
NEAR my_safe_to_handle_signal, /* Set when allowed to SIGTSTP */
|
||||
NEAR my_dont_interrupt; /* call remember_intr when set */
|
||||
extern my_bool NEAR mysys_uses_curses, my_use_symdir;
|
||||
extern long lCurMemory,lMaxMemory; /* from safemalloc */
|
||||
extern size_t lCurMemory,lMaxMemory; /* from safemalloc */
|
||||
|
||||
extern ulong my_default_record_cache_size;
|
||||
extern my_bool NEAR my_disable_locking,NEAR my_disable_async_io,
|
||||
@ -239,6 +240,11 @@ typedef struct wild_file_pack /* Struct to hold info when selecting files */
|
||||
my_string *wild; /* Pointer to wildcards */
|
||||
} WF_PACK;
|
||||
|
||||
struct my_rnd_struct {
|
||||
unsigned long seed1,seed2,max_value;
|
||||
double max_value_dbl;
|
||||
};
|
||||
|
||||
typedef struct st_typelib { /* Different types saved here */
|
||||
uint count; /* How many types */
|
||||
const char *name; /* Name of typelib */
|
||||
@ -285,7 +291,7 @@ typedef struct st_dynamic_array {
|
||||
|
||||
typedef struct st_dynamic_string {
|
||||
char *str;
|
||||
uint length,max_length,alloc_increment;
|
||||
size_t length,max_length,alloc_increment;
|
||||
} DYNAMIC_STRING;
|
||||
|
||||
|
||||
@ -363,10 +369,10 @@ typedef struct st_changeable_var {
|
||||
|
||||
#ifndef ST_USED_MEM_DEFINED
|
||||
#define ST_USED_MEM_DEFINED
|
||||
typedef struct st_used_mem { /* struct for once_alloc */
|
||||
struct st_used_mem *next; /* Next block in use */
|
||||
unsigned int left; /* memory left in block */
|
||||
unsigned int size; /* Size of block */
|
||||
typedef struct st_used_mem { /* struct for once_alloc */
|
||||
struct st_used_mem *next; /* Next block in use */
|
||||
size_t left; /* memory left in block */
|
||||
size_t size; /* Size of block */
|
||||
} USED_MEM;
|
||||
|
||||
typedef struct st_mem_root {
|
||||
@ -423,14 +429,14 @@ extern uint my_fwrite(FILE *stream,const byte *Buffer,uint Count,
|
||||
myf MyFlags);
|
||||
extern my_off_t my_fseek(FILE *stream,my_off_t pos,int whence,myf MyFlags);
|
||||
extern my_off_t my_ftell(FILE *stream,myf MyFlags);
|
||||
extern gptr _mymalloc(uint uSize,const char *sFile,
|
||||
extern gptr _mymalloc(size_t uSize,const char *sFile,
|
||||
uint uLine, myf MyFlag);
|
||||
extern gptr _myrealloc(gptr pPtr,uint uSize,const char *sFile,
|
||||
extern gptr _myrealloc(gptr pPtr,size_t uSize,const char *sFile,
|
||||
uint uLine, myf MyFlag);
|
||||
extern gptr my_multi_malloc _VARARGS((myf MyFlags, ...));
|
||||
extern void _myfree(gptr pPtr,const char *sFile,uint uLine, myf MyFlag);
|
||||
extern int _sanity(const char *sFile,unsigned int uLine);
|
||||
extern gptr _my_memdup(const byte *from,uint length,
|
||||
extern gptr _my_memdup(const byte *from, size_t length,
|
||||
const char *sFile, uint uLine,myf MyFlag);
|
||||
extern my_string _my_strdup(const char *from, const char *sFile, uint uLine,
|
||||
myf MyFlag);
|
||||
@ -580,10 +586,10 @@ extern int find_type(my_string x,TYPELIB *typelib,uint full_name);
|
||||
extern void make_type(my_string to,uint nr,TYPELIB *typelib);
|
||||
extern const char *get_type(TYPELIB *typelib,uint nr);
|
||||
extern my_bool init_dynamic_string(DYNAMIC_STRING *str, const char *init_str,
|
||||
uint init_alloc,uint alloc_increment);
|
||||
size_t init_alloc, size_t alloc_increment);
|
||||
extern my_bool dynstr_append(DYNAMIC_STRING *str, const char *append);
|
||||
my_bool dynstr_append_mem(DYNAMIC_STRING *str, const char *append,
|
||||
uint length);
|
||||
size_t length);
|
||||
extern my_bool dynstr_set(DYNAMIC_STRING *str, const char *init_str);
|
||||
extern my_bool dynstr_realloc(DYNAMIC_STRING *str, ulong additional_size);
|
||||
extern void dynstr_free(DYNAMIC_STRING *str);
|
||||
@ -592,18 +598,18 @@ my_bool set_changeable_var(my_string str,CHANGEABLE_VAR *vars);
|
||||
my_bool set_changeable_varval(const char *var, ulong val,
|
||||
CHANGEABLE_VAR *vars);
|
||||
#ifdef HAVE_MLOCK
|
||||
extern byte *my_malloc_lock(uint length,myf flags);
|
||||
extern byte *my_malloc_lock(size_t length,myf flags);
|
||||
extern void my_free_lock(byte *ptr,myf flags);
|
||||
#else
|
||||
#define my_malloc_lock(A,B) my_malloc((A),(B))
|
||||
#define my_free_lock(A,B) my_free((A),(B))
|
||||
#endif
|
||||
#define alloc_root_inited(A) ((A)->min_malloc != 0)
|
||||
void init_alloc_root(MEM_ROOT *mem_root, uint block_size, uint pre_alloc_size);
|
||||
gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size);
|
||||
void init_alloc_root(MEM_ROOT *mem_root, size_t block_size, size_t pre_alloc_size);
|
||||
gptr alloc_root(MEM_ROOT *mem_root, size_t Size);
|
||||
void free_root(MEM_ROOT *root, myf MyFLAGS);
|
||||
char *strdup_root(MEM_ROOT *root,const char *str);
|
||||
char *memdup_root(MEM_ROOT *root,const char *str,uint len);
|
||||
char *memdup_root(MEM_ROOT *root,const char *str, size_t len);
|
||||
void load_defaults(const char *conf_file, const char **groups,
|
||||
int *argc, char ***argv);
|
||||
void free_defaults(char **argv);
|
||||
@ -613,10 +619,10 @@ my_bool my_uncompress(byte *, ulong *, ulong *);
|
||||
byte *my_compress_alloc(const byte *packet, ulong *len, ulong *complen);
|
||||
ulong checksum(const byte *mem, uint count);
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__WIN__)
|
||||
#if defined(_MSC_VER) && !defined(_WIN32)
|
||||
extern void sleep(int sec);
|
||||
#endif
|
||||
#ifdef __WIN__
|
||||
#ifdef _WIN32
|
||||
extern my_bool have_tcpip; /* Is set if tcpip is used */
|
||||
#endif
|
||||
|
||||
|
121
include/mysql.h
121
include/mysql.h
@ -20,14 +20,6 @@
|
||||
#ifndef _mysql_h
|
||||
#define _mysql_h
|
||||
|
||||
#ifdef __CYGWIN__ /* CYGWIN implements a UNIX API */
|
||||
#undef WIN
|
||||
#undef _WIN
|
||||
#undef _WIN32
|
||||
#undef _WIN64
|
||||
#undef __WIN__
|
||||
#endif
|
||||
|
||||
#ifndef MYSQL_SERVER
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -38,25 +30,39 @@ extern "C" {
|
||||
#ifndef _global_h /* If not standard header */
|
||||
#include <sys/types.h>
|
||||
#ifdef __LCC__
|
||||
#include <winsock.h> /* For windows */
|
||||
#include <winsock2.h> /* For windows */
|
||||
#endif
|
||||
typedef char my_bool;
|
||||
#if (defined(_WIN32) || defined(_WIN64)) && !defined(__WIN__)
|
||||
#define __WIN__
|
||||
#endif
|
||||
#if !defined(__WIN__)
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#define STDCALL
|
||||
#else
|
||||
#include <WinSock2.h>
|
||||
#define STDCALL __stdcall
|
||||
#endif
|
||||
typedef char * gptr;
|
||||
|
||||
|
||||
|
||||
#ifndef my_socket_defined
|
||||
#define my_socket_defined
|
||||
#ifdef _WIN32
|
||||
#define my_socket SOCKET
|
||||
#else
|
||||
typedef int my_socket;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#include "mysql_com.h"
|
||||
#include "mysql_version.h"
|
||||
#include "my_list.h"
|
||||
|
||||
#ifndef ST_USED_MEM_DEFINED
|
||||
#define ST_USED_MEM_DEFINED
|
||||
typedef struct st_used_mem { /* struct for once_alloc */
|
||||
struct st_used_mem *next; /* Next block in use */
|
||||
unsigned int left; /* memory left in block */
|
||||
unsigned int size; /* size of block */
|
||||
typedef struct st_used_mem { /* struct for once_alloc */
|
||||
struct st_used_mem *next; /* Next block in use */
|
||||
size_t left; /* memory left in block */
|
||||
size_t size; /* Size of block */
|
||||
} USED_MEM;
|
||||
|
||||
typedef struct st_mem_root {
|
||||
@ -71,19 +77,6 @@ typedef struct st_mem_root {
|
||||
} MEM_ROOT;
|
||||
#endif
|
||||
|
||||
#ifndef my_socket_defined
|
||||
#ifdef __WIN__
|
||||
#define my_socket SOCKET
|
||||
#else
|
||||
typedef int my_socket;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#include "mysql_com.h"
|
||||
#include "mysql_version.h"
|
||||
#include "my_list.h"
|
||||
|
||||
|
||||
extern unsigned int mysql_port;
|
||||
extern char *mysql_unix_port;
|
||||
|
||||
@ -125,12 +118,13 @@ typedef unsigned int MYSQL_FIELD_OFFSET; /* offset to current field */
|
||||
|
||||
#if defined(NO_CLIENT_LONG_LONG)
|
||||
typedef unsigned long my_ulonglong;
|
||||
#elif defined (__WIN__)
|
||||
#elif defined (_WIN32)
|
||||
typedef unsigned __int64 my_ulonglong;
|
||||
#else
|
||||
typedef unsigned long long my_ulonglong;
|
||||
#endif
|
||||
|
||||
|
||||
#define SET_CLIENT_ERROR(a, b, c, d) \
|
||||
{ \
|
||||
(a)->net.last_errno= (b);\
|
||||
@ -202,12 +196,18 @@ enum mysql_status { MYSQL_STATUS_READY,
|
||||
MYSQL_STATUS_QUIT_SENT, /* object is "destroyed" at this stage */
|
||||
};
|
||||
|
||||
enum mysql_protocol_type
|
||||
{
|
||||
MYSQL_PROTOCOL_DEFAULT, MYSQL_PROTOCOL_TCP, MYSQL_PROTOCOL_SOCKET,
|
||||
MYSQL_PROTOCOL_PIPE, MYSQL_PROTOCOL_MEMORY
|
||||
};
|
||||
|
||||
struct st_mysql_options {
|
||||
unsigned int connect_timeout, read_timeout, write_timeout;
|
||||
unsigned int port, protocol;
|
||||
unsigned long client_flag;
|
||||
char *host,*user,*password,*unix_socket,*db;
|
||||
struct st_dynamic_array *init_commands;
|
||||
char *init_command;
|
||||
char *my_cnf_file,*my_cnf_group, *charset_dir, *charset_name;
|
||||
char *ssl_key; /* PEM key file */
|
||||
char *ssl_cert; /* PEM cert file */
|
||||
@ -222,14 +222,14 @@ struct st_mysql_options {
|
||||
enum mysql_option methods_to_use;
|
||||
char *client_ip;
|
||||
my_bool secure_auth;
|
||||
|
||||
my_bool report_data_truncation;
|
||||
/* function pointers for local infile support */
|
||||
int (*local_infile_init)(void **, const char *, void *);
|
||||
int (*local_infile_read)(void *, char *, unsigned int);
|
||||
void (*local_infile_end)(void *);
|
||||
int (*local_infile_error)(void *, char *, unsigned int);
|
||||
void *local_infile_userdata;
|
||||
struct st_mysql_options_extension *extension;
|
||||
struct st_mysql_options_extention *extension;
|
||||
};
|
||||
|
||||
typedef struct st_mysql {
|
||||
@ -237,9 +237,9 @@ typedef struct st_mysql {
|
||||
unsigned char *connector_fd; /* ConnectorFd for SSL */
|
||||
char *host,*user,*passwd,*unix_socket,*server_version,*host_info;
|
||||
char *info,*db;
|
||||
struct charset_info_st *charset; /* character set */
|
||||
MYSQL_FIELD *fields;
|
||||
MEM_ROOT field_alloc;
|
||||
const struct charset_info_st *charset; /* character set */
|
||||
MYSQL_FIELD *fields;
|
||||
MEM_ROOT field_alloc;
|
||||
my_ulonglong affected_rows;
|
||||
my_ulonglong insert_id; /* id if insert on table with NEXTNR */
|
||||
my_ulonglong extra_info; /* Used by mysqlshow */
|
||||
@ -269,6 +269,17 @@ typedef struct st_mysql {
|
||||
} MYSQL;
|
||||
|
||||
|
||||
struct st_mysql_options_extention {
|
||||
char *plugin_dir;
|
||||
char *default_auth;
|
||||
void (*report_progress)(const MYSQL *mysql,
|
||||
unsigned int stage,
|
||||
unsigned int max_stage,
|
||||
double progress,
|
||||
const char *proc_info,
|
||||
unsigned int proc_info_length);
|
||||
};
|
||||
|
||||
typedef struct st_mysql_res {
|
||||
my_ulonglong row_count;
|
||||
unsigned int field_count, current_field;
|
||||
@ -310,7 +321,20 @@ typedef struct character_set
|
||||
unsigned int mbmaxlen; /* max. length for multibyte strings */
|
||||
} MY_CHARSET_INFO;
|
||||
|
||||
/* Local infile support functions */
|
||||
#define LOCAL_INFILE_ERROR_LEN 512
|
||||
|
||||
void STDCALL mysql_set_local_infile_handler(MYSQL *mysql,
|
||||
int (*local_infile_init)(void **, const char *, void *),
|
||||
int (*local_infile_read)(void *, char *, unsigned int),
|
||||
void (*local_infile_end)(void *),
|
||||
int (*local_infile_error)(void *, char*, unsigned int),
|
||||
void *);
|
||||
|
||||
void mysql_set_local_infile_default(MYSQL *mysql);
|
||||
|
||||
void my_set_error(MYSQL *mysql, unsigned int error_nr,
|
||||
const char *sqlstate, const char *format, ...);
|
||||
/* Functions to get information from the MYSQL and MYSQL_RES structures */
|
||||
/* Should definitely be used if one uses shared libraries */
|
||||
|
||||
@ -377,7 +401,6 @@ int STDCALL mysql_ping(MYSQL *mysql);
|
||||
char * STDCALL mysql_stat(MYSQL *mysql);
|
||||
char * STDCALL mysql_get_server_info(MYSQL *mysql);
|
||||
unsigned long STDCALL mysql_get_server_version(MYSQL *mysql);
|
||||
char * STDCALL mysql_get_client_info(void);
|
||||
char * STDCALL mysql_get_host_info(MYSQL *mysql);
|
||||
unsigned int STDCALL mysql_get_proto_info(MYSQL *mysql);
|
||||
MYSQL_RES * STDCALL mysql_list_dbs(MYSQL *mysql,const char *wild);
|
||||
@ -404,28 +427,22 @@ unsigned long STDCALL mysql_real_escape_string(MYSQL *mysql,
|
||||
char *to,const char *from,
|
||||
unsigned long length);
|
||||
void STDCALL mysql_debug(const char *debug);
|
||||
char * STDCALL mysql_odbc_escape_string(MYSQL *mysql,
|
||||
char *to,
|
||||
unsigned long to_length,
|
||||
const char *from,
|
||||
unsigned long from_length,
|
||||
void *param,
|
||||
char *
|
||||
(*extend_buffer)
|
||||
(void *, char *to,
|
||||
unsigned long *length));
|
||||
#define mysql_debug_init(A) mysql_debug((A));
|
||||
void STDCALL mysql_debug_end();
|
||||
void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name);
|
||||
unsigned int STDCALL mysql_thread_safe(void);
|
||||
unsigned int STDCALL mysql_warning_count(MYSQL *mysql);
|
||||
const char * STDCALL mysql_sqlstate(MYSQL *mysql);
|
||||
int STDCALL mysql_server_init(int argc __attribute__((unused)),
|
||||
char **argv __attribute__((unused)),
|
||||
char **groups __attribute__((unused)));
|
||||
int STDCALL mysql_server_init(int argc, char **argv, char **groups);
|
||||
void STDCALL mysql_server_end(void);
|
||||
void STDCALL mysql_thread_end(void);
|
||||
my_bool STDCALL mysql_thread_init(void);
|
||||
int STDCALL mysql_set_server_option(MYSQL *mysql,
|
||||
enum enum_mysql_set_option option);
|
||||
const char * STDCALL mysql_get_client_info(void);
|
||||
unsigned long STDCALL mysql_get_client_version(void);
|
||||
|
||||
#include <mysql_stmt.h>
|
||||
#include <my_stmt.h>
|
||||
|
||||
#define mysql_reload(mysql) mysql_refresh((mysql),REFRESH_GRANT)
|
||||
|
||||
|
175
include/mysql/client_plugin.h
Normal file
175
include/mysql/client_plugin.h
Normal file
@ -0,0 +1,175 @@
|
||||
/* Copyright (C) 2010, 2011 Sergei Golubchik and Monty Program 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 see <http://www.gnu.org/licenses>
|
||||
or write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St., Fifth Floor, Boston, MA 02110, USA */
|
||||
|
||||
/**
|
||||
@file
|
||||
|
||||
MySQL Client Plugin API
|
||||
|
||||
This file defines the API for plugins that work on the client side
|
||||
*/
|
||||
#ifndef MYSQL_CLIENT_PLUGIN_INCLUDED
|
||||
#define MYSQL_CLIENT_PLUGIN_INCLUDED
|
||||
|
||||
#ifndef MYSQL_ABI_CHECK
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifndef PLUGINDIR
|
||||
#define PLUGINDIR "lib/plugin"
|
||||
#endif
|
||||
|
||||
/* known plugin types */
|
||||
#define MYSQL_CLIENT_reserved1 0
|
||||
#define MYSQL_CLIENT_reserved2 1
|
||||
#define MYSQL_CLIENT_AUTHENTICATION_PLUGIN 2
|
||||
|
||||
#define MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION 0x0100
|
||||
|
||||
#define MYSQL_CLIENT_MAX_PLUGINS 3
|
||||
|
||||
#define mysql_declare_client_plugin(X) \
|
||||
struct st_mysql_client_plugin_ ## X \
|
||||
_mysql_client_plugin_declaration_ = { \
|
||||
MYSQL_CLIENT_ ## X ## _PLUGIN, \
|
||||
MYSQL_CLIENT_ ## X ## _PLUGIN_INTERFACE_VERSION,
|
||||
#define mysql_end_client_plugin }
|
||||
|
||||
/* generic plugin header structure */
|
||||
#define MYSQL_CLIENT_PLUGIN_HEADER \
|
||||
int type; \
|
||||
unsigned int interface_version; \
|
||||
const char *name; \
|
||||
const char *author; \
|
||||
const char *desc; \
|
||||
unsigned int version[3]; \
|
||||
int (*init)(char *, size_t, int, va_list); \
|
||||
int (*deinit)();
|
||||
|
||||
struct st_mysql_client_plugin
|
||||
{
|
||||
MYSQL_CLIENT_PLUGIN_HEADER
|
||||
};
|
||||
|
||||
struct st_mysql;
|
||||
|
||||
/******** authentication plugin specific declarations *********/
|
||||
#include <mysql/plugin_auth_common.h>
|
||||
|
||||
struct st_mysql_client_plugin_AUTHENTICATION
|
||||
{
|
||||
MYSQL_CLIENT_PLUGIN_HEADER
|
||||
int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, struct st_mysql *mysql);
|
||||
};
|
||||
|
||||
/**
|
||||
type of the mysql_authentication_dialog_ask function
|
||||
|
||||
@param mysql mysql
|
||||
@param type type of the input
|
||||
1 - ordinary string input
|
||||
2 - password string
|
||||
@param prompt prompt
|
||||
@param buf a buffer to store the use input
|
||||
@param buf_len the length of the buffer
|
||||
|
||||
@retval a pointer to the user input string.
|
||||
It may be equal to 'buf' or to 'mysql->password'.
|
||||
In all other cases it is assumed to be an allocated
|
||||
string, and the "dialog" plugin will free() it.
|
||||
*/
|
||||
typedef char *(*mysql_authentication_dialog_ask_t)(struct st_mysql *mysql,
|
||||
int type, const char *prompt, char *buf, int buf_len);
|
||||
/******** using plugins ************/
|
||||
|
||||
/**
|
||||
loads a plugin and initializes it
|
||||
|
||||
@param mysql MYSQL structure. only MYSQL_PLUGIN_DIR option value is used,
|
||||
and last_errno/last_error, for error reporting
|
||||
@param name a name of the plugin to load
|
||||
@param type type of plugin that should be loaded, -1 to disable type check
|
||||
@param argc number of arguments to pass to the plugin initialization
|
||||
function
|
||||
@param ... arguments for the plugin initialization function
|
||||
|
||||
@retval
|
||||
a pointer to the loaded plugin, or NULL in case of a failure
|
||||
*/
|
||||
struct st_mysql_client_plugin *
|
||||
mysql_load_plugin(struct st_mysql *mysql, const char *name, int type,
|
||||
int argc, ...);
|
||||
|
||||
/**
|
||||
loads a plugin and initializes it, taking va_list as an argument
|
||||
|
||||
This is the same as mysql_load_plugin, but take va_list instead of
|
||||
a list of arguments.
|
||||
|
||||
@param mysql MYSQL structure. only MYSQL_PLUGIN_DIR option value is used,
|
||||
and last_errno/last_error, for error reporting
|
||||
@param name a name of the plugin to load
|
||||
@param type type of plugin that should be loaded, -1 to disable type check
|
||||
@param argc number of arguments to pass to the plugin initialization
|
||||
function
|
||||
@param args arguments for the plugin initialization function
|
||||
|
||||
@retval
|
||||
a pointer to the loaded plugin, or NULL in case of a failure
|
||||
*/
|
||||
struct st_mysql_client_plugin *
|
||||
mysql_load_plugin_v(struct st_mysql *mysql, const char *name, int type,
|
||||
int argc, va_list args);
|
||||
|
||||
/**
|
||||
finds an already loaded plugin by name, or loads it, if necessary
|
||||
|
||||
@param mysql MYSQL structure. only MYSQL_PLUGIN_DIR option value is used,
|
||||
and last_errno/last_error, for error reporting
|
||||
@param name a name of the plugin to load
|
||||
@param type type of plugin that should be loaded
|
||||
|
||||
@retval
|
||||
a pointer to the plugin, or NULL in case of a failure
|
||||
*/
|
||||
struct st_mysql_client_plugin *
|
||||
mysql_client_find_plugin(struct st_mysql *mysql, const char *name, int type);
|
||||
|
||||
/**
|
||||
adds a plugin structure to the list of loaded plugins
|
||||
|
||||
This is useful if an application has the necessary functionality
|
||||
(for example, a special load data handler) statically linked into
|
||||
the application binary. It can use this function to register the plugin
|
||||
directly, avoiding the need to factor it out into a shared object.
|
||||
|
||||
@param mysql MYSQL structure. It is only used for error reporting
|
||||
@param plugin an st_mysql_client_plugin structure to register
|
||||
|
||||
@retval
|
||||
a pointer to the plugin, or NULL in case of a failure
|
||||
*/
|
||||
struct st_mysql_client_plugin *
|
||||
mysql_client_register_plugin(struct st_mysql *mysql,
|
||||
struct st_mysql_client_plugin *plugin);
|
||||
|
||||
extern struct st_mysql_client_plugin *mysql_client_builtins[];
|
||||
|
||||
#endif
|
||||
|
||||
|
107
include/mysql/plugin_auth.h
Normal file
107
include/mysql/plugin_auth.h
Normal file
@ -0,0 +1,107 @@
|
||||
#ifndef MYSQL_PLUGIN_AUTH_COMMON_INCLUDED
|
||||
/* Copyright (C) 2010 Sergei Golubchik and Monty Program 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 */
|
||||
|
||||
/**
|
||||
@file
|
||||
|
||||
This file defines constants and data structures that are the same for
|
||||
both client- and server-side authentication plugins.
|
||||
*/
|
||||
#define MYSQL_PLUGIN_AUTH_COMMON_INCLUDED
|
||||
|
||||
/** the max allowed length for a user name */
|
||||
#define MYSQL_USERNAME_LENGTH 48
|
||||
|
||||
/**
|
||||
return values of the plugin authenticate_user() method.
|
||||
*/
|
||||
|
||||
/**
|
||||
Authentication failed. Additionally, all other CR_xxx values
|
||||
(libmysql error code) can be used too.
|
||||
|
||||
The client plugin may set the error code and the error message directly
|
||||
in the MYSQL structure and return CR_ERROR. If a CR_xxx specific error
|
||||
code was returned, an error message in the MYSQL structure will be
|
||||
overwritten. If CR_ERROR is returned without setting the error in MYSQL,
|
||||
CR_UNKNOWN_ERROR will be user.
|
||||
*/
|
||||
#define CR_ERROR 0
|
||||
/**
|
||||
Authentication (client part) was successful. It does not mean that the
|
||||
authentication as a whole was successful, usually it only means
|
||||
that the client was able to send the user name and the password to the
|
||||
server. If CR_OK is returned, the libmysql reads the next packet expecting
|
||||
it to be one of OK, ERROR, or CHANGE_PLUGIN packets.
|
||||
*/
|
||||
#define CR_OK -1
|
||||
/**
|
||||
Authentication was successful.
|
||||
It means that the client has done its part successfully and also that
|
||||
a plugin has read the last packet (one of OK, ERROR, CHANGE_PLUGIN).
|
||||
In this case, libmysql will not read a packet from the server,
|
||||
but it will use the data at mysql->net.read_pos.
|
||||
|
||||
A plugin may return this value if the number of roundtrips in the
|
||||
authentication protocol is not known in advance, and the client plugin
|
||||
needs to read one packet more to determine if the authentication is finished
|
||||
or not.
|
||||
*/
|
||||
#define CR_OK_HANDSHAKE_COMPLETE -2
|
||||
|
||||
typedef struct st_plugin_vio_info
|
||||
{
|
||||
enum { MYSQL_VIO_INVALID, MYSQL_VIO_TCP, MYSQL_VIO_SOCKET,
|
||||
MYSQL_VIO_PIPE, MYSQL_VIO_MEMORY } protocol;
|
||||
int socket; /**< it's set, if the protocol is SOCKET or TCP */
|
||||
#ifdef _WIN32
|
||||
HANDLE handle; /**< it's set, if the protocol is PIPE or MEMORY */
|
||||
#endif
|
||||
} MYSQL_PLUGIN_VIO_INFO;
|
||||
|
||||
/**
|
||||
Provides plugin access to communication channel
|
||||
*/
|
||||
typedef struct st_plugin_vio
|
||||
{
|
||||
/**
|
||||
Plugin provides a pointer reference and this function sets it to the
|
||||
contents of any incoming packet. Returns the packet length, or -1 if
|
||||
the plugin should terminate.
|
||||
*/
|
||||
int (*read_packet)(struct st_plugin_vio *vio,
|
||||
unsigned char **buf);
|
||||
|
||||
/**
|
||||
Plugin provides a buffer with data and the length and this
|
||||
function sends it as a packet. Returns 0 on success, 1 on failure.
|
||||
*/
|
||||
int (*write_packet)(struct st_plugin_vio *vio,
|
||||
const unsigned char *packet,
|
||||
int packet_len);
|
||||
|
||||
/**
|
||||
Fills in a st_plugin_vio_info structure, providing the information
|
||||
about the connection.
|
||||
*/
|
||||
void (*info)(struct st_plugin_vio *vio, struct st_plugin_vio_info *info);
|
||||
|
||||
} MYSQL_PLUGIN_VIO;
|
||||
|
||||
#endif
|
||||
|
107
include/mysql/plugin_auth_common.h
Normal file
107
include/mysql/plugin_auth_common.h
Normal file
@ -0,0 +1,107 @@
|
||||
#ifndef MYSQL_PLUGIN_AUTH_COMMON_INCLUDED
|
||||
/* Copyright (C) 2010 Sergei Golubchik and Monty Program 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 */
|
||||
|
||||
/**
|
||||
@file
|
||||
|
||||
This file defines constants and data structures that are the same for
|
||||
both client- and server-side authentication plugins.
|
||||
*/
|
||||
#define MYSQL_PLUGIN_AUTH_COMMON_INCLUDED
|
||||
|
||||
/** the max allowed length for a user name */
|
||||
#define MYSQL_USERNAME_LENGTH 48
|
||||
|
||||
/**
|
||||
return values of the plugin authenticate_user() method.
|
||||
*/
|
||||
|
||||
/**
|
||||
Authentication failed. Additionally, all other CR_xxx values
|
||||
(libmysql error code) can be used too.
|
||||
|
||||
The client plugin may set the error code and the error message directly
|
||||
in the MYSQL structure and return CR_ERROR. If a CR_xxx specific error
|
||||
code was returned, an error message in the MYSQL structure will be
|
||||
overwritten. If CR_ERROR is returned without setting the error in MYSQL,
|
||||
CR_UNKNOWN_ERROR will be user.
|
||||
*/
|
||||
#define CR_ERROR 0
|
||||
/**
|
||||
Authentication (client part) was successful. It does not mean that the
|
||||
authentication as a whole was successful, usually it only means
|
||||
that the client was able to send the user name and the password to the
|
||||
server. If CR_OK is returned, the libmysql reads the next packet expecting
|
||||
it to be one of OK, ERROR, or CHANGE_PLUGIN packets.
|
||||
*/
|
||||
#define CR_OK -1
|
||||
/**
|
||||
Authentication was successful.
|
||||
It means that the client has done its part successfully and also that
|
||||
a plugin has read the last packet (one of OK, ERROR, CHANGE_PLUGIN).
|
||||
In this case, libmysql will not read a packet from the server,
|
||||
but it will use the data at mysql->net.read_pos.
|
||||
|
||||
A plugin may return this value if the number of roundtrips in the
|
||||
authentication protocol is not known in advance, and the client plugin
|
||||
needs to read one packet more to determine if the authentication is finished
|
||||
or not.
|
||||
*/
|
||||
#define CR_OK_HANDSHAKE_COMPLETE -2
|
||||
|
||||
typedef struct st_plugin_vio_info
|
||||
{
|
||||
enum { MYSQL_VIO_INVALID, MYSQL_VIO_TCP, MYSQL_VIO_SOCKET,
|
||||
MYSQL_VIO_PIPE, MYSQL_VIO_MEMORY } protocol;
|
||||
int socket; /**< it's set, if the protocol is SOCKET or TCP */
|
||||
#ifdef _WIN32
|
||||
HANDLE handle; /**< it's set, if the protocol is PIPE or MEMORY */
|
||||
#endif
|
||||
} MYSQL_PLUGIN_VIO_INFO;
|
||||
|
||||
/**
|
||||
Provides plugin access to communication channel
|
||||
*/
|
||||
typedef struct st_plugin_vio
|
||||
{
|
||||
/**
|
||||
Plugin provides a pointer reference and this function sets it to the
|
||||
contents of any incoming packet. Returns the packet length, or -1 if
|
||||
the plugin should terminate.
|
||||
*/
|
||||
int (*read_packet)(struct st_plugin_vio *vio,
|
||||
unsigned char **buf);
|
||||
|
||||
/**
|
||||
Plugin provides a buffer with data and the length and this
|
||||
function sends it as a packet. Returns 0 on success, 1 on failure.
|
||||
*/
|
||||
int (*write_packet)(struct st_plugin_vio *vio,
|
||||
const unsigned char *packet,
|
||||
int packet_len);
|
||||
|
||||
/**
|
||||
Fills in a st_plugin_vio_info structure, providing the information
|
||||
about the connection.
|
||||
*/
|
||||
void (*info)(struct st_plugin_vio *vio, struct st_plugin_vio_info *info);
|
||||
|
||||
} MYSQL_PLUGIN_VIO;
|
||||
|
||||
#endif
|
||||
|
@ -32,19 +32,21 @@
|
||||
#define NAME_CHAR_LEN 64
|
||||
#define NAME_LEN 256 /* Field/table name length */
|
||||
#define HOSTNAME_LENGTH 60
|
||||
#define SYSTEM_MB_MAX_CHAR_LENGTH 3
|
||||
#define USERNAME_CHAR_LENGTH 16
|
||||
#define USERNAME_LENGTH 64
|
||||
#define USERNAME_LENGTH USERNAME_CHAR_LENGTH * SYSTEM_MB_MAX_CHAR_LENGTH
|
||||
#define SERVER_VERSION_LENGTH 60
|
||||
#define SQLSTATE_LENGTH 5
|
||||
#define SCRAMBLE_LENGTH 20
|
||||
#define SCRAMBLE_LENGTH_323 8
|
||||
|
||||
#define LOCAL_HOST "localhost"
|
||||
#define LOCAL_HOST_NAMEDPIPE "."
|
||||
|
||||
#if defined(__WIN__) && !defined( _CUSTOMCONFIG_)
|
||||
#if defined(_WIN32) && !defined( _CUSTOMCONFIG_)
|
||||
#define MYSQL_NAMEDPIPE "MySQL"
|
||||
#define MYSQL_SERVICENAME "MySql"
|
||||
#endif /* __WIN__ */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
|
||||
enum enum_server_command
|
||||
@ -96,6 +98,10 @@ enum enum_server_command
|
||||
#define AUTO_INCREMENT_FLAG 512 /* field is a autoincrement field */
|
||||
#define TIMESTAMP_FLAG 1024 /* Field is a timestamp */
|
||||
#define SET_FLAG 2048 /* field is a set */
|
||||
/* new since 3.23.58 */
|
||||
#define NO_DEFAULT_VALUE_FLAG 4096 /* Field doesn't have default value */
|
||||
#define ON_UPDATE_NOW_FLAG 8192 /* Field is set to NOW on UPDATE */
|
||||
/* end new */
|
||||
#define NUM_FLAG 32768 /* Field is num (for clients) */
|
||||
#define PART_KEY_FLAG 16384 /* Intern; Part of some key */
|
||||
#define GROUP_FLAG 32768 /* Intern: Group field */
|
||||
@ -136,6 +142,7 @@ enum enum_server_command
|
||||
#define CLIENT_MULTI_STATEMENTS (1UL << 16)
|
||||
#define CLIENT_MULTI_RESULTS (1UL << 17)
|
||||
#define CLIENT_PS_MULTI_RESULTS (1UL << 18)
|
||||
#define CLIENT_PLUGIN_AUTH (1UL << 19)
|
||||
#define CLIENT_PROGRESS (1UL << 29) /* client supports progress indicator */
|
||||
|
||||
#define CLIENT_SUPPORTED_FLAGS (CLIENT_LONG_PASSWORD | \
|
||||
@ -159,6 +166,15 @@ enum enum_server_command
|
||||
CLIENT_MULTI_RESULTS |\
|
||||
CLIENT_PROGRESS)
|
||||
|
||||
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD |\
|
||||
CLIENT_LONG_FLAG |\
|
||||
CLIENT_TRANSACTIONS |\
|
||||
CLIENT_SECURE_CONNECTION |\
|
||||
CLIENT_MULTI_RESULTS | \
|
||||
CLIENT_PS_MULTI_RESULTS |\
|
||||
CLIENT_PROTOCOL_41 |\
|
||||
CLIENT_PLUGIN_AUTH)
|
||||
|
||||
#define CLIENT_DEFAULT_FLAGS ((CLIENT_SUPPORTED_FLAGS & ~CLIENT_COMPRESS)\
|
||||
& ~CLIENT_SSL)
|
||||
|
||||
@ -222,6 +238,13 @@ typedef struct st_net {
|
||||
|
||||
#define packet_error ((unsigned int) -1)
|
||||
|
||||
/* used by mysql_set_server_option */
|
||||
enum enum_mysql_set_option
|
||||
{
|
||||
MYSQL_OPTION_MULTI_STATEMENTS_ON,
|
||||
MYSQL_OPTION_MULTI_STATEMENTS_OFF
|
||||
};
|
||||
|
||||
enum enum_field_types { MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY,
|
||||
MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG,
|
||||
MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE,
|
||||
@ -245,6 +268,32 @@ enum enum_field_types { MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY,
|
||||
|
||||
#define FIELD_TYPE_CHAR FIELD_TYPE_TINY /* For compability */
|
||||
#define FIELD_TYPE_INTERVAL FIELD_TYPE_ENUM /* For compability */
|
||||
#define FIELD_TYPE_DECIMAL MYSQL_TYPE_DECIMAL
|
||||
#define FIELD_TYPE_NEWDECIMAL MYSQL_TYPE_NEWDECIMAL
|
||||
#define FIELD_TYPE_TINY MYSQL_TYPE_TINY
|
||||
#define FIELD_TYPE_SHORT MYSQL_TYPE_SHORT
|
||||
#define FIELD_TYPE_LONG MYSQL_TYPE_LONG
|
||||
#define FIELD_TYPE_FLOAT MYSQL_TYPE_FLOAT
|
||||
#define FIELD_TYPE_DOUBLE MYSQL_TYPE_DOUBLE
|
||||
#define FIELD_TYPE_NULL MYSQL_TYPE_NULL
|
||||
#define FIELD_TYPE_TIMESTAMP MYSQL_TYPE_TIMESTAMP
|
||||
#define FIELD_TYPE_LONGLONG MYSQL_TYPE_LONGLONG
|
||||
#define FIELD_TYPE_INT24 MYSQL_TYPE_INT24
|
||||
#define FIELD_TYPE_DATE MYSQL_TYPE_DATE
|
||||
#define FIELD_TYPE_TIME MYSQL_TYPE_TIME
|
||||
#define FIELD_TYPE_DATETIME MYSQL_TYPE_DATETIME
|
||||
#define FIELD_TYPE_YEAR MYSQL_TYPE_YEAR
|
||||
#define FIELD_TYPE_NEWDATE MYSQL_TYPE_NEWDATE
|
||||
#define FIELD_TYPE_ENUM MYSQL_TYPE_ENUM
|
||||
#define FIELD_TYPE_SET MYSQL_TYPE_SET
|
||||
#define FIELD_TYPE_TINY_BLOB MYSQL_TYPE_TINY_BLOB
|
||||
#define FIELD_TYPE_MEDIUM_BLOB MYSQL_TYPE_MEDIUM_BLOB
|
||||
#define FIELD_TYPE_LONG_BLOB MYSQL_TYPE_LONG_BLOB
|
||||
#define FIELD_TYPE_BLOB MYSQL_TYPE_BLOB
|
||||
#define FIELD_TYPE_VAR_STRING MYSQL_TYPE_VAR_STRING
|
||||
#define FIELD_TYPE_STRING MYSQL_TYPE_STRING
|
||||
#define FIELD_TYPE_GEOMETRY MYSQL_TYPE_GEOMETRY
|
||||
#define FIELD_TYPE_BIT MYSQL_TYPE_BIT
|
||||
|
||||
extern unsigned long max_allowed_packet;
|
||||
extern unsigned long net_buffer_length;
|
||||
@ -255,11 +304,11 @@ int my_net_init(NET *net, Vio *vio);
|
||||
void net_end(NET *net);
|
||||
void net_clear(NET *net);
|
||||
int net_flush(NET *net);
|
||||
int my_net_write(NET *net,const char *packet,unsigned long len);
|
||||
int my_net_write(NET *net,const char *packet, size_t len);
|
||||
int net_write_command(NET *net,unsigned char command,const char *packet,
|
||||
unsigned long len);
|
||||
size_t len);
|
||||
int net_real_write(NET *net,const char *packet,unsigned long len);
|
||||
ulong my_net_read(NET *net);
|
||||
unsigned long my_net_read(NET *net);
|
||||
|
||||
struct rand_struct {
|
||||
unsigned long seed1,seed2,max_value;
|
||||
@ -295,6 +344,8 @@ typedef struct st_udf_init
|
||||
#define COMP_HEADER_SIZE 3 /* compression header extra size */
|
||||
|
||||
/* Prototypes to password functions */
|
||||
#define native_password_plugin_name "mysql_native_password"
|
||||
#define old_password_plugin_name "mysql_old_password"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -306,13 +357,12 @@ double rnd(struct rand_struct *);
|
||||
void make_scrambled_password(char *to,const char *password);
|
||||
void get_salt_from_password(unsigned long *res,const char *password);
|
||||
void make_password_from_salt(char *to, unsigned long *hash_res);
|
||||
char *scramble(char *to,const char *message,const char *password,
|
||||
my_bool old_ver);
|
||||
char *scramble_323(char *to,const char *message,const char *password);
|
||||
void my_scramble_41(const unsigned char *buffer, const char *scramble, const char *password);
|
||||
my_bool check_scramble(const char *, const char *message,
|
||||
unsigned long *salt,my_bool old_ver);
|
||||
char *get_tty_password(char *opt_message);
|
||||
void hash_password(unsigned long *result, const char *password);
|
||||
void hash_password(unsigned long *result, const char *password, size_t len);
|
||||
|
||||
/* Some other useful functions */
|
||||
|
||||
|
@ -1,23 +0,0 @@
|
||||
/* Copyright Abandoned 1996, 1999, 2001 MySQL AB
|
||||
This file is public domain and comes with NO WARRANTY of any kind */
|
||||
|
||||
/* Version numbers for protocol & mysqld */
|
||||
|
||||
#ifdef _CUSTOMCONFIG_
|
||||
#include <custom_conf.h>
|
||||
#else
|
||||
#define PROTOCOL_VERSION 10
|
||||
#define MYSQL_SERVER_VERSION "3.23.59"
|
||||
#define MYSQL_SERVER_SUFFIX ""
|
||||
#define FRM_VER
|
||||
#define MYSQL_VERSION_ID 32359
|
||||
#define MYSQL_PORT 3306
|
||||
#define MYSQL_UNIX_ADDR ""
|
||||
#define MYSQL_CONFIG_NAME "my"
|
||||
|
||||
/* mysqld compile time options */
|
||||
#ifndef MYSQL_CHARSET
|
||||
#define MYSQL_CHARSET ""
|
||||
#endif
|
||||
#endif
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <custom_conf.h>
|
||||
#else
|
||||
#define PROTOCOL_VERSION @PROTOCOL_VERSION@
|
||||
#define MYSQL_CLIENT_VERSION "@MYSQL_CLIENT_VERSION@"
|
||||
#define MYSQL_SERVER_VERSION "@MYSQL_CLIENT_VERSION@"
|
||||
#define MYSQL_SERVER_SUFFIX "@MYSQL_SERVER_SUFFIX@"
|
||||
#define FRM_VER @DOT_FRM_VERSION@
|
||||
|
@ -1,20 +1,5 @@
|
||||
/* Copyright (C) 2000 MySQL 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 */
|
||||
|
||||
/* Definefile for error messagenumbers */
|
||||
/* This file is automaticly generated from errmsg.sys ; Do not edit! */
|
||||
/* mysqld server error messagenumbers */
|
||||
|
||||
#define ER_HASHCHK 1000
|
||||
#define ER_NISAMCHK 1001
|
||||
|
@ -35,7 +35,7 @@ typedef struct {
|
||||
} MYSQL_SHA1_CTX;
|
||||
|
||||
void MYSQL_SHA1Init(MYSQL_SHA1_CTX *);
|
||||
void MYSQL_SHA1Update(MYSQL_SHA1_CTX *, const unsigned char *, unsigned int);
|
||||
void MYSQL_SHA1Update(MYSQL_SHA1_CTX *, const unsigned char *, size_t);
|
||||
void MYSQL_SHA1Final(unsigned char[20], MYSQL_SHA1_CTX *);
|
||||
|
||||
#endif
|
||||
|
@ -59,7 +59,7 @@ typedef struct st_thr_alarm_entry
|
||||
#define thr_end_alarm(A)
|
||||
|
||||
#else
|
||||
#if defined(__WIN__)
|
||||
#if defined(_WIN32)
|
||||
typedef struct st_thr_alarm_entry
|
||||
{
|
||||
rf_SetTimer crono;
|
||||
@ -79,7 +79,7 @@ typedef int thr_alarm_entry;
|
||||
|
||||
#define thr_got_alarm(thr_alarm) (**(thr_alarm))
|
||||
|
||||
#endif /* __WIN__ */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
typedef thr_alarm_entry* thr_alarm_t;
|
||||
|
||||
|
@ -23,6 +23,8 @@
|
||||
#ifndef vio_violite_h_
|
||||
#define vio_violite_h_
|
||||
|
||||
|
||||
|
||||
#include "my_net.h" /* needed because of struct in_addr */
|
||||
|
||||
#ifdef HAVE_VIO
|
||||
@ -47,7 +49,7 @@ enum enum_vio_type { VIO_CLOSED, VIO_TYPE_TCPIP, VIO_TYPE_SOCKET,
|
||||
Vio* vio_new(my_socket sd,
|
||||
enum enum_vio_type type,
|
||||
my_bool localhost);
|
||||
#ifdef __WIN__
|
||||
#ifdef _WIN32
|
||||
Vio* vio_new_win32pipe(HANDLE hPipe);
|
||||
#endif
|
||||
void vio_delete(Vio* vio);
|
||||
@ -92,6 +94,10 @@ const char* vio_description( Vio* vio);
|
||||
/* Return the type of the connection */
|
||||
enum enum_vio_type vio_type(Vio* vio);
|
||||
|
||||
/* set timeout */
|
||||
void vio_read_timeout(Vio *vio, uint seconds);
|
||||
void vio_write_timeout(Vio *vio, uint seconds);
|
||||
|
||||
/* Return last error number */
|
||||
int vio_errno(Vio *vio);
|
||||
|
||||
@ -110,6 +116,23 @@ void vio_in_addr(Vio *vio, struct in_addr *in);
|
||||
/* Return 1 if there is data to be read */
|
||||
my_bool vio_poll_read(Vio *vio,uint timeout);
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
#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 */
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
103
libmysql/CMakeLists.txt
Executable file → Normal file
103
libmysql/CMakeLists.txt
Executable file → Normal file
@ -1,21 +1,98 @@
|
||||
INCLUDE_DIRECTORIES(BEFORE SYSTEM
|
||||
${CMAKE_SOURCE_DIR}/include
|
||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
|
||||
${CMAKE_SOURCE_DIR}/zlib
|
||||
${CMAKE_SOURCE_DIR}/libmysql)
|
||||
|
||||
SET(LIBMYSQL_VERSION "16.0.0")
|
||||
|
||||
ADD_DEFINITIONS(-D ENABLED_LOCAL_INFILE)
|
||||
ADD_DEFINITIONS(-D HAVE_COMPRESS)
|
||||
ADD_DEFINITIONS(-D THREAD)
|
||||
|
||||
SET(LIBMYSQL_SOURCES array.c bchange.c bmove.c bmove_upp.c mysql_charset.c violite.c net.c charset.c conf_to_src.c ctype.c dbug.c default.c errmsg.c
|
||||
errors.c getopt1.c getopt.c get_password.c getvar.c hash.c int2str.c is_prefix.c libmysql.c list.c
|
||||
llstr.c longlong2str.c mf_cache.c mf_casecnv.c mf_dirname.c mf_fn_ext.c mf_format.c
|
||||
mf_iocache.c mf_loadpath.c mf_pack.c mf_path.c mf_tempfile.c mf_unixpath.c mf_wcomp.c mulalloc.c
|
||||
my_alloc.c my_compress.c my_create.c my_delete.c my_div.c my_error.c my_fopen.c my_fstream.c
|
||||
my_gethostbyname.c my_getwd.c my_init.c my_lib.c my_malloc.c my_messnc.c my_net.c
|
||||
my_once.c my_open.c my_port.c my_pread.c my_pthread.c my_read.c my_realloc.c my_seek.c my_static.c
|
||||
my_symlink.c my_thr_init.c my_write.c password.c safemalloc.c str2int.c strcend.c strcont.c
|
||||
strend.c strfill.c string.c strinstr.c strmake.c strmov.c strnlen.c strnmov.c
|
||||
strtoll.c strtoull.c strxmov.c thr_mutex.c typelib.c sha1.c mysql_stmt.c mysql_stmt_codec.c)
|
||||
SET(LIBMYSQL_SOURCES array.c bchange.c bmove.c bmove_upp.c my_charset.c
|
||||
violite.c net.c charset.c dbug.c default.c
|
||||
errmsg.c my_vsnprintf.c errors.c getopt1.c getopt.c
|
||||
get_password.c int2str.c is_prefix.c
|
||||
libmysql.c list.c llstr.c longlong2str.c
|
||||
mf_dirname.c mf_fn_ext.c mf_format.c
|
||||
mf_loadpath.c mf_pack.c mf_path.c
|
||||
mf_tempfile.c mf_unixpath.c mf_wcomp.c mulalloc.c
|
||||
my_alloc.c my_compress.c my_create.c my_delete.c my_div.c
|
||||
my_error.c my_fopen.c my_fstream.c my_gethostbyname.c
|
||||
my_getwd.c my_init.c my_lib.c my_malloc.c my_messnc.c
|
||||
my_net.c my_once.c my_open.c my_port.c
|
||||
my_pthread.c my_read.c my_realloc.c my_seek.c my_static.c
|
||||
my_symlink.c my_thr_init.c my_write.c password.c
|
||||
safemalloc.c str2int.c strcend.c strcont.c
|
||||
strend.c strfill.c string.c strinstr.c strmake.c
|
||||
strmov.c strnmov.c strtoll.c strtoull.c
|
||||
strxmov.c strxnmov.c thr_mutex.c typelib.c sha1.c my_stmt.c
|
||||
my_loaddata.c my_stmt_codec.c client_plugin.c my_auth.c)
|
||||
|
||||
|
||||
ADD_LIBRARY(mysqlclient STATIC ${LIBMYSQL_SOURCES})
|
||||
TARGET_LINK_LIBRARIES(mysqlclient m zlib)
|
||||
TARGET_LINK_LIBRARIES(mysqlclient ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS} zlib)
|
||||
|
||||
IF(UNIX)
|
||||
TARGET_LINK_LIBRARIES(mysqlclient m)
|
||||
ENDIF(UNIX)
|
||||
|
||||
ADD_LIBRARY(libmysql SHARED ${LIBMYSQL_SOURCES})
|
||||
TARGET_LINK_LIBRARIES(libmysql ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS} zlib)
|
||||
|
||||
IF(WIN32)
|
||||
TARGET_LINK_LIBRARIES(libmysql ws2_32)
|
||||
TARGET_LINK_LIBRARIES(mysqlclient ws2_32)
|
||||
ENDIF(WIN32)
|
||||
|
||||
IF(OPENSSL_LIBRARIES)
|
||||
TARGET_LINK_LIBRARIES(mysqlclient ${SSL_LIBRARIES})
|
||||
TARGET_LINK_LIBRARIES(libmysql ${SSL_LIBRARIES})
|
||||
ENDIF(OPENSSL_LIBRARIES)
|
||||
|
||||
IF(NOT WIN32)
|
||||
# we don't want a liblibmysql
|
||||
SET_TARGET_PROPERTIES(libmysql PROPERTIES PREFIX "")
|
||||
ENDIF(NOT WIN32)
|
||||
|
||||
# remove decimal points
|
||||
STRING(REGEX REPLACE "\\..+" "" LIBMYSQL_SO_VERSION ${LIBMYSQL_VERSION})
|
||||
SET_TARGET_PROPERTIES(libmysql PROPERTIES VERSION ${LIBMYSQL_VERSION}
|
||||
SOVERSION ${LIBMYSQL_SO_VERSION})
|
||||
|
||||
IF(NOT WIN32)
|
||||
ADD_CUSTOM_COMMAND(OUTPUT "libmysqlclient${CMAKE_SHARED_LIBRARY_SUFFIX}"
|
||||
"libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX}"
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E remove -f libmysqlclient${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E create_symlink libmysql${CMAKE_SHARED_LIBRARY_SUFFIX} libmysqlclient${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E remove -f libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E create_symlink libmysql${CMAKE_SHARED_LIBRARY_SUFFIX} libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/libmysql
|
||||
DEPENDS libmysql)
|
||||
|
||||
ADD_CUSTOM_TARGET(LIBMYSQL_SYMLINKS
|
||||
ALL
|
||||
DEPENDS "libmysqlclient${CMAKE_SHARED_LIBRARY_SUFFIX}"
|
||||
"libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
ENDIF(NOT WIN32)
|
||||
|
||||
#
|
||||
# Installation
|
||||
#
|
||||
IF(WIN32)
|
||||
INSTALL(TARGETS
|
||||
libmysql mysqlclient
|
||||
RUNTIME DESTINATION "lib"
|
||||
LIBRARY DESTINATION "lib"
|
||||
ARCHIVE DESTINATION "lib")
|
||||
ELSE(WIN32)
|
||||
INSTALL(TARGETS
|
||||
libmysql mysqlclient
|
||||
LIBRARY DESTINATION "lib"
|
||||
ARCHIVE DESTINATION "lib")
|
||||
INSTALL(FILES ${CMAKE_BINARY_DIR}/libmysql/libmysqlclient${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||
${CMAKE_BINARY_DIR}/libmysql/libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||
DESTINATION "lib")
|
||||
ENDIF(WIN32)
|
||||
|
||||
INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/include
|
||||
DESTINATION .)
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
/* Handling of arrays that can grow dynamicly. */
|
||||
|
||||
#ifdef __WIN__)
|
||||
#ifdef _WIN32
|
||||
#undef SAFEMALLOC /* Problems with threads */
|
||||
#endif
|
||||
|
||||
|
@ -28,9 +28,9 @@
|
||||
#include <my_global.h>
|
||||
#include "m_string.h"
|
||||
|
||||
void bchange(register char *dst, uint old_length, register const char *src, uint new_length, uint tot_length)
|
||||
void bchange(register char *dst, size_t old_length, register const char *src, size_t new_length, size_t tot_length)
|
||||
{
|
||||
uint rest=tot_length-old_length;
|
||||
size_t rest=tot_length-old_length;
|
||||
if (old_length < new_length)
|
||||
bmove_upp(dst+rest+new_length,dst+tot_length,rest);
|
||||
else
|
||||
|
@ -30,7 +30,7 @@
|
||||
#if defined(MC68000) && defined(DS90)
|
||||
|
||||
/* 0 <= len <= 65535 */
|
||||
void bmove_upp(byte *dst, const byte *src,uint len)
|
||||
void bmove_upp(byte *dst, const byte *src, size_t len)
|
||||
{
|
||||
asm(" movl 12(a7),d0 ");
|
||||
asm(" subql #1,d0 ");
|
||||
@ -43,7 +43,7 @@ asm(".L5: ");
|
||||
}
|
||||
#else
|
||||
|
||||
void bmove_upp(register char *dst, register const char *src, register uint len)
|
||||
void bmove_upp(register char *dst, register const char *src, register size_t len)
|
||||
{
|
||||
while (len-- != 0) *--dst = *--src;
|
||||
}
|
||||
|
@ -21,16 +21,16 @@
|
||||
#include <m_string.h>
|
||||
#include <my_dir.h>
|
||||
|
||||
CHARSET_INFO *default_charset_info = (CHARSET_INFO *)&compiled_charsets[5];
|
||||
|
||||
|
||||
CHARSET_INFO *get_charset(uint cs_number, myf flags)
|
||||
CHARSET_INFO *get_charset_by_nr(uint cs_number)
|
||||
{
|
||||
int i= 0;
|
||||
|
||||
while (compiled_charsets[i].nr && cs_number != compiled_charsets[i].nr)
|
||||
i++;
|
||||
|
||||
return (compiled_charsets[i].nr) ? &compiled_charsets[i] : NULL;
|
||||
return (compiled_charsets[i].nr) ? (CHARSET_INFO *)&compiled_charsets[i] : NULL;
|
||||
}
|
||||
|
||||
my_bool set_default_charset(uint cs, myf flags)
|
||||
@ -38,7 +38,7 @@ my_bool set_default_charset(uint cs, myf flags)
|
||||
CHARSET_INFO *new_charset;
|
||||
DBUG_ENTER("set_default_charset");
|
||||
DBUG_PRINT("enter",("character set: %d",(int) cs));
|
||||
new_charset = get_charset(cs, flags);
|
||||
new_charset = get_charset_by_nr(cs);
|
||||
if (!new_charset)
|
||||
{
|
||||
DBUG_PRINT("error",("Couldn't set default character set"));
|
||||
@ -48,14 +48,14 @@ my_bool set_default_charset(uint cs, myf flags)
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
CHARSET_INFO *get_charset_by_name(const char *cs_name, myf flags)
|
||||
CHARSET_INFO *get_charset_by_name(const char *cs_name)
|
||||
{
|
||||
int i= 0;
|
||||
|
||||
while (compiled_charsets[i].nr && strcmp(cs_name, compiled_charsets[i].name) != NULL)
|
||||
while (compiled_charsets[i].nr && strcmp(cs_name, compiled_charsets[i].name) != 0)
|
||||
i++;
|
||||
|
||||
return (compiled_charsets[i].nr) ? &compiled_charsets[i] : NULL;
|
||||
return (compiled_charsets[i].nr) ? (CHARSET_INFO *)&compiled_charsets[i] : NULL;
|
||||
}
|
||||
|
||||
my_bool set_default_charset_by_name(const char *cs_name, myf flags)
|
||||
@ -63,7 +63,7 @@ my_bool set_default_charset_by_name(const char *cs_name, myf flags)
|
||||
CHARSET_INFO *new_charset;
|
||||
DBUG_ENTER("set_default_charset_by_name");
|
||||
DBUG_PRINT("enter",("character set: %s", cs_name));
|
||||
new_charset = get_charset_by_name(cs_name, flags);
|
||||
new_charset = get_charset_by_name(cs_name);
|
||||
if (!new_charset)
|
||||
{
|
||||
DBUG_PRINT("error",("Couldn't set default character set"));
|
||||
|
459
libmysql/client_plugin.c
Normal file
459
libmysql/client_plugin.c
Normal file
@ -0,0 +1,459 @@
|
||||
/* Copyright (C) 2010, 2011 Sergei Golubchik and Monty Program 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 see <http://www.gnu.org/licenses>
|
||||
or write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St., Fifth Floor, Boston, MA 02110, USA */
|
||||
|
||||
/**
|
||||
@file
|
||||
|
||||
Support code for the client side (libmysql) plugins
|
||||
|
||||
Client plugins are somewhat different from server plugins, they are simpler.
|
||||
|
||||
They do not need to be installed or in any way explicitly loaded on the
|
||||
client, they are loaded automatically on demand.
|
||||
One client plugin per shared object, soname *must* match the plugin name.
|
||||
|
||||
There is no reference counting and no unloading either.
|
||||
*/
|
||||
|
||||
#if _MSC_VER
|
||||
/* Silence warnings about variable 'unused' being used. */
|
||||
#define FORCE_INIT_OF_VARS 1
|
||||
#endif
|
||||
|
||||
#include <my_global.h>
|
||||
#include "mysql.h"
|
||||
#include <my_sys.h>
|
||||
#include <m_string.h>
|
||||
#ifdef THREAD
|
||||
#include <my_pthread.h>
|
||||
#else
|
||||
#include <my_no_pthread.h>
|
||||
#endif
|
||||
|
||||
#include "errmsg.h"
|
||||
#include <mysql/client_plugin.h>
|
||||
|
||||
struct st_client_plugin_int {
|
||||
struct st_client_plugin_int *next;
|
||||
void *dlhandle;
|
||||
struct st_mysql_client_plugin *plugin;
|
||||
};
|
||||
|
||||
static my_bool initialized= 0;
|
||||
static MEM_ROOT mem_root;
|
||||
|
||||
#define plugin_declarations_sym "_mysql_client_plugin_declaration_"
|
||||
|
||||
static uint plugin_version[MYSQL_CLIENT_MAX_PLUGINS]=
|
||||
{
|
||||
0, /* these two are taken by Connector/C */
|
||||
0, /* these two are taken by Connector/C */
|
||||
MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION
|
||||
};
|
||||
|
||||
/*
|
||||
Loaded plugins are stored in a linked list.
|
||||
The list is append-only, the elements are added to the head (like in a stack).
|
||||
The elements are added under a mutex, but the list can be read and traversed
|
||||
without any mutex because once an element is added to the list, it stays
|
||||
there. The main purpose of a mutex is to prevent two threads from
|
||||
loading the same plugin twice in parallel.
|
||||
*/
|
||||
struct st_client_plugin_int *plugin_list[MYSQL_CLIENT_MAX_PLUGINS];
|
||||
#ifdef THREAD
|
||||
static pthread_mutex_t LOCK_load_client_plugin;
|
||||
#endif
|
||||
|
||||
static int is_not_initialized(MYSQL *mysql, const char *name)
|
||||
{
|
||||
if (initialized)
|
||||
return 0;
|
||||
|
||||
my_set_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD,
|
||||
SQLSTATE_UNKNOWN, ER(CR_AUTH_PLUGIN_CANNOT_LOAD),
|
||||
name, "not initialized");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
finds a plugin in the list
|
||||
|
||||
@param name plugin name to search for
|
||||
@param type plugin type
|
||||
|
||||
@note this does NOT necessarily need a mutex, take care!
|
||||
|
||||
@retval a pointer to a found plugin or 0
|
||||
*/
|
||||
|
||||
static struct st_mysql_client_plugin *find_plugin(const char *name, int type)
|
||||
{
|
||||
struct st_client_plugin_int *p;
|
||||
|
||||
DBUG_ASSERT(initialized);
|
||||
DBUG_ASSERT(type >= 0 && type < MYSQL_CLIENT_MAX_PLUGINS);
|
||||
if (type < 0 || type >= MYSQL_CLIENT_MAX_PLUGINS)
|
||||
return 0;
|
||||
|
||||
for (p= plugin_list[type]; p; p= p->next)
|
||||
{
|
||||
if (strcmp(p->plugin->name, name) == 0)
|
||||
return p->plugin;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
verifies the plugin and adds it to the list
|
||||
|
||||
@param mysql MYSQL structure (for error reporting)
|
||||
@param plugin plugin to install
|
||||
@param dlhandle a handle to the shared object (returned by dlopen)
|
||||
or 0 if the plugin was not dynamically loaded
|
||||
@param argc number of arguments in the 'va_list args'
|
||||
@param args arguments passed to the plugin initialization function
|
||||
|
||||
@retval a pointer to an installed plugin or 0
|
||||
*/
|
||||
|
||||
static struct st_mysql_client_plugin *
|
||||
add_plugin(MYSQL *mysql, struct st_mysql_client_plugin *plugin, void *dlhandle,
|
||||
int argc, va_list args)
|
||||
{
|
||||
const char *errmsg;
|
||||
struct st_client_plugin_int plugin_int, *p;
|
||||
char errbuf[1024];
|
||||
|
||||
DBUG_ASSERT(initialized);
|
||||
|
||||
plugin_int.plugin= plugin;
|
||||
plugin_int.dlhandle= dlhandle;
|
||||
|
||||
if (plugin->type >= MYSQL_CLIENT_MAX_PLUGINS)
|
||||
{
|
||||
errmsg= "Unknown client plugin type";
|
||||
goto err1;
|
||||
}
|
||||
|
||||
if (plugin->interface_version < plugin_version[plugin->type] ||
|
||||
(plugin->interface_version >> 8) >
|
||||
(plugin_version[plugin->type] >> 8))
|
||||
{
|
||||
errmsg= "Incompatible client plugin interface";
|
||||
goto err1;
|
||||
}
|
||||
|
||||
/* Call the plugin initialization function, if any */
|
||||
if (plugin->init && plugin->init(errbuf, sizeof(errbuf), argc, args))
|
||||
{
|
||||
errmsg= errbuf;
|
||||
goto err1;
|
||||
}
|
||||
|
||||
p= (struct st_client_plugin_int *)
|
||||
memdup_root(&mem_root, (char *)&plugin_int, sizeof(plugin_int));
|
||||
|
||||
if (!p)
|
||||
{
|
||||
errmsg= "Out of memory";
|
||||
goto err2;
|
||||
}
|
||||
|
||||
safe_mutex_assert_owner(&LOCK_load_client_plugin);
|
||||
|
||||
p->next= plugin_list[plugin->type];
|
||||
plugin_list[plugin->type]= p;
|
||||
|
||||
return plugin;
|
||||
|
||||
err2:
|
||||
if (plugin->deinit)
|
||||
plugin->deinit();
|
||||
err1:
|
||||
if (dlhandle)
|
||||
(void)dlclose(dlhandle);
|
||||
my_set_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD, SQLSTATE_UNKNOWN,
|
||||
ER(CR_AUTH_PLUGIN_CANNOT_LOAD), plugin->name, errmsg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Loads plugins which are specified in the environment variable
|
||||
LIBMYSQL_PLUGINS.
|
||||
|
||||
Multiple plugins must be separated by semicolon. This function doesn't
|
||||
return or log an error.
|
||||
|
||||
The function is be called by mysql_client_plugin_init
|
||||
|
||||
@todo
|
||||
Support extended syntax, passing parameters to plugins, for example
|
||||
LIBMYSQL_PLUGINS="plugin1(param1,param2);plugin2;..."
|
||||
or
|
||||
LIBMYSQL_PLUGINS="plugin1=int:param1,str:param2;plugin2;..."
|
||||
*/
|
||||
|
||||
static void load_env_plugins(MYSQL *mysql)
|
||||
{
|
||||
char *plugs, *free_env, *s= getenv("LIBMYSQL_PLUGINS");
|
||||
|
||||
/* no plugins to load */
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
free_env= plugs= my_strdup(s, MYF(MY_WME));
|
||||
|
||||
do {
|
||||
if ((s= strchr(plugs, ';')))
|
||||
*s= '\0';
|
||||
mysql_load_plugin(mysql, plugs, -1, 0);
|
||||
plugs= s + 1;
|
||||
} while (s);
|
||||
|
||||
my_free(free_env, MYF(0));
|
||||
}
|
||||
|
||||
/********** extern functions to be used by libmysql *********************/
|
||||
|
||||
/**
|
||||
Initializes the client plugin layer.
|
||||
|
||||
This function must be called before any other client plugin function.
|
||||
|
||||
@retval 0 successful
|
||||
@retval != 0 error occured
|
||||
*/
|
||||
|
||||
int mysql_client_plugin_init()
|
||||
{
|
||||
MYSQL mysql;
|
||||
struct st_mysql_client_plugin **builtin;
|
||||
va_list unused;
|
||||
LINT_INIT_STRUCT(unused);
|
||||
|
||||
if (initialized)
|
||||
return 0;
|
||||
|
||||
bzero(&mysql, sizeof(mysql)); /* dummy mysql for set_mysql_extended_error */
|
||||
|
||||
pthread_mutex_init(&LOCK_load_client_plugin, MY_MUTEX_INIT_SLOW);
|
||||
init_alloc_root(&mem_root, 128, 128);
|
||||
|
||||
bzero(&plugin_list, sizeof(plugin_list));
|
||||
|
||||
initialized= 1;
|
||||
|
||||
pthread_mutex_lock(&LOCK_load_client_plugin);
|
||||
|
||||
for (builtin= mysql_client_builtins; *builtin; builtin++)
|
||||
add_plugin(&mysql, *builtin, 0, 0, unused);
|
||||
|
||||
pthread_mutex_unlock(&LOCK_load_client_plugin);
|
||||
|
||||
load_env_plugins(&mysql);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Deinitializes the client plugin layer.
|
||||
|
||||
Unloades all client plugins and frees any associated resources.
|
||||
*/
|
||||
|
||||
void mysql_client_plugin_deinit()
|
||||
{
|
||||
int i;
|
||||
struct st_client_plugin_int *p;
|
||||
|
||||
if (!initialized)
|
||||
return;
|
||||
|
||||
for (i=0; i < MYSQL_CLIENT_MAX_PLUGINS; i++)
|
||||
for (p= plugin_list[i]; p; p= p->next)
|
||||
{
|
||||
if (p->plugin->deinit)
|
||||
p->plugin->deinit();
|
||||
if (p->dlhandle)
|
||||
(void)dlclose(p->dlhandle);
|
||||
}
|
||||
|
||||
bzero(&plugin_list, sizeof(plugin_list));
|
||||
initialized= 0;
|
||||
free_root(&mem_root, MYF(0));
|
||||
pthread_mutex_destroy(&LOCK_load_client_plugin);
|
||||
}
|
||||
|
||||
/************* public facing functions, for client consumption *********/
|
||||
|
||||
/* see <mysql/client_plugin.h> for a full description */
|
||||
struct st_mysql_client_plugin *
|
||||
mysql_client_register_plugin(MYSQL *mysql,
|
||||
struct st_mysql_client_plugin *plugin)
|
||||
{
|
||||
va_list unused;
|
||||
LINT_INIT_STRUCT(unused);
|
||||
|
||||
if (is_not_initialized(mysql, plugin->name))
|
||||
return NULL;
|
||||
|
||||
pthread_mutex_lock(&LOCK_load_client_plugin);
|
||||
|
||||
/* make sure the plugin wasn't loaded meanwhile */
|
||||
if (find_plugin(plugin->name, plugin->type))
|
||||
{
|
||||
my_set_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD,
|
||||
SQLSTATE_UNKNOWN, ER(CR_AUTH_PLUGIN_CANNOT_LOAD),
|
||||
plugin->name, "it is already loaded");
|
||||
plugin= NULL;
|
||||
}
|
||||
else
|
||||
plugin= add_plugin(mysql, plugin, 0, 0, unused);
|
||||
|
||||
pthread_mutex_unlock(&LOCK_load_client_plugin);
|
||||
return plugin;
|
||||
}
|
||||
|
||||
|
||||
/* see <mysql/client_plugin.h> for a full description */
|
||||
struct st_mysql_client_plugin *
|
||||
mysql_load_plugin_v(MYSQL *mysql, const char *name, int type,
|
||||
int argc, va_list args)
|
||||
{
|
||||
const char *errmsg;
|
||||
#ifdef _WIN32
|
||||
char errbuf[255];
|
||||
#endif
|
||||
char dlpath[FN_REFLEN+1];
|
||||
void *sym, *dlhandle;
|
||||
struct st_mysql_client_plugin *plugin;
|
||||
|
||||
if (is_not_initialized(mysql, name))
|
||||
return NULL;
|
||||
|
||||
pthread_mutex_lock(&LOCK_load_client_plugin);
|
||||
|
||||
/* make sure the plugin wasn't loaded meanwhile */
|
||||
if (type >= 0 && find_plugin(name, type))
|
||||
{
|
||||
errmsg= "it is already loaded";
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Compile dll path */
|
||||
strxnmov(dlpath, sizeof(dlpath) - 1,
|
||||
mysql->options.extension && mysql->options.extension->plugin_dir ?
|
||||
mysql->options.extension->plugin_dir : PLUGINDIR, "/",
|
||||
name, SO_EXT, NullS);
|
||||
|
||||
/* Open new dll handle */
|
||||
if (!(dlhandle= dlopen(dlpath, RTLD_NOW)))
|
||||
{
|
||||
#ifdef _WIN32
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL,
|
||||
GetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR)&errbuf, 255, NULL);
|
||||
errmsg= errbuf;
|
||||
#else
|
||||
errmsg= dlerror();
|
||||
#endif
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!(sym= dlsym(dlhandle, plugin_declarations_sym)))
|
||||
{
|
||||
errmsg= "not a plugin";
|
||||
(void)dlclose(dlhandle);
|
||||
goto err;
|
||||
}
|
||||
|
||||
plugin= (struct st_mysql_client_plugin*)sym;
|
||||
|
||||
if (type >=0 && type != plugin->type)
|
||||
{
|
||||
errmsg= "type mismatch";
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (strcmp(name, plugin->name))
|
||||
{
|
||||
errmsg= "name mismatch";
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (type < 0 && find_plugin(name, plugin->type))
|
||||
{
|
||||
errmsg= "it is already loaded";
|
||||
goto err;
|
||||
}
|
||||
|
||||
plugin= add_plugin(mysql, plugin, dlhandle, argc, args);
|
||||
|
||||
pthread_mutex_unlock(&LOCK_load_client_plugin);
|
||||
|
||||
return plugin;
|
||||
|
||||
err:
|
||||
pthread_mutex_unlock(&LOCK_load_client_plugin);
|
||||
my_set_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD, SQLSTATE_UNKNOWN,
|
||||
ER(CR_AUTH_PLUGIN_CANNOT_LOAD), name, errmsg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* see <mysql/client_plugin.h> for a full description */
|
||||
struct st_mysql_client_plugin *
|
||||
mysql_load_plugin(MYSQL *mysql, const char *name, int type, int argc, ...)
|
||||
{
|
||||
struct st_mysql_client_plugin *p;
|
||||
va_list args;
|
||||
va_start(args, argc);
|
||||
p= mysql_load_plugin_v(mysql, name, type, argc, args);
|
||||
va_end(args);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/* see <mysql/client_plugin.h> for a full description */
|
||||
struct st_mysql_client_plugin *
|
||||
mysql_client_find_plugin(MYSQL *mysql, const char *name, int type)
|
||||
{
|
||||
struct st_mysql_client_plugin *p;
|
||||
|
||||
if (is_not_initialized(mysql, name))
|
||||
return NULL;
|
||||
|
||||
if (type < 0 || type >= MYSQL_CLIENT_MAX_PLUGINS)
|
||||
{
|
||||
my_set_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD, SQLSTATE_UNKNOWN,
|
||||
ER(CR_AUTH_PLUGIN_CANNOT_LOAD), name, "invalid type");
|
||||
}
|
||||
|
||||
if ((p= find_plugin(name, type)))
|
||||
return p;
|
||||
|
||||
/* not found, load it */
|
||||
return mysql_load_plugin(mysql, name, type, 0);
|
||||
}
|
||||
|
||||
|
@ -1,34 +0,0 @@
|
||||
# Install script for directory: /home/georg/priv/monty/libmysql-lgpl-3.23/libmysql
|
||||
|
||||
# Set the install prefix
|
||||
IF(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||
SET(CMAKE_INSTALL_PREFIX "/usr/local")
|
||||
ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||
STRING(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
|
||||
|
||||
# Set the install configuration name.
|
||||
IF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
|
||||
IF(BUILD_TYPE)
|
||||
STRING(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
|
||||
CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
|
||||
ELSE(BUILD_TYPE)
|
||||
SET(CMAKE_INSTALL_CONFIG_NAME "Debug")
|
||||
ENDIF(BUILD_TYPE)
|
||||
MESSAGE(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
|
||||
ENDIF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
|
||||
|
||||
# Set the component getting installed.
|
||||
IF(NOT CMAKE_INSTALL_COMPONENT)
|
||||
IF(COMPONENT)
|
||||
MESSAGE(STATUS "Install component: \"${COMPONENT}\"")
|
||||
SET(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
|
||||
ELSE(COMPONENT)
|
||||
SET(CMAKE_INSTALL_COMPONENT)
|
||||
ENDIF(COMPONENT)
|
||||
ENDIF(NOT CMAKE_INSTALL_COMPONENT)
|
||||
|
||||
# Install shared libraries without execute permission?
|
||||
IF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)
|
||||
SET(CMAKE_INSTALL_SO_NO_EXE "0")
|
||||
ENDIF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)
|
||||
|
@ -1,143 +0,0 @@
|
||||
/* 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 "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, const char *set, const 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;
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
/* 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 */
|
||||
|
||||
#include <my_global.h>
|
||||
#include <m_ctype.h>
|
||||
#include <m_string.h>
|
||||
|
||||
/* generated by make, using conf_to_src */
|
||||
/* #include "ctype_extra_sources.c" */
|
||||
|
||||
/* generated by configure */
|
||||
/* #include "ctype_autoconf.c" */
|
||||
|
||||
CHARSET_INFO *default_charset_info = &compiled_charsets[5];
|
||||
|
||||
CHARSET_INFO *find_compiled_charset(uint cs_number)
|
||||
{
|
||||
CHARSET_INFO *cs;
|
||||
for (cs = compiled_charsets; cs->nr > 0; cs++)
|
||||
if (cs->nr == cs_number)
|
||||
return cs;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CHARSET_INFO *find_compiled_charset_by_name(const char *name)
|
||||
{
|
||||
CHARSET_INFO *cs;
|
||||
for (cs = compiled_charsets; cs->nr > 0; cs++)
|
||||
if (!strcmp(cs->name, name))
|
||||
return cs;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint compiled_charset_number(const char *name)
|
||||
{
|
||||
CHARSET_INFO *cs;
|
||||
for (cs = compiled_charsets; cs->nr > 0; cs++)
|
||||
if (!strcmp(cs->name, name))
|
||||
return cs->nr;
|
||||
|
||||
return 0; /* this mimics find_type() */
|
||||
}
|
||||
|
||||
const char *compiled_charset_name(uint charset_number)
|
||||
{
|
||||
CHARSET_INFO *cs;
|
||||
for (cs = compiled_charsets; cs->nr > 0; cs++)
|
||||
if (cs->nr == charset_number)
|
||||
return cs->name;
|
||||
|
||||
return "?"; /* this mimics get_type() */
|
||||
}
|
@ -72,7 +72,7 @@
|
||||
#include <my_global.h>
|
||||
#include <m_string.h>
|
||||
#include <errno.h>
|
||||
#if defined(MSDOS) || defined(__WIN__)
|
||||
#if defined(MSDOS) || defined(_WIN32)
|
||||
#include <process.h>
|
||||
#endif
|
||||
|
||||
@ -123,7 +123,7 @@
|
||||
* Typedefs to make things more obvious.
|
||||
*/
|
||||
|
||||
#ifndef __WIN__
|
||||
#ifndef _WIN32
|
||||
typedef int BOOLEAN;
|
||||
#else
|
||||
#define BOOLEAN BOOL
|
||||
@ -275,10 +275,8 @@ static BOOLEAN DoTrace(CODE_STATE *state);
|
||||
/* Test to see if file is writable */
|
||||
#if !(!defined(HAVE_ACCESS) || defined(MSDOS))
|
||||
static BOOLEAN Writable(char *pathname);
|
||||
/* Change file owner and group */
|
||||
static void ChangeOwner(char *pathname);
|
||||
/* Allocate memory for runtime support */
|
||||
#endif
|
||||
/* Allocate memory for runtime support */
|
||||
static char *DbugMalloc(int size);
|
||||
/* Remove leading pathname components */
|
||||
static char *BaseName(const char *pathname);
|
||||
@ -317,6 +315,8 @@ static char *static_strtok(char *s1,pchar chr);
|
||||
#endif
|
||||
#ifndef MSDOS
|
||||
#define ChangeOwner(name)
|
||||
#else
|
||||
static void ChangeOwner(char *pathname);
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -1923,7 +1923,7 @@ static void dbug_flush(CODE_STATE *state)
|
||||
if (stack->flags & FLUSH_ON_WRITE)
|
||||
#endif
|
||||
{
|
||||
#if defined(MSDOS) || defined(__WIN__)
|
||||
#if defined(MSDOS) || defined(_WIN32)
|
||||
if (_db_fp_ != stdout && _db_fp_ != stderr)
|
||||
{
|
||||
if (!(freopen(stack->name,"a",_db_fp_)))
|
||||
@ -1990,7 +1990,7 @@ static unsigned long Clock ()
|
||||
return ((ru.ru_utime.tv_sec * 1000) + (ru.ru_utime.tv_usec / 1000));
|
||||
}
|
||||
|
||||
#elif defined(MSDOS) || defined(__WIN__) || defined(OS2)
|
||||
#elif defined(MSDOS) || defined(_WIN32) || defined(OS2)
|
||||
|
||||
static ulong Clock()
|
||||
{
|
||||
|
@ -47,7 +47,7 @@ char *defaults_extra_file=0;
|
||||
/* Which directories are searched for options (and in which order) */
|
||||
|
||||
const char *default_directories[]= {
|
||||
#ifdef __WIN__
|
||||
#ifdef _WIN32
|
||||
"C:/",
|
||||
#else
|
||||
"/etc/",
|
||||
@ -56,14 +56,14 @@ const char *default_directories[]= {
|
||||
DATADIR,
|
||||
#endif
|
||||
"", /* Place for defaults_extra_dir */
|
||||
#ifndef __WIN__
|
||||
#ifndef _WIN32
|
||||
"~/",
|
||||
#endif
|
||||
NullS,
|
||||
};
|
||||
|
||||
#define default_ext ".cnf" /* extension for config file */
|
||||
#ifdef __WIN__
|
||||
#ifdef _WIN32
|
||||
#include <winbase.h>
|
||||
#define windows_ext ".ini"
|
||||
#endif
|
||||
@ -141,7 +141,7 @@ void load_defaults(const char *conf_file, const char **groups,
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef __WIN__
|
||||
#ifdef _WIN32
|
||||
char system_dir[FN_REFLEN];
|
||||
GetWindowsDirectory(system_dir,sizeof(system_dir));
|
||||
if (search_default_file(&args, &alloc, system_dir, conf_file, windows_ext,
|
||||
@ -244,7 +244,7 @@ static my_bool search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
|
||||
strmov(name,config_file);
|
||||
}
|
||||
fn_format(name,name,"","",4);
|
||||
#if !defined(__WIN__) && !defined(OS2)
|
||||
#if !defined(_WIN32) && !defined(OS2)
|
||||
{
|
||||
MY_STAT stat_info;
|
||||
if (!my_stat(name,&stat_info,MYF(0)))
|
||||
@ -364,7 +364,7 @@ static my_bool search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
|
||||
|
||||
void print_defaults(const char *conf_file, const char **groups)
|
||||
{
|
||||
#ifdef __WIN__
|
||||
#ifdef _WIN32
|
||||
bool have_ext=fn_ext(conf_file)[0] != 0;
|
||||
#endif
|
||||
char name[FN_REFLEN];
|
||||
@ -375,7 +375,7 @@ void print_defaults(const char *conf_file, const char **groups)
|
||||
fputs(conf_file,stdout);
|
||||
else
|
||||
{
|
||||
#ifdef __WIN__
|
||||
#ifdef _WIN32
|
||||
GetWindowsDirectory(name,sizeof(name));
|
||||
printf("%s\\%s%s ",name,conf_file,have_ext ? "" : windows_ext);
|
||||
#endif
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <my_global.h>
|
||||
#include <my_sys.h>
|
||||
#include "errmsg.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef GERMAN
|
||||
const char *client_errors[]=
|
||||
@ -39,7 +40,7 @@ const char *client_errors[]=
|
||||
"%-.64s 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",
|
||||
"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)",
|
||||
@ -93,7 +94,7 @@ const char *client_errors[]=
|
||||
/* 2011 */ "%-.64s via TCP/IP",
|
||||
/* 2012 */ "Error in server handshake",
|
||||
/* 2013 */ "Lost connection to MySQL server during query",
|
||||
/* 2014 */ "Commands out of sync; You can't run this command now",
|
||||
/* 2014 */ "Commands out of sync; you can't run this command now",
|
||||
/* 2015 */ "%-.64s via named pipe",
|
||||
/* 2016 */ "Can't wait for named pipe to host: %-.64s pipe: %-.32s (%lu)",
|
||||
/* 2017 */ "Can't open named pipe to host: %-.64s pipe: %-.32s (%lu)",
|
||||
@ -106,7 +107,7 @@ const char *client_errors[]=
|
||||
/* 2024 */ "",
|
||||
/* 2025 */ "",
|
||||
/* 2026 */ "",
|
||||
/* 2027 */ "",
|
||||
/* 2027 */ "received malformed packet",
|
||||
/* 2028 */ "",
|
||||
/* 2029 */ "",
|
||||
/* 2030 */ "",
|
||||
@ -137,7 +138,9 @@ const char *client_errors[]=
|
||||
/* 2055 */ "",
|
||||
/* 2056 */ "",
|
||||
/* 2057 */ "The number of parameters in bound buffers differs from number of columns in resultset",
|
||||
/* 2058 */ "Can't connect twice. Already connected"
|
||||
/* 2058 */ "Can't connect twice. Already connected",
|
||||
/* 2059 */ "Plugin %s could not be loaded: %s",
|
||||
""
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include <pwd.h>
|
||||
#endif /* HAVE_PWD_H */
|
||||
#else /* ! HAVE_GETPASS */
|
||||
#if !defined( __WIN__) && !defined(OS2)
|
||||
#if !defined( _WIN32) && !defined(OS2)
|
||||
#include <sys/ioctl.h>
|
||||
#ifdef HAVE_TERMIOS_H /* For tty-password */
|
||||
#include <termios.h>
|
||||
@ -55,14 +55,14 @@
|
||||
#endif
|
||||
#else
|
||||
#include <conio.h>
|
||||
#endif /* __WIN__ */
|
||||
#endif /* _WIN32 */
|
||||
#endif /* HAVE_GETPASS */
|
||||
|
||||
#ifdef HAVE_GETPASSPHRASE /* For Solaris */
|
||||
#define getpass(A) getpassphrase(A)
|
||||
#define getpass(A) getpassphrase(A)
|
||||
#endif
|
||||
|
||||
#if defined( __WIN__) || defined(OS2)
|
||||
#if defined( _WIN32) || defined(OS2)
|
||||
/* were just going to fake it here and get input from the keyboard */
|
||||
|
||||
char *get_tty_password(char *opt_message)
|
||||
@ -208,4 +208,4 @@ char *get_tty_password(char *opt_message)
|
||||
|
||||
DBUG_RETURN(my_strdup(buff,MYF(MY_FAE)));
|
||||
}
|
||||
#endif /*__WIN__*/
|
||||
#endif /*_WIN32*/
|
||||
|
@ -176,10 +176,6 @@ static char *posixly_correct;
|
||||
/* Avoid depending on library functions or files
|
||||
whose names are inconsistent. */
|
||||
|
||||
#ifndef OS2
|
||||
char *getenv (const char *);
|
||||
#endif
|
||||
|
||||
static char *
|
||||
my_index (const char *str, int chr)
|
||||
{
|
||||
|
@ -47,9 +47,9 @@ Cambridge, MA 02139, USA. */
|
||||
|
||||
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
|
||||
|
||||
#ifndef __WIN__
|
||||
#ifndef _WIN32
|
||||
#include <stdlib.h>
|
||||
#endif /* __WIN__ */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
|
@ -1,112 +0,0 @@
|
||||
/* 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 */
|
||||
|
||||
/* Allow use of the -O variable= option to set long variables */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include <m_string.h>
|
||||
#include <m_ctype.h>
|
||||
|
||||
/* set all changeable variables */
|
||||
|
||||
void set_all_changeable_vars(CHANGEABLE_VAR *vars)
|
||||
{
|
||||
for ( ; vars->name ; vars++)
|
||||
*vars->varptr= vars->def_value;
|
||||
}
|
||||
|
||||
|
||||
my_bool set_changeable_varval(const char* var, ulong val,
|
||||
CHANGEABLE_VAR *vars)
|
||||
{
|
||||
char buffer[256];
|
||||
sprintf( buffer, "%s=%lu", var, (unsigned long) val );
|
||||
return set_changeable_var( buffer, vars );
|
||||
}
|
||||
|
||||
|
||||
my_bool set_changeable_var(my_string str,CHANGEABLE_VAR *vars)
|
||||
{
|
||||
char endchar;
|
||||
my_string end;
|
||||
DBUG_ENTER("set_changeable_var");
|
||||
DBUG_PRINT("enter",("%s",str));
|
||||
|
||||
if (str)
|
||||
{
|
||||
if (!(end=strchr(str,'=')))
|
||||
fprintf(stderr,"Can't find '=' in expression '%s' to option -O\n",str);
|
||||
else
|
||||
{
|
||||
uint length,found_count=0;
|
||||
CHANGEABLE_VAR *var,*found;
|
||||
my_string var_end;
|
||||
const char *name;
|
||||
longlong num;
|
||||
|
||||
/* Skip end space from variable */
|
||||
for (var_end=end ; end > str && isspace(var_end[-1]) ; var_end--) ;
|
||||
length=(uint) (var_end-str);
|
||||
/* Skip start space from argument */
|
||||
for (end++ ; isspace(*end) ; end++) ;
|
||||
|
||||
for (var=vars,found=0 ; (name=var->name) ; var++)
|
||||
{
|
||||
if (!my_casecmp(name,str,length))
|
||||
{
|
||||
found=var; found_count++;
|
||||
if (!name[length])
|
||||
{
|
||||
found_count=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found_count == 0)
|
||||
{
|
||||
fprintf(stderr,"No variable match for: -O '%s'\n",str);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (found_count > 1)
|
||||
{
|
||||
fprintf(stderr,"Variable prefix '%*s' is not unique\n",length,str);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
num=strtoll(end, (char **)NULL, 10); endchar=strend(end)[-1];
|
||||
if (endchar == 'k' || endchar == 'K')
|
||||
num*=1024;
|
||||
else if (endchar == 'm' || endchar == 'M')
|
||||
num*=1024L*1024L;
|
||||
else if (endchar == 'g' || endchar == 'G')
|
||||
num*=1024L*1024L*1024L;
|
||||
else if (!isdigit(endchar))
|
||||
{
|
||||
fprintf(stderr,"Unknown prefix used for variable value '%s'\n",str);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (num < (longlong) found->min_value)
|
||||
num=(longlong) found->min_value;
|
||||
else if (num > 0 && (ulonglong) num > (ulonglong) (ulong) found->max_value)
|
||||
num=(longlong) (ulong) found->max_value;
|
||||
num=((num- (longlong) found->sub_size) / (ulonglong) found->block_size);
|
||||
(*found->varptr)= (long) (num*(ulonglong) found->block_size);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
}
|
||||
DBUG_RETURN(1);
|
||||
}
|
640
libmysql/hash.c
640
libmysql/hash.c
@ -1,640 +0,0 @@
|
||||
/* 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 */
|
||||
|
||||
/* The hash functions used for saveing keys */
|
||||
/* One of key_length or key_length_offset must be given */
|
||||
/* Key length of 0 isn't allowed */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include <m_string.h>
|
||||
#include <m_ctype.h>
|
||||
#include "hash.h"
|
||||
|
||||
#define NO_RECORD ((uint) -1)
|
||||
#define LOWFIND 1
|
||||
#define LOWUSED 2
|
||||
#define HIGHFIND 4
|
||||
#define HIGHUSED 8
|
||||
|
||||
static uint hash_mask(uint hashnr,uint buffmax,uint maxlength);
|
||||
static void movelink(HASH_LINK *array,uint pos,uint next_link,uint newlink);
|
||||
static uint calc_hashnr(const byte *key,uint length);
|
||||
static uint calc_hashnr_caseup(const byte *key,uint length);
|
||||
static int hashcmp(HASH *hash,HASH_LINK *pos,const byte *key,uint length);
|
||||
|
||||
|
||||
my_bool _hash_init(HASH *hash,uint size,uint key_offset,uint key_length,
|
||||
hash_get_key get_key,
|
||||
void (*free_element)(void*),uint flags CALLER_INFO_PROTO)
|
||||
{
|
||||
DBUG_ENTER("hash_init");
|
||||
DBUG_PRINT("enter",("hash: %lx size: %d",hash,size));
|
||||
|
||||
hash->records=0;
|
||||
if (my_init_dynamic_array_ci(&hash->array,sizeof(HASH_LINK),size,0))
|
||||
{
|
||||
hash->free=0; /* Allow call to hash_free */
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
hash->key_offset=key_offset;
|
||||
hash->key_length=key_length;
|
||||
hash->blength=1;
|
||||
hash->current_record= NO_RECORD; /* For the future */
|
||||
hash->get_key=get_key;
|
||||
hash->free=free_element;
|
||||
hash->flags=flags;
|
||||
if (flags & HASH_CASE_INSENSITIVE)
|
||||
hash->calc_hashnr=calc_hashnr_caseup;
|
||||
else
|
||||
hash->calc_hashnr=calc_hashnr;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
void hash_free(HASH *hash)
|
||||
{
|
||||
DBUG_ENTER("hash_free");
|
||||
if (hash->free)
|
||||
{
|
||||
uint i,records;
|
||||
HASH_LINK *data=dynamic_element(&hash->array,0,HASH_LINK*);
|
||||
for (i=0,records=hash->records ; i < records ; i++)
|
||||
(*hash->free)(data[i].data);
|
||||
hash->free=0;
|
||||
}
|
||||
delete_dynamic(&hash->array);
|
||||
hash->records=0;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/* some helper functions */
|
||||
|
||||
/*
|
||||
This function is char* instead of byte* as HPUX11 compiler can't
|
||||
handle inline functions that are not defined as native types
|
||||
*/
|
||||
|
||||
inline char*
|
||||
hash_key(HASH *hash,const byte *record,uint *length,my_bool first)
|
||||
{
|
||||
if (hash->get_key)
|
||||
return (*hash->get_key)(record,length,first);
|
||||
*length=hash->key_length;
|
||||
return (byte*) record+hash->key_offset;
|
||||
}
|
||||
|
||||
/* Calculate pos according to keys */
|
||||
|
||||
static uint hash_mask(uint hashnr,uint buffmax,uint maxlength)
|
||||
{
|
||||
if ((hashnr & (buffmax-1)) < maxlength) return (hashnr & (buffmax-1));
|
||||
return (hashnr & ((buffmax >> 1) -1));
|
||||
}
|
||||
|
||||
static uint hash_rec_mask(HASH *hash,HASH_LINK *pos,uint buffmax,
|
||||
uint maxlength)
|
||||
{
|
||||
uint length;
|
||||
byte *key= (byte*) hash_key(hash,pos->data,&length,0);
|
||||
return hash_mask((*hash->calc_hashnr)(key,length),buffmax,maxlength);
|
||||
}
|
||||
|
||||
#ifndef NEW_HASH_FUNCTION
|
||||
|
||||
/* Calc hashvalue for a key */
|
||||
|
||||
static uint calc_hashnr(const byte *key,uint length)
|
||||
{
|
||||
register uint nr=1, nr2=4;
|
||||
while (length--)
|
||||
{
|
||||
nr^= (((nr & 63)+nr2)*((uint) (uchar) *key++))+ (nr << 8);
|
||||
nr2+=3;
|
||||
}
|
||||
return((uint) nr);
|
||||
}
|
||||
|
||||
/* Calc hashvalue for a key, case indepenently */
|
||||
|
||||
static uint calc_hashnr_caseup(const byte *key,uint length)
|
||||
{
|
||||
register uint nr=1, nr2=4;
|
||||
while (length--)
|
||||
{
|
||||
nr^= (((nr & 63)+nr2)*((uint) (uchar) toupper(*key++)))+ (nr << 8);
|
||||
nr2+=3;
|
||||
}
|
||||
return((uint) nr);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Fowler/Noll/Vo hash
|
||||
*
|
||||
* The basis of the hash algorithm was taken from an idea sent by email to the
|
||||
* IEEE Posix P1003.2 mailing list from Phong Vo (kpv@research.att.com) and
|
||||
* Glenn Fowler (gsf@research.att.com). Landon Curt Noll (chongo@toad.com)
|
||||
* later improved on their algorithm.
|
||||
*
|
||||
* The magic is in the interesting relationship between the special prime
|
||||
* 16777619 (2^24 + 403) and 2^32 and 2^8.
|
||||
*
|
||||
* This hash produces the fewest collisions of any function that we've seen so
|
||||
* far, and works well on both numbers and strings.
|
||||
*/
|
||||
|
||||
uint calc_hashnr(const byte *key, uint len)
|
||||
{
|
||||
const byte *end=key+len;
|
||||
uint hash;
|
||||
for (hash = 0; key < end; key++)
|
||||
{
|
||||
hash *= 16777619;
|
||||
hash ^= (uint) *(uchar*) key;
|
||||
}
|
||||
return (hash);
|
||||
}
|
||||
|
||||
uint calc_hashnr_caseup(const byte *key, uint len)
|
||||
{
|
||||
const byte *end=key+len;
|
||||
uint hash;
|
||||
for (hash = 0; key < end; key++)
|
||||
{
|
||||
hash *= 16777619;
|
||||
hash ^= (uint) (uchar) toupper(*key);
|
||||
}
|
||||
return (hash);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __SUNPRO_C /* SUNPRO can't handle this */
|
||||
inline
|
||||
#endif
|
||||
unsigned int rec_hashnr(HASH *hash,const byte *record)
|
||||
{
|
||||
uint length;
|
||||
byte *key= (byte*) hash_key(hash,record,&length,0);
|
||||
return (*hash->calc_hashnr)(key,length);
|
||||
}
|
||||
|
||||
|
||||
/* Search after a record based on a key */
|
||||
/* Sets info->current_ptr to found record */
|
||||
|
||||
gptr hash_search(HASH *hash,const byte *key,uint length)
|
||||
{
|
||||
HASH_LINK *pos;
|
||||
uint flag,idx;
|
||||
DBUG_ENTER("hash_search");
|
||||
|
||||
flag=1;
|
||||
if (hash->records)
|
||||
{
|
||||
idx=hash_mask((*hash->calc_hashnr)(key,length ? length :
|
||||
hash->key_length),
|
||||
hash->blength,hash->records);
|
||||
do
|
||||
{
|
||||
pos= dynamic_element(&hash->array,idx,HASH_LINK*);
|
||||
if (!hashcmp(hash,pos,key,length))
|
||||
{
|
||||
DBUG_PRINT("exit",("found key at %d",idx));
|
||||
hash->current_record= idx;
|
||||
DBUG_RETURN (pos->data);
|
||||
}
|
||||
if (flag)
|
||||
{
|
||||
flag=0; /* Reset flag */
|
||||
if (hash_rec_mask(hash,pos,hash->blength,hash->records) != idx)
|
||||
break; /* Wrong link */
|
||||
}
|
||||
}
|
||||
while ((idx=pos->next) != NO_RECORD);
|
||||
}
|
||||
hash->current_record= NO_RECORD;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/* Get next record with identical key */
|
||||
/* Can only be called if previous calls was hash_search */
|
||||
|
||||
gptr hash_next(HASH *hash,const byte *key,uint length)
|
||||
{
|
||||
HASH_LINK *pos;
|
||||
uint idx;
|
||||
|
||||
if (hash->current_record != NO_RECORD)
|
||||
{
|
||||
HASH_LINK *data=dynamic_element(&hash->array,0,HASH_LINK*);
|
||||
for (idx=data[hash->current_record].next; idx != NO_RECORD ; idx=pos->next)
|
||||
{
|
||||
pos=data+idx;
|
||||
if (!hashcmp(hash,pos,key,length))
|
||||
{
|
||||
hash->current_record= idx;
|
||||
return pos->data;
|
||||
}
|
||||
}
|
||||
hash->current_record=NO_RECORD;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Change link from pos to new_link */
|
||||
|
||||
static void movelink(HASH_LINK *array,uint find,uint next_link,uint newlink)
|
||||
{
|
||||
HASH_LINK *old_link;
|
||||
do
|
||||
{
|
||||
old_link=array+next_link;
|
||||
}
|
||||
while ((next_link=old_link->next) != find);
|
||||
old_link->next= newlink;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Compare a key in a record to a whole key. Return 0 if identical */
|
||||
|
||||
static int hashcmp(HASH *hash,HASH_LINK *pos,const byte *key,uint length)
|
||||
{
|
||||
uint rec_keylength;
|
||||
byte *rec_key= (byte*) hash_key(hash,pos->data,&rec_keylength,1);
|
||||
return (length && length != rec_keylength) ||
|
||||
(hash->flags & HASH_CASE_INSENSITIVE ?
|
||||
my_casecmp(rec_key,key,rec_keylength) :
|
||||
memcmp(rec_key,key,rec_keylength));
|
||||
}
|
||||
|
||||
|
||||
/* Write a hash-key to the hash-index */
|
||||
|
||||
my_bool hash_insert(HASH *info,const byte *record)
|
||||
{
|
||||
int flag;
|
||||
uint halfbuff,hash_nr,first_index,idx;
|
||||
byte *ptr_to_rec,*ptr_to_rec2;
|
||||
HASH_LINK *data,*empty,*gpos,*gpos2,*pos;
|
||||
|
||||
LINT_INIT(gpos); LINT_INIT(gpos2);
|
||||
LINT_INIT(ptr_to_rec); LINT_INIT(ptr_to_rec2);
|
||||
|
||||
flag=0;
|
||||
if (!(empty=(HASH_LINK*) alloc_dynamic(&info->array)))
|
||||
return(TRUE); /* No more memory */
|
||||
|
||||
info->current_record= NO_RECORD;
|
||||
data=dynamic_element(&info->array,0,HASH_LINK*);
|
||||
halfbuff= info->blength >> 1;
|
||||
|
||||
idx=first_index=info->records-halfbuff;
|
||||
if (idx != info->records) /* If some records */
|
||||
{
|
||||
do
|
||||
{
|
||||
pos=data+idx;
|
||||
hash_nr=rec_hashnr(info,pos->data);
|
||||
if (flag == 0) /* First loop; Check if ok */
|
||||
if (hash_mask(hash_nr,info->blength,info->records) != first_index)
|
||||
break;
|
||||
if (!(hash_nr & halfbuff))
|
||||
{ /* Key will not move */
|
||||
if (!(flag & LOWFIND))
|
||||
{
|
||||
if (flag & HIGHFIND)
|
||||
{
|
||||
flag=LOWFIND | HIGHFIND;
|
||||
/* key shall be moved to the current empty position */
|
||||
gpos=empty;
|
||||
ptr_to_rec=pos->data;
|
||||
empty=pos; /* This place is now free */
|
||||
}
|
||||
else
|
||||
{
|
||||
flag=LOWFIND | LOWUSED; /* key isn't changed */
|
||||
gpos=pos;
|
||||
ptr_to_rec=pos->data;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(flag & LOWUSED))
|
||||
{
|
||||
/* Change link of previous LOW-key */
|
||||
gpos->data=ptr_to_rec;
|
||||
gpos->next=(uint) (pos-data);
|
||||
flag= (flag & HIGHFIND) | (LOWFIND | LOWUSED);
|
||||
}
|
||||
gpos=pos;
|
||||
ptr_to_rec=pos->data;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /* key will be moved */
|
||||
if (!(flag & HIGHFIND))
|
||||
{
|
||||
flag= (flag & LOWFIND) | HIGHFIND;
|
||||
/* key shall be moved to the last (empty) position */
|
||||
gpos2 = empty; empty=pos;
|
||||
ptr_to_rec2=pos->data;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(flag & HIGHUSED))
|
||||
{
|
||||
/* Change link of previous hash-key and save */
|
||||
gpos2->data=ptr_to_rec2;
|
||||
gpos2->next=(uint) (pos-data);
|
||||
flag= (flag & LOWFIND) | (HIGHFIND | HIGHUSED);
|
||||
}
|
||||
gpos2=pos;
|
||||
ptr_to_rec2=pos->data;
|
||||
}
|
||||
}
|
||||
}
|
||||
while ((idx=pos->next) != NO_RECORD);
|
||||
|
||||
if ((flag & (LOWFIND | LOWUSED)) == LOWFIND)
|
||||
{
|
||||
gpos->data=ptr_to_rec;
|
||||
gpos->next=NO_RECORD;
|
||||
}
|
||||
if ((flag & (HIGHFIND | HIGHUSED)) == HIGHFIND)
|
||||
{
|
||||
gpos2->data=ptr_to_rec2;
|
||||
gpos2->next=NO_RECORD;
|
||||
}
|
||||
}
|
||||
/* Check if we are at the empty position */
|
||||
|
||||
idx=hash_mask(rec_hashnr(info,record),info->blength,info->records+1);
|
||||
pos=data+idx;
|
||||
if (pos == empty)
|
||||
{
|
||||
pos->data=(byte*) record;
|
||||
pos->next=NO_RECORD;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check if more records in same hash-nr family */
|
||||
empty[0]=pos[0];
|
||||
gpos=data+hash_rec_mask(info,pos,info->blength,info->records+1);
|
||||
if (pos == gpos)
|
||||
{
|
||||
pos->data=(byte*) record;
|
||||
pos->next=(uint) (empty - data);
|
||||
}
|
||||
else
|
||||
{
|
||||
pos->data=(byte*) record;
|
||||
pos->next=NO_RECORD;
|
||||
movelink(data,(uint) (pos-data),(uint) (gpos-data),(uint) (empty-data));
|
||||
}
|
||||
}
|
||||
if (++info->records == info->blength)
|
||||
info->blength+= info->blength;
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
** Remove one record from hash-table. The record with the same record
|
||||
** ptr is removed.
|
||||
** if there is a free-function it's called for record if found
|
||||
******************************************************************************/
|
||||
|
||||
my_bool hash_delete(HASH *hash,byte *record)
|
||||
{
|
||||
uint blength,pos2,pos_hashnr,lastpos_hashnr,idx,empty_index;
|
||||
HASH_LINK *data,*lastpos,*gpos,*pos,*pos3,*empty;
|
||||
DBUG_ENTER("hash_delete");
|
||||
if (!hash->records)
|
||||
DBUG_RETURN(1);
|
||||
|
||||
blength=hash->blength;
|
||||
data=dynamic_element(&hash->array,0,HASH_LINK*);
|
||||
/* Search after record with key */
|
||||
pos=data+ hash_mask(rec_hashnr(hash,record),blength,hash->records);
|
||||
gpos = 0;
|
||||
|
||||
while (pos->data != record)
|
||||
{
|
||||
gpos=pos;
|
||||
if (pos->next == NO_RECORD)
|
||||
DBUG_RETURN(1); /* Key not found */
|
||||
pos=data+pos->next;
|
||||
}
|
||||
|
||||
if ( --(hash->records) < hash->blength >> 1) hash->blength>>=1;
|
||||
hash->current_record= NO_RECORD;
|
||||
lastpos=data+hash->records;
|
||||
|
||||
/* Remove link to record */
|
||||
empty=pos; empty_index=(uint) (empty-data);
|
||||
if (gpos)
|
||||
gpos->next=pos->next; /* unlink current ptr */
|
||||
else if (pos->next != NO_RECORD)
|
||||
{
|
||||
empty=data+(empty_index=pos->next);
|
||||
pos->data=empty->data;
|
||||
pos->next=empty->next;
|
||||
}
|
||||
|
||||
if (empty == lastpos) /* last key at wrong pos or no next link */
|
||||
goto exit;
|
||||
|
||||
/* Move the last key (lastpos) */
|
||||
lastpos_hashnr=rec_hashnr(hash,lastpos->data);
|
||||
/* pos is where lastpos should be */
|
||||
pos=data+hash_mask(lastpos_hashnr,hash->blength,hash->records);
|
||||
if (pos == empty) /* Move to empty position. */
|
||||
{
|
||||
empty[0]=lastpos[0];
|
||||
goto exit;
|
||||
}
|
||||
pos_hashnr=rec_hashnr(hash,pos->data);
|
||||
/* pos3 is where the pos should be */
|
||||
pos3= data+hash_mask(pos_hashnr,hash->blength,hash->records);
|
||||
if (pos != pos3)
|
||||
{ /* pos is on wrong posit */
|
||||
empty[0]=pos[0]; /* Save it here */
|
||||
pos[0]=lastpos[0]; /* This should be here */
|
||||
movelink(data,(uint) (pos-data),(uint) (pos3-data),empty_index);
|
||||
goto exit;
|
||||
}
|
||||
pos2= hash_mask(lastpos_hashnr,blength,hash->records+1);
|
||||
if (pos2 == hash_mask(pos_hashnr,blength,hash->records+1))
|
||||
{ /* Identical key-positions */
|
||||
if (pos2 != hash->records)
|
||||
{
|
||||
empty[0]=lastpos[0];
|
||||
movelink(data,(uint) (lastpos-data),(uint) (pos-data),empty_index);
|
||||
goto exit;
|
||||
}
|
||||
idx= (uint) (pos-data); /* Link pos->next after lastpos */
|
||||
}
|
||||
else idx= NO_RECORD; /* Different positions merge */
|
||||
|
||||
empty[0]=lastpos[0];
|
||||
movelink(data,idx,empty_index,pos->next);
|
||||
pos->next=empty_index;
|
||||
|
||||
exit:
|
||||
VOID(pop_dynamic(&hash->array));
|
||||
if (hash->free)
|
||||
(*hash->free)((byte*) record);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/*
|
||||
Update keys when record has changed.
|
||||
This is much more efficent than using a delete & insert.
|
||||
*/
|
||||
|
||||
my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length)
|
||||
{
|
||||
uint idx,new_index,new_pos_index,blength,records,empty;
|
||||
HASH_LINK org_link,*data,*previous,*pos;
|
||||
DBUG_ENTER("hash_update");
|
||||
|
||||
data=dynamic_element(&hash->array,0,HASH_LINK*);
|
||||
blength=hash->blength; records=hash->records;
|
||||
|
||||
/* Search after record with key */
|
||||
|
||||
idx=hash_mask((*hash->calc_hashnr)(old_key,(old_key_length ?
|
||||
old_key_length :
|
||||
hash->key_length)),
|
||||
blength,records);
|
||||
new_index=hash_mask(rec_hashnr(hash,record),blength,records);
|
||||
if (idx == new_index)
|
||||
DBUG_RETURN(0); /* Nothing to do (No record check) */
|
||||
previous=0;
|
||||
for (;;)
|
||||
{
|
||||
|
||||
if ((pos= data+idx)->data == record)
|
||||
break;
|
||||
previous=pos;
|
||||
if ((idx=pos->next) == NO_RECORD)
|
||||
DBUG_RETURN(1); /* Not found in links */
|
||||
}
|
||||
hash->current_record= NO_RECORD;
|
||||
org_link= *pos;
|
||||
empty=idx;
|
||||
|
||||
/* Relink record from current chain */
|
||||
|
||||
if (!previous)
|
||||
{
|
||||
if (pos->next != NO_RECORD)
|
||||
{
|
||||
empty=pos->next;
|
||||
*pos= data[pos->next];
|
||||
}
|
||||
}
|
||||
else
|
||||
previous->next=pos->next; /* unlink pos */
|
||||
|
||||
/* Move data to correct position */
|
||||
pos=data+new_index;
|
||||
new_pos_index=hash_rec_mask(hash,pos,blength,records);
|
||||
if (new_index != new_pos_index)
|
||||
{ /* Other record in wrong position */
|
||||
data[empty] = *pos;
|
||||
movelink(data,new_index,new_pos_index,empty);
|
||||
org_link.next=NO_RECORD;
|
||||
data[new_index]= org_link;
|
||||
}
|
||||
else
|
||||
{ /* Link in chain at right position */
|
||||
org_link.next=data[new_index].next;
|
||||
data[empty]=org_link;
|
||||
data[new_index].next=empty;
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
byte *hash_element(HASH *hash,uint idx)
|
||||
{
|
||||
if (idx < hash->records)
|
||||
return dynamic_element(&hash->array,idx,HASH_LINK*)->data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
|
||||
my_bool hash_check(HASH *hash)
|
||||
{
|
||||
int error;
|
||||
uint i,rec_link,found,max_links,seek,links,idx;
|
||||
uint records,blength;
|
||||
HASH_LINK *data,*hash_info;
|
||||
|
||||
records=hash->records; blength=hash->blength;
|
||||
data=dynamic_element(&hash->array,0,HASH_LINK*);
|
||||
error=0;
|
||||
|
||||
for (i=found=max_links=seek=0 ; i < records ; i++)
|
||||
{
|
||||
if (hash_rec_mask(hash,data+i,blength,records) == i)
|
||||
{
|
||||
found++; seek++; links=1;
|
||||
for (idx=data[i].next ;
|
||||
idx != NO_RECORD && found < records + 1;
|
||||
idx=hash_info->next)
|
||||
{
|
||||
if (idx >= records)
|
||||
{
|
||||
DBUG_PRINT("error",
|
||||
("Found pointer outside array to %d from link starting at %d",
|
||||
idx,i));
|
||||
error=1;
|
||||
}
|
||||
hash_info=data+idx;
|
||||
seek+= ++links;
|
||||
if ((rec_link=hash_rec_mask(hash,hash_info,blength,records)) != i)
|
||||
{
|
||||
DBUG_PRINT("error",
|
||||
("Record in wrong link at %d: Start %d Record: %lx Record-link %d", idx,i,hash_info->data,rec_link));
|
||||
error=1;
|
||||
}
|
||||
else
|
||||
found++;
|
||||
}
|
||||
if (links > max_links) max_links=links;
|
||||
}
|
||||
}
|
||||
if (found != records)
|
||||
{
|
||||
DBUG_PRINT("error",("Found %ld of %ld records"));
|
||||
error=1;
|
||||
}
|
||||
if (records)
|
||||
DBUG_PRINT("info",
|
||||
("records: %ld seeks: %d max links: %d hitrate: %.2f",
|
||||
records,seek,max_links,(float) seek / (float) records));
|
||||
return error;
|
||||
}
|
||||
#endif
|
@ -104,25 +104,23 @@ char *int2str(register long int val, register char *dst, register int radix)
|
||||
radix 10 / -10
|
||||
*/
|
||||
|
||||
char *int10_to_str(long int val,char *dst,int radix)
|
||||
char *int10_to_str(long int val, char *dst, int radix)
|
||||
{
|
||||
char buffer[65];
|
||||
register char *p;
|
||||
long int new_val;
|
||||
unsigned long int uval= (unsigned long int)val;
|
||||
|
||||
if (radix < 0) /* -10 */
|
||||
if (radix < 0 && val < 0) /* -10 */
|
||||
{
|
||||
if (val < 0)
|
||||
{
|
||||
*dst++ = '-';
|
||||
val = -val;
|
||||
}
|
||||
*dst++ = '-';
|
||||
uval = (unsigned long int)0-uval;
|
||||
}
|
||||
|
||||
p = &buffer[sizeof(buffer)-1];
|
||||
*p = '\0';
|
||||
new_val= (long) ((unsigned long int) val / 10);
|
||||
*--p = '0'+ (char) ((unsigned long int) val - (unsigned long) new_val * 10);
|
||||
new_val= (long)(uval / 10);
|
||||
*--p = '0'+ (char)(uval - (unsigned long)new_val * 10);
|
||||
val = new_val;
|
||||
|
||||
while (val != 0)
|
||||
|
1130
libmysql/libmysql.c
1130
libmysql/libmysql.c
File diff suppressed because it is too large
Load Diff
107
libmysql/libmysql_exports.def
Normal file
107
libmysql/libmysql_exports.def
Normal file
@ -0,0 +1,107 @@
|
||||
EXPORTS
|
||||
get_tty_password
|
||||
load_defaults
|
||||
mysql_thread_end
|
||||
mysql_thread_init
|
||||
myodbc_remove_escape
|
||||
mysql_affected_rows
|
||||
mysql_autocommit
|
||||
mysql_stmt_bind_param
|
||||
mysql_stmt_bind_result
|
||||
mysql_change_user
|
||||
mysql_character_set_name
|
||||
mysql_close
|
||||
mysql_commit
|
||||
mysql_data_seek
|
||||
mysql_debug
|
||||
mysql_dump_debug_info
|
||||
mysql_eof
|
||||
mysql_errno
|
||||
mysql_error
|
||||
mysql_escape_string
|
||||
mysql_hex_string
|
||||
mysql_stmt_execute
|
||||
mysql_stmt_fetch
|
||||
mysql_stmt_fetch_column
|
||||
mysql_fetch_field
|
||||
mysql_fetch_field_direct
|
||||
mysql_fetch_fields
|
||||
mysql_fetch_lengths
|
||||
mysql_fetch_row
|
||||
mysql_field_count
|
||||
mysql_field_seek
|
||||
mysql_field_tell
|
||||
mysql_free_result
|
||||
mysql_get_client_info
|
||||
mysql_get_host_info
|
||||
mysql_get_proto_info
|
||||
mysql_get_server_info
|
||||
mysql_get_client_version
|
||||
;mysql_get_ssl_cipher
|
||||
mysql_info
|
||||
mysql_init
|
||||
mysql_insert_id
|
||||
mysql_kill
|
||||
mysql_set_server_option
|
||||
mysql_list_dbs
|
||||
mysql_list_fields
|
||||
mysql_list_processes
|
||||
mysql_list_tables
|
||||
mysql_more_results
|
||||
mysql_next_result
|
||||
mysql_num_fields
|
||||
mysql_num_rows
|
||||
mysql_options
|
||||
mysql_stmt_param_count
|
||||
;mysql_stmt_param_metadata
|
||||
mysql_ping
|
||||
mysql_stmt_result_metadata
|
||||
mysql_query
|
||||
mysql_read_query_result
|
||||
mysql_real_connect
|
||||
mysql_real_escape_string
|
||||
mysql_real_query
|
||||
mysql_refresh
|
||||
mysql_rollback
|
||||
mysql_row_seek
|
||||
mysql_row_tell
|
||||
mysql_select_db
|
||||
mysql_stmt_send_long_data
|
||||
mysql_send_query
|
||||
mysql_shutdown
|
||||
mysql_ssl_set
|
||||
mysql_stat
|
||||
mysql_stmt_affected_rows
|
||||
mysql_stmt_close
|
||||
mysql_stmt_reset
|
||||
mysql_stmt_data_seek
|
||||
mysql_stmt_errno
|
||||
mysql_stmt_error
|
||||
mysql_stmt_free_result
|
||||
mysql_stmt_num_rows
|
||||
mysql_stmt_row_seek
|
||||
mysql_stmt_row_tell
|
||||
mysql_stmt_store_result
|
||||
mysql_store_result
|
||||
mysql_thread_id
|
||||
mysql_thread_safe
|
||||
mysql_use_result
|
||||
mysql_warning_count
|
||||
mysql_stmt_sqlstate
|
||||
mysql_sqlstate
|
||||
mysql_get_server_version
|
||||
mysql_stmt_prepare
|
||||
mysql_stmt_init
|
||||
mysql_stmt_insert_id
|
||||
mysql_stmt_attr_get
|
||||
mysql_stmt_attr_set
|
||||
mysql_stmt_field_count
|
||||
mysql_set_local_infile_default
|
||||
mysql_set_local_infile_handler
|
||||
mysql_server_init
|
||||
mysql_server_end
|
||||
mysql_set_character_set
|
||||
mysql_get_character_set_info
|
||||
;mysql_stmt_next_result
|
||||
|
||||
|
@ -1,123 +0,0 @@
|
||||
/* 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 */
|
||||
|
||||
/* Open a temporary file and cache it with io_cache. Delete it on close */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include <m_string.h>
|
||||
#include "my_static.h"
|
||||
#include "mysys_err.h"
|
||||
|
||||
/*
|
||||
Remove an open tempfile so that it doesn't survive
|
||||
if we crash; If the operating system doesn't support
|
||||
this, just remember the file name for later removal
|
||||
*/
|
||||
|
||||
static my_bool cache_remove_open_tmp(IO_CACHE *cache __attribute__((unused)),
|
||||
const char *name)
|
||||
{
|
||||
#if O_TEMPORARY == 0
|
||||
#if !defined(CANT_DELETE_OPEN_FILES)
|
||||
/* The following should always succeed */
|
||||
(void) my_delete(name,MYF(MY_WME | ME_NOINPUT));
|
||||
#else
|
||||
int length;
|
||||
if (!(cache->file_name=
|
||||
(char*) my_malloc((length=strlen(name)+1),MYF(MY_WME))))
|
||||
{
|
||||
my_close(cache->file,MYF(0));
|
||||
cache->file = -1;
|
||||
errno=my_errno=ENOMEM;
|
||||
return 1;
|
||||
}
|
||||
memcpy(cache->file_name,name,length);
|
||||
#endif
|
||||
#endif /* O_TEMPORARY == 0 */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Open tempfile cached by IO_CACHE
|
||||
** Should be used when no seeks are done (only reinit_io_buff)
|
||||
** Return 0 if cache is inited ok
|
||||
** The actual file is created when the IO_CACHE buffer gets filled
|
||||
** If dir is not given, use TMPDIR.
|
||||
*/
|
||||
|
||||
my_bool open_cached_file(IO_CACHE *cache, const char* dir, const char *prefix,
|
||||
uint cache_size, myf cache_myflags)
|
||||
{
|
||||
DBUG_ENTER("open_cached_file");
|
||||
cache->dir= dir ? my_strdup(dir,MYF(cache_myflags & MY_WME)) : (char*) 0;
|
||||
cache->prefix= (prefix ? my_strdup(prefix,MYF(cache_myflags & MY_WME)) :
|
||||
(char*) 0);
|
||||
cache->file_name=0;
|
||||
cache->buffer=0; /* Mark that not open */
|
||||
if (!init_io_cache(cache,-1,cache_size,WRITE_CACHE,0L,0,
|
||||
MYF(cache_myflags | MY_NABP)))
|
||||
{
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
my_free(cache->dir, MYF(MY_ALLOW_ZERO_PTR));
|
||||
my_free(cache->prefix,MYF(MY_ALLOW_ZERO_PTR));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
/* Create the temporary file */
|
||||
|
||||
my_bool real_open_cached_file(IO_CACHE *cache)
|
||||
{
|
||||
char name_buff[FN_REFLEN];
|
||||
int error=1;
|
||||
DBUG_ENTER("real_open_cached_file");
|
||||
if ((cache->file=create_temp_file(name_buff, cache->dir, cache->prefix,
|
||||
(O_RDWR | O_BINARY | O_TRUNC |
|
||||
O_TEMPORARY | O_SHORT_LIVED),
|
||||
MYF(MY_WME))) >= 0)
|
||||
{
|
||||
error=0;
|
||||
cache_remove_open_tmp(cache, name_buff);
|
||||
}
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
||||
void close_cached_file(IO_CACHE *cache)
|
||||
{
|
||||
DBUG_ENTER("close_cached_file");
|
||||
if (my_b_inited(cache))
|
||||
{
|
||||
File file=cache->file;
|
||||
cache->file= -1; /* Don't flush data */
|
||||
(void) end_io_cache(cache);
|
||||
if (file >= 0)
|
||||
{
|
||||
(void) my_close(file,MYF(0));
|
||||
#ifdef CANT_DELETE_OPEN_FILES
|
||||
if (cache->file_name)
|
||||
{
|
||||
(void) my_delete(cache->file_name,MYF(MY_WME | ME_NOINPUT));
|
||||
my_free(cache->file_name,MYF(0));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
my_free(cache->dir,MYF(MY_ALLOW_ZERO_PTR));
|
||||
my_free(cache->prefix,MYF(MY_ALLOW_ZERO_PTR));
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
@ -1,267 +0,0 @@
|
||||
/* 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 */
|
||||
|
||||
/*
|
||||
Functions to convert to lover_case and to upper_case in scandinavia.
|
||||
|
||||
case_sort converts a character string to a representaion that can
|
||||
be compared by strcmp to find with is alfabetical bigger.
|
||||
(lower- and uppercase letters is compared as the same)
|
||||
*/
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include <m_ctype.h>
|
||||
#include <m_string.h>
|
||||
|
||||
/* string to uppercase */
|
||||
|
||||
void caseup_str(my_string str)
|
||||
{
|
||||
#ifdef USE_MB
|
||||
if (use_mb(default_charset_info))
|
||||
{
|
||||
register uint32 l;
|
||||
register char *end=str+(uint) strlen(str);
|
||||
while (*str)
|
||||
{
|
||||
if ((l=my_ismbchar(default_charset_info, str,end))) str+=l;
|
||||
else *str=toupper(*str),++str;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
while ((*str = toupper(*str)) != 0)
|
||||
str++;
|
||||
} /* caseup_str */
|
||||
|
||||
/* string to lowercase */
|
||||
|
||||
void casedn_str(my_string str)
|
||||
{
|
||||
#ifdef USE_MB
|
||||
if (use_mb(default_charset_info))
|
||||
{
|
||||
register uint32 l;
|
||||
register char *end=str+(uint) strlen(str);
|
||||
while (*str)
|
||||
{
|
||||
if ((l=my_ismbchar(default_charset_info, str,end))) str+=l;
|
||||
else *str=tolower(*str),++str;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
while ((*str= tolower(*str)) != 0)
|
||||
str++;
|
||||
} /* casedn_str */
|
||||
|
||||
|
||||
/* to uppercase */
|
||||
|
||||
void caseup(my_string str, uint length)
|
||||
{
|
||||
#ifdef USE_MB
|
||||
if (use_mb(default_charset_info))
|
||||
{
|
||||
register uint32 l;
|
||||
register char *end=str+length;
|
||||
while (str<end)
|
||||
{
|
||||
if ((l=my_ismbchar(default_charset_info, str,end))) str+=l;
|
||||
else *str=toupper(*str),++str;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
for ( ; length>0 ; length--, str++)
|
||||
*str= toupper(*str);
|
||||
} /* caseup */
|
||||
|
||||
/* to lowercase */
|
||||
|
||||
void casedn(my_string str, uint length)
|
||||
{
|
||||
#ifdef USE_MB
|
||||
if (use_mb(default_charset_info))
|
||||
{
|
||||
register uint32 l;
|
||||
register char *end=str+length;
|
||||
while (str<end)
|
||||
{
|
||||
if ((l=my_ismbchar(default_charset_info, str,end))) str+=l;
|
||||
else *str=tolower(*str),++str;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
for ( ; length>0 ; length--, str++)
|
||||
*str= tolower(*str);
|
||||
} /* casedn */
|
||||
|
||||
/* to sort-string that can be compared to get text in order */
|
||||
|
||||
void case_sort(my_string str, uint length)
|
||||
{
|
||||
/* todo: can we remove this?
|
||||
for ( ; length>0 ; length--, str++)
|
||||
*str= (char) my_sort_order[(uchar) *str];
|
||||
*/
|
||||
} /* case_sort */
|
||||
|
||||
/* find string in another with no case_sensivity */
|
||||
|
||||
/* ToDo: This function should be modified to support multibyte charset.
|
||||
However it is not used untill 3.23.5.
|
||||
Wei He (hewei@mail.ied.ac.cn)
|
||||
*/
|
||||
|
||||
my_string my_strcasestr(const char *str, const char *search)
|
||||
{
|
||||
uchar *i,*j,*pos;
|
||||
|
||||
pos=(uchar*) str;
|
||||
skipp:
|
||||
while (*pos != '\0')
|
||||
{
|
||||
if (toupper((uchar) *pos++) == toupper((uchar) *search))
|
||||
{
|
||||
i=(uchar*) pos; j=(uchar*) search+1;
|
||||
while (*j)
|
||||
if (toupper(*i++) != toupper(*j++)) goto skipp;
|
||||
return ((char*) pos-1);
|
||||
}
|
||||
}
|
||||
return ((my_string) 0);
|
||||
} /* strcstr */
|
||||
|
||||
|
||||
/* compare strings without regarding to case */
|
||||
|
||||
int my_strcasecmp(const char *s, const char *t)
|
||||
{
|
||||
#ifdef USE_MB
|
||||
if (use_mb(default_charset_info))
|
||||
{
|
||||
register uint32 l;
|
||||
register const char *end=s+(uint) strlen(s);
|
||||
while (s<end)
|
||||
{
|
||||
if ((l=my_ismbchar(default_charset_info, s,end)))
|
||||
{
|
||||
while (l--)
|
||||
if (*s++ != *t++) return 1;
|
||||
}
|
||||
else if (my_ismbhead(default_charset_info, *t)) return 1;
|
||||
else if (toupper((uchar) *s++) != toupper((uchar) *t++)) return 1;
|
||||
}
|
||||
return *t;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
while (toupper((uchar) *s) == toupper((uchar) *t++))
|
||||
if (!*s++) return 0;
|
||||
return ((int) toupper((uchar) s[0]) - (int) toupper((uchar) t[-1]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int my_casecmp(const char *s, const char *t, uint len)
|
||||
{
|
||||
#ifdef USE_MB
|
||||
if (use_mb(default_charset_info))
|
||||
{
|
||||
register uint32 l;
|
||||
register const char *end=s+len;
|
||||
while (s<end)
|
||||
{
|
||||
if ((l=my_ismbchar(default_charset_info, s,end)))
|
||||
{
|
||||
while (l--)
|
||||
if (*s++ != *t++) return 1;
|
||||
}
|
||||
else if (my_ismbhead(default_charset_info, *t)) return 1;
|
||||
else if (toupper((uchar) *s++) != toupper((uchar) *t++)) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
while (len-- != 0 && toupper(*s++) == toupper(*t++)) ;
|
||||
return (int) len+1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int my_strsortcmp(const char *s, const char *t)
|
||||
{
|
||||
/* todo can we remove this?
|
||||
#ifdef USE_STRCOLL
|
||||
if (use_strcoll(default_charset_info))
|
||||
return my_strcoll(default_charset_info, (uchar *)s, (uchar *)t);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
while (my_sort_order[(uchar) *s] == my_sort_order[(uchar) *t++])
|
||||
if (!*s++) return 0;
|
||||
return ((int) my_sort_order[(uchar) s[0]] -
|
||||
(int) my_sort_order[(uchar) t[-1]]);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
int my_sortcmp(const char *s, const char *t, uint len)
|
||||
{
|
||||
#ifdef USE_STRCOLL
|
||||
if (use_strcoll(default_charset_info))
|
||||
return my_strnncoll(default_charset_info,
|
||||
(uchar *)s, len, (uchar *)t, len);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
while (len--)
|
||||
{
|
||||
if (my_sort_order[(uchar) *s++] != my_sort_order[(uchar) *t++])
|
||||
return ((int) my_sort_order[(uchar) s[-1]] -
|
||||
(int) my_sort_order[(uchar) t[-1]]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int my_sortncmp(const char *s, uint s_len, const char *t, uint t_len)
|
||||
{
|
||||
#ifdef USE_STRCOLL
|
||||
if (use_strcoll(default_charset_info))
|
||||
return my_strnncoll(default_charset_info,
|
||||
(uchar *)s, s_len, (uchar *)t, t_len);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
uint len= min(s_len,t_len);
|
||||
while (len--)
|
||||
{
|
||||
if (my_sort_order[(uchar) *s++] != my_sort_order[(uchar) *t++])
|
||||
return ((int) my_sort_order[(uchar) s[-1]] -
|
||||
(int) my_sort_order[(uchar) t[-1]]);
|
||||
}
|
||||
return (int) (s_len - t_len);
|
||||
}
|
||||
}
|
||||
*/
|
@ -1,614 +0,0 @@
|
||||
/* 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 */
|
||||
|
||||
/*
|
||||
Cashing of files with only does (sequential) read or writes of fixed-
|
||||
length records. A read isn't allowed to go over file-length. A read is ok
|
||||
if it ends at file-length and next read can try to read after file-length
|
||||
(and get a EOF-error).
|
||||
Possibly use of asyncronic io.
|
||||
macros for read and writes for faster io.
|
||||
Used instead of FILE when reading or writing whole files.
|
||||
This will make mf_rec_cache obsolete.
|
||||
One can change info->pos_in_file to a higher value to skip bytes in file if
|
||||
also info->rc_pos is set to info->rc_end.
|
||||
If called through open_cached_file(), then the temporary file will
|
||||
only be created if a write exeeds the file buffer or if one calls
|
||||
flush_io_cache().
|
||||
*/
|
||||
|
||||
#define MAP_TO_USE_RAID
|
||||
#include "mysys_priv.h"
|
||||
#include <m_string.h>
|
||||
#ifdef HAVE_AIOWAIT
|
||||
#include "mysys_err.h"
|
||||
#include <errno.h>
|
||||
static void my_aiowait(my_aio_result *result);
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** if cachesize == 0 then use default cachesize (from s-file)
|
||||
** if file == -1 then real_open_cached_file() will be called.
|
||||
** returns 0 if ok
|
||||
*/
|
||||
|
||||
int init_io_cache(IO_CACHE *info, File file, uint cachesize,
|
||||
enum cache_type type, my_off_t seek_offset,
|
||||
pbool use_async_io, myf cache_myflags)
|
||||
{
|
||||
uint min_cache;
|
||||
DBUG_ENTER("init_io_cache");
|
||||
DBUG_PRINT("enter",("type: %d pos: %ld",(int) type, (ulong) seek_offset));
|
||||
|
||||
info->file=file;
|
||||
if (!cachesize)
|
||||
if (! (cachesize= my_default_record_cache_size))
|
||||
DBUG_RETURN(1); /* No cache requested */
|
||||
min_cache=use_async_io ? IO_SIZE*4 : IO_SIZE*2;
|
||||
if (type == READ_CACHE)
|
||||
{ /* Assume file isn't growing */
|
||||
if (cache_myflags & MY_DONT_CHECK_FILESIZE)
|
||||
{
|
||||
cache_myflags &= ~MY_DONT_CHECK_FILESIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
my_off_t file_pos,end_of_file;
|
||||
if ((file_pos=my_tell(file,MYF(0)) == MY_FILEPOS_ERROR))
|
||||
DBUG_RETURN(1);
|
||||
end_of_file=my_seek(file,0L,MY_SEEK_END,MYF(0));
|
||||
if (end_of_file < seek_offset)
|
||||
end_of_file=seek_offset;
|
||||
VOID(my_seek(file,file_pos,MY_SEEK_SET,MYF(0)));
|
||||
if ((my_off_t) cachesize > end_of_file-seek_offset+IO_SIZE*2-1)
|
||||
{
|
||||
cachesize=(uint) (end_of_file-seek_offset)+IO_SIZE*2-1;
|
||||
use_async_io=0; /* No nead to use async */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
cachesize=(uint) ((ulong) (cachesize + min_cache-1) &
|
||||
(ulong) ~(min_cache-1));
|
||||
if (cachesize < min_cache)
|
||||
cachesize = min_cache;
|
||||
if ((info->buffer=
|
||||
(byte*) my_malloc(cachesize,
|
||||
MYF((cache_myflags & ~ MY_WME) |
|
||||
(cachesize == min_cache ? MY_WME : 0)))) != 0)
|
||||
break; /* Enough memory found */
|
||||
if (cachesize == min_cache)
|
||||
DBUG_RETURN(2); /* Can't alloc cache */
|
||||
cachesize= (uint) ((long) cachesize*3/4); /* Try with less memory */
|
||||
}
|
||||
info->pos_in_file=seek_offset;
|
||||
info->read_length=info->buffer_length=cachesize;
|
||||
info->seek_not_done= test(file >= 0); /* Seek not done */
|
||||
info->myflags=cache_myflags & ~(MY_NABP | MY_FNABP);
|
||||
info->rc_request_pos=info->rc_pos=info->buffer;
|
||||
|
||||
if (type == READ_CACHE)
|
||||
{
|
||||
info->rc_end=info->buffer; /* Nothing in cache */
|
||||
}
|
||||
else /* type == WRITE_CACHE */
|
||||
{
|
||||
info->rc_end=info->buffer+info->buffer_length- (seek_offset & (IO_SIZE-1));
|
||||
}
|
||||
info->end_of_file=MY_FILEPOS_ERROR; /* May be changed by user */
|
||||
info->type=type;
|
||||
info->error=0;
|
||||
info->read_function=_my_b_read;
|
||||
#ifdef HAVE_AIOWAIT
|
||||
if (use_async_io && ! my_disable_async_io)
|
||||
{
|
||||
DBUG_PRINT("info",("Using async io"));
|
||||
info->read_length/=2;
|
||||
info->read_function=_my_b_async_read;
|
||||
}
|
||||
info->inited=info->aio_result.pending=0;
|
||||
#endif
|
||||
DBUG_RETURN(0);
|
||||
} /* init_io_cache */
|
||||
|
||||
|
||||
/* Wait until current request is ready */
|
||||
|
||||
#ifdef HAVE_AIOWAIT
|
||||
static void my_aiowait(my_aio_result *result)
|
||||
{
|
||||
if (result->pending)
|
||||
{
|
||||
struct aio_result_t *tmp;
|
||||
for (;;)
|
||||
{
|
||||
if ((int) (tmp=aiowait((struct timeval *) 0)) == -1)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
DBUG_PRINT("error",("No aio request, error: %d",errno));
|
||||
result->pending=0; /* Assume everythings is ok */
|
||||
break;
|
||||
}
|
||||
((my_aio_result*) tmp)->pending=0;
|
||||
if ((my_aio_result*) tmp == result)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Use this to reset cache to start or other type */
|
||||
/* Some simple optimizing is done when reinit in current buffer */
|
||||
|
||||
my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
|
||||
my_off_t seek_offset,
|
||||
pbool use_async_io __attribute__((unused)),
|
||||
pbool clear_cache)
|
||||
{
|
||||
DBUG_ENTER("reinit_io_cache");
|
||||
|
||||
info->seek_not_done= test(info->file >= 0); /* Seek not done */
|
||||
if (! clear_cache &&
|
||||
seek_offset >= info->pos_in_file &&
|
||||
seek_offset <= info->pos_in_file +
|
||||
(uint) (info->rc_end - info->rc_request_pos))
|
||||
{ /* use current buffer */
|
||||
if (info->type == WRITE_CACHE && type == READ_CACHE)
|
||||
{
|
||||
info->rc_end=info->rc_pos;
|
||||
info->end_of_file=my_b_tell(info);
|
||||
}
|
||||
else if (info->type == READ_CACHE && type == WRITE_CACHE)
|
||||
info->rc_end=info->buffer+info->buffer_length;
|
||||
info->rc_pos=info->rc_request_pos+(seek_offset-info->pos_in_file);
|
||||
#ifdef HAVE_AIOWAIT
|
||||
my_aiowait(&info->aio_result); /* Wait for outstanding req */
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
if (info->type == WRITE_CACHE && type == READ_CACHE)
|
||||
info->end_of_file=my_b_tell(info);
|
||||
if (flush_io_cache(info))
|
||||
DBUG_RETURN(1);
|
||||
info->pos_in_file=seek_offset;
|
||||
info->rc_request_pos=info->rc_pos=info->buffer;
|
||||
if (type == READ_CACHE)
|
||||
{
|
||||
info->rc_end=info->buffer; /* Nothing in cache */
|
||||
}
|
||||
else
|
||||
{
|
||||
info->rc_end=info->buffer+info->buffer_length-
|
||||
(seek_offset & (IO_SIZE-1));
|
||||
info->end_of_file=MY_FILEPOS_ERROR; /* May be changed by user */
|
||||
}
|
||||
}
|
||||
info->type=type;
|
||||
info->error=0;
|
||||
info->read_function=_my_b_read;
|
||||
#ifdef HAVE_AIOWAIT
|
||||
if (use_async_io && ! my_disable_async_io &&
|
||||
((ulong) info->buffer_length <
|
||||
(ulong) (info->end_of_file - seek_offset)))
|
||||
{
|
||||
info->read_length=info->buffer_length/2;
|
||||
info->read_function=_my_b_async_read;
|
||||
}
|
||||
info->inited=0;
|
||||
#endif
|
||||
DBUG_RETURN(0);
|
||||
} /* init_io_cache */
|
||||
|
||||
|
||||
|
||||
/* Read buffered. Returns 1 if can't read requested characters */
|
||||
/* Returns 0 if record read */
|
||||
|
||||
int _my_b_read(register IO_CACHE *info, byte *Buffer, uint Count)
|
||||
{
|
||||
uint length,diff_length,left_length;
|
||||
my_off_t max_length, pos_in_file;
|
||||
|
||||
memcpy(Buffer,info->rc_pos,
|
||||
(size_t) (left_length=(uint) (info->rc_end-info->rc_pos)));
|
||||
Buffer+=left_length;
|
||||
Count-=left_length;
|
||||
pos_in_file=info->pos_in_file+(uint) (info->rc_end - info->buffer);
|
||||
if (info->seek_not_done)
|
||||
{ /* File touched, do seek */
|
||||
VOID(my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)));
|
||||
info->seek_not_done=0;
|
||||
}
|
||||
diff_length=(uint) (pos_in_file & (IO_SIZE-1));
|
||||
if (Count >= (uint) (IO_SIZE+(IO_SIZE-diff_length)))
|
||||
{ /* Fill first intern buffer */
|
||||
uint read_length;
|
||||
if (info->end_of_file == pos_in_file)
|
||||
{ /* End of file */
|
||||
info->error=(int) left_length;
|
||||
return 1;
|
||||
}
|
||||
length=(Count & (uint) ~(IO_SIZE-1))-diff_length;
|
||||
if ((read_length=my_read(info->file,Buffer,(uint) length,info->myflags))
|
||||
!= (uint) length)
|
||||
{
|
||||
info->error= read_length == (uint) -1 ? -1 :
|
||||
(int) (read_length+left_length);
|
||||
return 1;
|
||||
}
|
||||
Count-=length;
|
||||
Buffer+=length;
|
||||
pos_in_file+=length;
|
||||
left_length+=length;
|
||||
diff_length=0;
|
||||
}
|
||||
max_length=info->end_of_file - pos_in_file;
|
||||
if (max_length > info->read_length-diff_length)
|
||||
max_length=info->read_length-diff_length;
|
||||
|
||||
if (!max_length)
|
||||
{
|
||||
if (Count)
|
||||
{
|
||||
info->error= left_length; /* We only got this many char */
|
||||
return 1;
|
||||
}
|
||||
length=0; /* Didn't read any chars */
|
||||
}
|
||||
else if ((length=my_read(info->file,info->buffer,(uint) max_length,
|
||||
info->myflags)) < Count ||
|
||||
length == (uint) -1)
|
||||
{
|
||||
if (length != (uint) -1)
|
||||
memcpy(Buffer,info->buffer,(size_t) length);
|
||||
info->error= length == (uint) -1 ? -1 : (int) (length+left_length);
|
||||
return 1;
|
||||
}
|
||||
info->rc_pos=info->buffer+Count;
|
||||
info->rc_end=info->buffer+length;
|
||||
info->pos_in_file=pos_in_file;
|
||||
memcpy(Buffer,info->buffer,(size_t) Count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_AIOWAIT
|
||||
|
||||
int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count)
|
||||
{
|
||||
uint length,read_length,diff_length,left_length,use_length,org_Count;
|
||||
my_off_t max_length;
|
||||
my_off_t next_pos_in_file;
|
||||
byte *read_buffer;
|
||||
|
||||
memcpy(Buffer,info->rc_pos,
|
||||
(size_t) (left_length=(uint) (info->rc_end-info->rc_pos)));
|
||||
Buffer+=left_length;
|
||||
org_Count=Count;
|
||||
Count-=left_length;
|
||||
|
||||
if (info->inited)
|
||||
{ /* wait for read block */
|
||||
info->inited=0; /* No more block to read */
|
||||
my_aiowait(&info->aio_result); /* Wait for outstanding req */
|
||||
if (info->aio_result.result.aio_errno)
|
||||
{
|
||||
if (info->myflags & MY_WME)
|
||||
my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG),
|
||||
my_filename(info->file),
|
||||
info->aio_result.result.aio_errno);
|
||||
my_errno=info->aio_result.result.aio_errno;
|
||||
info->error= -1;
|
||||
return(1);
|
||||
}
|
||||
if (! (read_length = (uint) info->aio_result.result.aio_return) ||
|
||||
read_length == (uint) -1)
|
||||
{
|
||||
my_errno=0; /* For testing */
|
||||
info->error= (read_length == (uint) -1 ? -1 :
|
||||
(int) (read_length+left_length));
|
||||
return(1);
|
||||
}
|
||||
info->pos_in_file+=(uint) (info->rc_end - info->rc_request_pos);
|
||||
|
||||
if (info->rc_request_pos != info->buffer)
|
||||
info->rc_request_pos=info->buffer;
|
||||
else
|
||||
info->rc_request_pos=info->buffer+info->read_length;
|
||||
info->rc_pos=info->rc_request_pos;
|
||||
next_pos_in_file=info->aio_read_pos+read_length;
|
||||
|
||||
/* Check if pos_in_file is changed
|
||||
(_ni_read_cache may have skipped some bytes) */
|
||||
|
||||
if (info->aio_read_pos < info->pos_in_file)
|
||||
{ /* Fix if skipped bytes */
|
||||
if (info->aio_read_pos + read_length < info->pos_in_file)
|
||||
{
|
||||
read_length=0; /* Skipp block */
|
||||
next_pos_in_file=info->pos_in_file;
|
||||
}
|
||||
else
|
||||
{
|
||||
my_off_t offset= (info->pos_in_file - info->aio_read_pos);
|
||||
info->pos_in_file=info->aio_read_pos; /* Whe are here */
|
||||
info->rc_pos=info->rc_request_pos+offset;
|
||||
read_length-=offset; /* Bytes left from rc_pos */
|
||||
}
|
||||
}
|
||||
#ifndef DBUG_OFF
|
||||
if (info->aio_read_pos > info->pos_in_file)
|
||||
{
|
||||
my_errno=EINVAL;
|
||||
return(info->read_length= -1);
|
||||
}
|
||||
#endif
|
||||
/* Copy found bytes to buffer */
|
||||
length=min(Count,read_length);
|
||||
memcpy(Buffer,info->rc_pos,(size_t) length);
|
||||
Buffer+=length;
|
||||
Count-=length;
|
||||
left_length+=length;
|
||||
info->rc_end=info->rc_pos+read_length;
|
||||
info->rc_pos+=length;
|
||||
}
|
||||
else
|
||||
next_pos_in_file=(info->pos_in_file+ (uint)
|
||||
(info->rc_end - info->rc_request_pos));
|
||||
|
||||
/* If reading large blocks, or first read or read with skipp */
|
||||
if (Count)
|
||||
{
|
||||
if (next_pos_in_file == info->end_of_file)
|
||||
{
|
||||
info->error=(int) (read_length+left_length);
|
||||
return 1;
|
||||
}
|
||||
VOID(my_seek(info->file,next_pos_in_file,MY_SEEK_SET,MYF(0)));
|
||||
read_length=IO_SIZE*2- (uint) (next_pos_in_file & (IO_SIZE-1));
|
||||
if (Count < read_length)
|
||||
{ /* Small block, read to cache */
|
||||
if ((read_length=my_read(info->file,info->rc_request_pos,
|
||||
read_length, info->myflags)) == (uint) -1)
|
||||
return info->error= -1;
|
||||
use_length=min(Count,read_length);
|
||||
memcpy(Buffer,info->rc_request_pos,(size_t) use_length);
|
||||
info->rc_pos=info->rc_request_pos+Count;
|
||||
info->rc_end=info->rc_request_pos+read_length;
|
||||
info->pos_in_file=next_pos_in_file; /* Start of block in cache */
|
||||
next_pos_in_file+=read_length;
|
||||
|
||||
if (Count != use_length)
|
||||
{ /* Didn't find hole block */
|
||||
if (info->myflags & (MY_WME | MY_FAE | MY_FNABP) && Count != org_Count)
|
||||
my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG),
|
||||
my_filename(info->file),my_errno);
|
||||
info->error=(int) (read_length+left_length);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /* Big block, don't cache it */
|
||||
if ((read_length=my_read(info->file,Buffer,(uint) Count,info->myflags))
|
||||
!= Count)
|
||||
{
|
||||
info->error= read_length == (uint) -1 ? -1 : read_length+left_length;
|
||||
return 1;
|
||||
}
|
||||
info->rc_pos=info->rc_end=info->rc_request_pos;
|
||||
info->pos_in_file=(next_pos_in_file+=Count);
|
||||
}
|
||||
}
|
||||
|
||||
/* Read next block with asyncronic io */
|
||||
max_length=info->end_of_file - next_pos_in_file;
|
||||
diff_length=(next_pos_in_file & (IO_SIZE-1));
|
||||
|
||||
if (max_length > (my_off_t) info->read_length - diff_length)
|
||||
max_length= (my_off_t) info->read_length - diff_length;
|
||||
if (info->rc_request_pos != info->buffer)
|
||||
read_buffer=info->buffer;
|
||||
else
|
||||
read_buffer=info->buffer+info->read_length;
|
||||
info->aio_read_pos=next_pos_in_file;
|
||||
if (max_length)
|
||||
{
|
||||
info->aio_result.result.aio_errno=AIO_INPROGRESS; /* Marker for test */
|
||||
DBUG_PRINT("aioread",("filepos: %ld length: %ld",
|
||||
(ulong) next_pos_in_file,(ulong) max_length));
|
||||
if (aioread(info->file,read_buffer,(int) max_length,
|
||||
(my_off_t) next_pos_in_file,MY_SEEK_SET,
|
||||
&info->aio_result.result))
|
||||
{ /* Skipp async io */
|
||||
my_errno=errno;
|
||||
DBUG_PRINT("error",("got error: %d, aio_result: %d from aioread, async skipped",
|
||||
errno, info->aio_result.result.aio_errno));
|
||||
if (info->rc_request_pos != info->buffer)
|
||||
{
|
||||
bmove(info->buffer,info->rc_request_pos,
|
||||
(uint) (info->rc_end - info->rc_pos));
|
||||
info->rc_request_pos=info->buffer;
|
||||
info->rc_pos-=info->read_length;
|
||||
info->rc_end-=info->read_length;
|
||||
}
|
||||
info->read_length=info->buffer_length; /* Use hole buffer */
|
||||
info->read_function=_my_b_read; /* Use normal IO_READ next */
|
||||
}
|
||||
else
|
||||
info->inited=info->aio_result.pending=1;
|
||||
}
|
||||
return 0; /* Block read, async in use */
|
||||
} /* _my_b_async_read */
|
||||
#endif
|
||||
|
||||
|
||||
/* Read one byte when buffer is empty */
|
||||
|
||||
int _my_b_get(IO_CACHE *info)
|
||||
{
|
||||
byte buff;
|
||||
if ((*(info)->read_function)(info,&buff,1))
|
||||
return my_b_EOF;
|
||||
return (int) (uchar) buff;
|
||||
}
|
||||
|
||||
/* Returns != 0 if error on write */
|
||||
|
||||
int _my_b_write(register IO_CACHE *info, const byte *Buffer, uint Count)
|
||||
{
|
||||
uint rest_length,length;
|
||||
|
||||
rest_length=(uint) (info->rc_end - info->rc_pos);
|
||||
memcpy(info->rc_pos,Buffer,(size_t) rest_length);
|
||||
Buffer+=rest_length;
|
||||
Count-=rest_length;
|
||||
info->rc_pos+=rest_length;
|
||||
if (flush_io_cache(info))
|
||||
return 1;
|
||||
if (Count >= IO_SIZE)
|
||||
{ /* Fill first intern buffer */
|
||||
length=Count & (uint) ~(IO_SIZE-1);
|
||||
if (info->seek_not_done)
|
||||
{ /* File touched, do seek */
|
||||
VOID(my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0)));
|
||||
info->seek_not_done=0;
|
||||
}
|
||||
if (my_write(info->file,Buffer,(uint) length,info->myflags | MY_NABP))
|
||||
return info->error= -1;
|
||||
Count-=length;
|
||||
Buffer+=length;
|
||||
info->pos_in_file+=length;
|
||||
}
|
||||
memcpy(info->rc_pos,Buffer,(size_t) Count);
|
||||
info->rc_pos+=Count;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Write a block to disk where part of the data may be inside the record
|
||||
buffer. As all write calls to the data goes through the cache,
|
||||
we will never get a seek over the end of the buffer
|
||||
*/
|
||||
|
||||
int my_block_write(register IO_CACHE *info, const byte *Buffer, uint Count,
|
||||
my_off_t pos)
|
||||
{
|
||||
uint length;
|
||||
int error=0;
|
||||
|
||||
if (pos < info->pos_in_file)
|
||||
{
|
||||
/* Of no overlap, write everything without buffering */
|
||||
if (pos + Count <= info->pos_in_file)
|
||||
return my_pwrite(info->file, Buffer, Count, pos,
|
||||
info->myflags | MY_NABP);
|
||||
/* Write the part of the block that is before buffer */
|
||||
length= (uint) (info->pos_in_file - pos);
|
||||
if (my_pwrite(info->file, Buffer, length, pos, info->myflags | MY_NABP))
|
||||
info->error=error=-1;
|
||||
Buffer+=length;
|
||||
pos+= length;
|
||||
Count-= length;
|
||||
}
|
||||
|
||||
/* Check if we want to write inside the used part of the buffer.*/
|
||||
length= (uint) (info->rc_end - info->buffer);
|
||||
if (pos < info->pos_in_file + length)
|
||||
{
|
||||
uint offset= (uint) (pos - info->pos_in_file);
|
||||
length-=offset;
|
||||
if (length > Count)
|
||||
length=Count;
|
||||
memcpy(info->buffer+offset, Buffer, length);
|
||||
Buffer+=length;
|
||||
Count-= length;
|
||||
/* Fix length of buffer if the new data was larger */
|
||||
if (info->buffer+length > info->rc_pos)
|
||||
info->rc_pos=info->buffer+length;
|
||||
if (!Count)
|
||||
return (error);
|
||||
}
|
||||
/* Write at the end of the current buffer; This is the normal case */
|
||||
if (_my_b_write(info, Buffer, Count))
|
||||
error= -1;
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Flush write cache */
|
||||
|
||||
int flush_io_cache(IO_CACHE *info)
|
||||
{
|
||||
uint length;
|
||||
DBUG_ENTER("flush_io_cache");
|
||||
|
||||
if (info->type == WRITE_CACHE)
|
||||
{
|
||||
if (info->file == -1)
|
||||
{
|
||||
if (real_open_cached_file(info))
|
||||
DBUG_RETURN((info->error= -1));
|
||||
}
|
||||
if (info->rc_pos != info->buffer)
|
||||
{
|
||||
length=(uint) (info->rc_pos - info->buffer);
|
||||
if (info->seek_not_done)
|
||||
{ /* File touched, do seek */
|
||||
if (my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0)) ==
|
||||
MY_FILEPOS_ERROR)
|
||||
DBUG_RETURN((info->error= -1));
|
||||
info->seek_not_done=0;
|
||||
}
|
||||
info->rc_pos=info->buffer;
|
||||
info->pos_in_file+=length;
|
||||
info->rc_end=(info->buffer+info->buffer_length-
|
||||
(info->pos_in_file & (IO_SIZE-1)));
|
||||
if (my_write(info->file,info->buffer,length,info->myflags | MY_NABP))
|
||||
DBUG_RETURN((info->error= -1));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_AIOWAIT
|
||||
else
|
||||
{
|
||||
my_aiowait(&info->aio_result); /* Wait for outstanding req */
|
||||
info->inited=0;
|
||||
}
|
||||
#endif
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
int end_io_cache(IO_CACHE *info)
|
||||
{
|
||||
int error=0;
|
||||
DBUG_ENTER("end_io_cache");
|
||||
if (info->buffer)
|
||||
{
|
||||
if (info->file != -1) /* File doesn't exist */
|
||||
error=flush_io_cache(info);
|
||||
my_free((gptr) info->buffer,MYF(MY_WME));
|
||||
info->buffer=info->rc_pos=(byte*) 0;
|
||||
}
|
||||
DBUG_RETURN(error);
|
||||
} /* end_io_cache */
|
@ -35,7 +35,7 @@ static my_string NEAR_F expand_tilde(my_string *path);
|
||||
void pack_dirname(my_string to, const char *from)
|
||||
{
|
||||
int cwd_err;
|
||||
uint d_length,length,buff_length;
|
||||
uint d_length,length,buff_length= 0;
|
||||
my_string start;
|
||||
char buff[FN_REFLEN];
|
||||
DBUG_ENTER("pack_dirname");
|
||||
|
@ -74,7 +74,7 @@ my_string my_path(my_string to, const char *progname,
|
||||
/* test if file without filename is found in path */
|
||||
/* Returns to if found and to has dirpart if found, else NullS */
|
||||
|
||||
#if defined(MSDOS) || defined(__WIN__) || defined(__EMX__) || defined(OS2)
|
||||
#if defined(MSDOS) || defined(_WIN32) || defined(__EMX__) || defined(OS2)
|
||||
#define F_OK 0
|
||||
#define PATH_SEP ';'
|
||||
#define PROGRAM_EXTENSION ".exe"
|
||||
@ -107,7 +107,7 @@ static char *find_file_in_path(char *to, const char *name)
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef __WIN__
|
||||
#ifdef _WIN32
|
||||
to[0]=FN_CURLIB;
|
||||
strxmov(to+1,dir,name,ext,NullS);
|
||||
if (!access(to,F_OK)) /* Test in current dir */
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <my_sys.h>
|
||||
#include <m_string.h>
|
||||
|
||||
void init_alloc_root(MEM_ROOT *mem_root, uint block_size, uint pre_alloc_size)
|
||||
void init_alloc_root(MEM_ROOT *mem_root, size_t block_size, size_t pre_alloc_size)
|
||||
{
|
||||
mem_root->free=mem_root->used=0;
|
||||
mem_root->min_malloc=32;
|
||||
@ -42,7 +42,7 @@ void init_alloc_root(MEM_ROOT *mem_root, uint block_size, uint pre_alloc_size)
|
||||
#endif
|
||||
}
|
||||
|
||||
gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size)
|
||||
gptr alloc_root(MEM_ROOT *mem_root, size_t Size)
|
||||
{
|
||||
#if defined(HAVE_purify) && defined(EXTRA_DEBUG)
|
||||
reg1 USED_MEM *next;
|
||||
@ -58,7 +58,7 @@ gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size)
|
||||
mem_root->used=next;
|
||||
return (gptr) (((char*) next)+ALIGN_SIZE(sizeof(USED_MEM)));
|
||||
#else
|
||||
uint get_size,max_left;
|
||||
size_t get_size,max_left;
|
||||
gptr point;
|
||||
reg1 USED_MEM *next;
|
||||
reg2 USED_MEM **prev;
|
||||
@ -137,7 +137,7 @@ void free_root(MEM_ROOT *root, myf MyFlags)
|
||||
|
||||
char *strdup_root(MEM_ROOT *root,const char *str)
|
||||
{
|
||||
uint len= (uint) strlen(str)+1;
|
||||
size_t len= strlen(str)+1;
|
||||
char *pos;
|
||||
if ((pos=alloc_root(root,len)))
|
||||
memcpy(pos,str,len);
|
||||
@ -145,7 +145,7 @@ char *strdup_root(MEM_ROOT *root,const char *str)
|
||||
}
|
||||
|
||||
|
||||
char *memdup_root(MEM_ROOT *root,const char *str,uint len)
|
||||
char *memdup_root(MEM_ROOT *root, const char *str, size_t len)
|
||||
{
|
||||
char *pos;
|
||||
if ((pos=alloc_root(root,len)))
|
||||
|
737
libmysql/my_auth.c
Normal file
737
libmysql/my_auth.c
Normal file
@ -0,0 +1,737 @@
|
||||
#include <my_global.h>
|
||||
#include <my_sys.h>
|
||||
#include <m_string.h>
|
||||
#include <errmsg.h>
|
||||
#include <mysql.h>
|
||||
#include <mysql/client_plugin.h>
|
||||
#include <violite.h>
|
||||
|
||||
typedef struct st_mysql_client_plugin_AUTHENTICATION auth_plugin_t;
|
||||
static int client_mpvio_write_packet(struct st_plugin_vio*, const uchar*, size_t);
|
||||
static int native_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql);
|
||||
static int old_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql);
|
||||
extern void read_user_name(char *name);
|
||||
|
||||
#define compile_time_assert(A) \
|
||||
do {\
|
||||
typedef char constraint[(A) ? 1 : -1];\
|
||||
} while (0);
|
||||
|
||||
static auth_plugin_t native_password_client_plugin=
|
||||
{
|
||||
MYSQL_CLIENT_AUTHENTICATION_PLUGIN,
|
||||
MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION,
|
||||
native_password_plugin_name,
|
||||
"R.J.Silk, Sergei Golubchik",
|
||||
"Native MySQL authentication",
|
||||
{1, 0, 0},
|
||||
NULL,
|
||||
NULL,
|
||||
native_password_auth_client
|
||||
};
|
||||
|
||||
static auth_plugin_t old_password_client_plugin=
|
||||
{
|
||||
MYSQL_CLIENT_AUTHENTICATION_PLUGIN,
|
||||
MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION,
|
||||
old_password_plugin_name,
|
||||
"R.J.Silk, Sergei Golubchik",
|
||||
"Old MySQL-3.23 authentication",
|
||||
{1, 0, 0},
|
||||
NULL,
|
||||
NULL,
|
||||
old_password_auth_client
|
||||
};
|
||||
|
||||
struct st_mysql_client_plugin *mysql_client_builtins[]=
|
||||
{
|
||||
(struct st_mysql_client_plugin *)&native_password_client_plugin,
|
||||
0
|
||||
};
|
||||
|
||||
/* this is a "superset" of MYSQL_PLUGIN_VIO, in C++ I use inheritance */
|
||||
typedef struct {
|
||||
int (*read_packet)(struct st_plugin_vio *vio, uchar **buf);
|
||||
int (*write_packet)(struct st_plugin_vio *vio, const uchar *pkt, size_t pkt_len);
|
||||
void (*info)(struct st_plugin_vio *vio, struct st_plugin_vio_info *info);
|
||||
/* -= end of MYSQL_PLUGIN_VIO =- */
|
||||
MYSQL *mysql;
|
||||
auth_plugin_t *plugin; /**< what plugin we're under */
|
||||
const char *db;
|
||||
struct {
|
||||
uchar *pkt; /**< pointer into NET::buff */
|
||||
uint pkt_len;
|
||||
} cached_server_reply;
|
||||
uint packets_read, packets_written; /**< counters for send/received packets */
|
||||
my_bool mysql_change_user; /**< if it's mysql_change_user() */
|
||||
int last_read_packet_len; /**< the length of the last *read* packet */
|
||||
} MCPVIO_EXT;
|
||||
|
||||
static int native_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
|
||||
{
|
||||
int pkt_len;
|
||||
uchar *pkt;
|
||||
|
||||
if (((MCPVIO_EXT *)vio)->mysql_change_user)
|
||||
{
|
||||
/*
|
||||
in mysql_change_user() the client sends the first packet.
|
||||
we use the old scramble.
|
||||
*/
|
||||
pkt= (uchar*)mysql->scramble_buff;
|
||||
pkt_len= SCRAMBLE_LENGTH + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* read the scramble */
|
||||
if ((pkt_len= vio->read_packet(vio, &pkt)) < 0)
|
||||
return CR_ERROR;
|
||||
|
||||
if (pkt_len != SCRAMBLE_LENGTH + 1)
|
||||
return CR_SERVER_HANDSHAKE_ERR;
|
||||
|
||||
/* save it in MYSQL */
|
||||
memcpy(mysql->scramble_buff, pkt, SCRAMBLE_LENGTH);
|
||||
mysql->scramble_buff[SCRAMBLE_LENGTH] = 0;
|
||||
}
|
||||
|
||||
if (mysql->passwd[0])
|
||||
{
|
||||
char scrambled[SCRAMBLE_LENGTH + 1];
|
||||
my_scramble_41((uchar *)scrambled, (char*)pkt, mysql->passwd);
|
||||
if (vio->write_packet(vio, (uchar*)scrambled, SCRAMBLE_LENGTH))
|
||||
return CR_ERROR;
|
||||
}
|
||||
else
|
||||
if (vio->write_packet(vio, 0, 0)) /* no password */
|
||||
return CR_ERROR;
|
||||
|
||||
return CR_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
client authentication plugin that does old MySQL authentication
|
||||
using an 8-byte (4.0-) scramble
|
||||
*/
|
||||
|
||||
static int old_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
|
||||
{
|
||||
uchar *pkt;
|
||||
int pkt_len;
|
||||
|
||||
if (((MCPVIO_EXT *)vio)->mysql_change_user)
|
||||
{
|
||||
/*
|
||||
in mysql_change_user() the client sends the first packet.
|
||||
we use the old scramble.
|
||||
*/
|
||||
pkt= (uchar*)mysql->scramble_buff;
|
||||
pkt_len= SCRAMBLE_LENGTH_323 + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* read the scramble */
|
||||
if ((pkt_len= vio->read_packet(vio, &pkt)) < 0)
|
||||
return CR_ERROR;
|
||||
|
||||
if (pkt_len != SCRAMBLE_LENGTH_323 + 1 &&
|
||||
pkt_len != SCRAMBLE_LENGTH + 1)
|
||||
return CR_SERVER_HANDSHAKE_ERR;
|
||||
|
||||
/* save it in MYSQL */
|
||||
memcpy(mysql->scramble_buff, pkt, pkt_len);
|
||||
mysql->scramble_buff[pkt_len] = 0;
|
||||
}
|
||||
|
||||
if (mysql->passwd[0])
|
||||
{
|
||||
char scrambled[SCRAMBLE_LENGTH_323 + 1];
|
||||
scramble_323(scrambled, (char*)pkt, mysql->passwd);
|
||||
if (vio->write_packet(vio, (uchar*)scrambled, SCRAMBLE_LENGTH_323 + 1))
|
||||
return CR_ERROR;
|
||||
}
|
||||
else
|
||||
if (vio->write_packet(vio, 0, 0)) /* no password */
|
||||
return CR_ERROR;
|
||||
|
||||
return CR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
sends a COM_CHANGE_USER command with a caller provided payload
|
||||
|
||||
Packet format:
|
||||
|
||||
Bytes Content
|
||||
----- ----
|
||||
n user name - \0-terminated string
|
||||
n password
|
||||
3.23 scramble - \0-terminated string (9 bytes)
|
||||
otherwise - length (1 byte) coded
|
||||
n database name - \0-terminated string
|
||||
2 character set number (if the server >= 4.1.x)
|
||||
n client auth plugin name - \0-terminated string,
|
||||
(if the server supports plugin auth)
|
||||
|
||||
@retval 0 ok
|
||||
@retval 1 error
|
||||
*/
|
||||
|
||||
static int send_change_user_packet(MCPVIO_EXT *mpvio,
|
||||
const uchar *data, int data_len)
|
||||
{
|
||||
MYSQL *mysql= mpvio->mysql;
|
||||
char *buff, *end;
|
||||
int res= 1;
|
||||
|
||||
buff= my_alloca(USERNAME_LENGTH+1 + data_len+1 + NAME_LEN+1 + 2 + NAME_LEN+1);
|
||||
|
||||
end= strmake(buff, mysql->user, USERNAME_LENGTH) + 1;
|
||||
|
||||
if (!data_len)
|
||||
*end++= 0;
|
||||
else
|
||||
{
|
||||
if (mysql->client_flag & CLIENT_SECURE_CONNECTION)
|
||||
{
|
||||
DBUG_ASSERT(data_len <= 255);
|
||||
if (data_len > 255)
|
||||
{
|
||||
my_set_error(mysql, CR_MALFORMED_PACKET, SQLSTATE_UNKNOWN, 0);
|
||||
goto error;
|
||||
}
|
||||
*end++= data_len;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBUG_ASSERT(data_len == SCRAMBLE_LENGTH_323 + 1);
|
||||
DBUG_ASSERT(data[SCRAMBLE_LENGTH_323] == 0);
|
||||
}
|
||||
memcpy(end, data, data_len);
|
||||
end+= data_len;
|
||||
}
|
||||
end= strmake(end, mpvio->db ? mpvio->db : "", NAME_LEN) + 1;
|
||||
|
||||
if (mysql->server_capabilities & CLIENT_PROTOCOL_41)
|
||||
{
|
||||
int2store(end, (ushort) mysql->charset->nr);
|
||||
end+= 2;
|
||||
}
|
||||
|
||||
if (mysql->server_capabilities & CLIENT_PLUGIN_AUTH)
|
||||
end= strmake(end, mpvio->plugin->name, NAME_LEN) + 1;
|
||||
|
||||
res= simple_command(mysql, MYSQL_COM_CHANGE_USER,
|
||||
buff, (ulong)(end-buff), 1);
|
||||
|
||||
error:
|
||||
my_afree(buff);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
sends a client authentication packet (second packet in the 3-way handshake)
|
||||
|
||||
Packet format (when the server is 4.0 or earlier):
|
||||
|
||||
Bytes Content
|
||||
----- ----
|
||||
2 client capabilities
|
||||
3 max packet size
|
||||
n user name, \0-terminated
|
||||
9 scramble_323, \0-terminated
|
||||
|
||||
Packet format (when the server is 4.1 or newer):
|
||||
|
||||
Bytes Content
|
||||
----- ----
|
||||
4 client capabilities
|
||||
4 max packet size
|
||||
1 charset number
|
||||
23 reserved (always 0)
|
||||
n user name, \0-terminated
|
||||
n plugin auth data (e.g. scramble), length (1 byte) coded
|
||||
n database name, \0-terminated
|
||||
(if CLIENT_CONNECT_WITH_DB is set in the capabilities)
|
||||
n client auth plugin name - \0-terminated string,
|
||||
(if CLIENT_PLUGIN_AUTH is set in the capabilities)
|
||||
|
||||
@retval 0 ok
|
||||
@retval 1 error
|
||||
*/
|
||||
|
||||
static int send_client_reply_packet(MCPVIO_EXT *mpvio,
|
||||
const uchar *data, int data_len)
|
||||
{
|
||||
MYSQL *mysql= mpvio->mysql;
|
||||
NET *net= &mysql->net;
|
||||
char *buff, *end;
|
||||
|
||||
/* see end= buff+32 below, fixed size of the packet is 32 bytes */
|
||||
buff= my_alloca(33 + USERNAME_LENGTH + data_len + NAME_LEN + NAME_LEN);
|
||||
|
||||
mysql->client_flag|= mysql->options.client_flag;
|
||||
mysql->client_flag|= CLIENT_CAPABILITIES;
|
||||
|
||||
if (mysql->client_flag & CLIENT_MULTI_STATEMENTS)
|
||||
mysql->client_flag|= CLIENT_MULTI_RESULTS;
|
||||
|
||||
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
|
||||
if (mysql->options.ssl_key || mysql->options.ssl_cert ||
|
||||
mysql->options.ssl_ca || mysql->options.ssl_capath ||
|
||||
mysql->options.ssl_cipher)
|
||||
mysql->options.use_ssl= 1;
|
||||
if (mysql->options.use_ssl)
|
||||
mysql->client_flag|= CLIENT_SSL;
|
||||
#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY*/
|
||||
if (mpvio->db)
|
||||
mysql->client_flag|= CLIENT_CONNECT_WITH_DB;
|
||||
|
||||
/* Remove options that server doesn't support */
|
||||
mysql->client_flag= mysql->client_flag &
|
||||
(~(CLIENT_COMPRESS | CLIENT_SSL | CLIENT_PROTOCOL_41)
|
||||
| mysql->server_capabilities);
|
||||
|
||||
#ifndef HAVE_COMPRESS
|
||||
mysql->client_flag&= ~CLIENT_COMPRESS;
|
||||
#endif
|
||||
|
||||
if (mysql->client_flag & CLIENT_PROTOCOL_41)
|
||||
{
|
||||
/* 4.1 server and 4.1 client has a 32 byte option flag */
|
||||
int4store(buff,mysql->client_flag);
|
||||
int4store(buff+4, net->max_packet_size);
|
||||
buff[8]= (char) mysql->charset->nr;
|
||||
bzero(buff+9, 32-9);
|
||||
end= buff+32;
|
||||
}
|
||||
else
|
||||
{
|
||||
int2store(buff, mysql->client_flag);
|
||||
int3store(buff+2, net->max_packet_size);
|
||||
end= buff+5;
|
||||
}
|
||||
#ifdef HAVE_OPENSSL
|
||||
if (mysql->client_flag & CLIENT_SSL)
|
||||
{
|
||||
/* Do the SSL layering. */
|
||||
struct st_mysql_options *options= &mysql->options;
|
||||
struct st_VioSSLFd *ssl_fd;
|
||||
char error_string[1024];
|
||||
|
||||
/*
|
||||
Send mysql->client_flag, max_packet_size - unencrypted otherwise
|
||||
the server does not know we want to do SSL
|
||||
*/
|
||||
if (my_net_write(net, (uchar*)buff, (size_t) (end-buff)) || net_flush(net))
|
||||
{
|
||||
my_set_error(mysql, CR_SERVER_LOST, SQLSTATE_UNKNOWN,
|
||||
ER(CR_SERVER_LOST_EXTENDED),
|
||||
"sending connection information to server",
|
||||
errno);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Create the VioSSLConnectorFd - init SSL and load certs */
|
||||
if (!(ssl_fd= new_VioSSLConnectorFd(options->ssl_key,
|
||||
options->ssl_cert,
|
||||
options->ssl_ca,
|
||||
options->ssl_capath,
|
||||
options->ssl_cipher)))
|
||||
{
|
||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, 0);
|
||||
goto error;
|
||||
}
|
||||
mysql->connector_fd= (void*)ssl_fd;
|
||||
|
||||
/* Connect to the server */
|
||||
DBUG_PRINT("info", ("IO layer change in progress..."));
|
||||
if (sslconnect(ssl_fd, net->vio,
|
||||
(long) (mysql->options.connect_timeout),
|
||||
error_string))
|
||||
{
|
||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR,
|
||||
SQLSTATE_UNKNOWN, "SSL error: %s",
|
||||
error_string[0] ? error_string :
|
||||
ER(CR_SSL_CONNECTION_ERROR));
|
||||
goto error;
|
||||
}
|
||||
DBUG_PRINT("info", ("IO layer change done!"));
|
||||
|
||||
/* Verify server cert */
|
||||
if ((mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) &&
|
||||
ssl_verify_server_cert(net->vio, mysql->host))
|
||||
{
|
||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, 0);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
||||
DBUG_PRINT("info",("Server version = '%s' capabilites: %lu status: %u client_flag: %lu",
|
||||
mysql->server_version, mysql->server_capabilities,
|
||||
mysql->server_status, mysql->client_flag));
|
||||
|
||||
compile_time_assert(MYSQL_USERNAME_LENGTH == USERNAME_LENGTH);
|
||||
|
||||
/* This needs to be changed as it's not useful with big packets */
|
||||
if (mysql->user[0])
|
||||
strmake(end, mysql->user, USERNAME_LENGTH);
|
||||
else
|
||||
read_user_name(end);
|
||||
|
||||
/* We have to handle different version of handshake here */
|
||||
DBUG_PRINT("info",("user: %s",end));
|
||||
end= strend(end) + 1;
|
||||
if (data_len)
|
||||
{
|
||||
if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
|
||||
{
|
||||
*end++= data_len;
|
||||
memcpy(end, data, data_len);
|
||||
end+= data_len;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBUG_ASSERT(data_len == SCRAMBLE_LENGTH_323 + 1); /* incl. \0 at the end */
|
||||
memcpy(end, data, data_len);
|
||||
end+= data_len;
|
||||
}
|
||||
}
|
||||
else
|
||||
*end++= 0;
|
||||
|
||||
/* Add database if needed */
|
||||
if (mpvio->db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB))
|
||||
{
|
||||
end= strmake(end, mpvio->db, NAME_LEN) + 1;
|
||||
mysql->db= my_strdup(mpvio->db, MYF(MY_WME));
|
||||
}
|
||||
|
||||
if (mysql->server_capabilities & CLIENT_PLUGIN_AUTH)
|
||||
end= strmake(end, mpvio->plugin->name, NAME_LEN) + 1;
|
||||
|
||||
/* Write authentication package */
|
||||
if (my_net_write(net, buff, (size_t) (end-buff)) || net_flush(net))
|
||||
{
|
||||
my_set_error(mysql, CR_SERVER_LOST, SQLSTATE_UNKNOWN,
|
||||
ER(CR_SERVER_LOST_EXTENDED),
|
||||
"sending authentication information",
|
||||
errno);
|
||||
goto error;
|
||||
}
|
||||
my_afree(buff);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
my_afree(buff);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
vio->read_packet() callback method for client authentication plugins
|
||||
|
||||
This function is called by a client authentication plugin, when it wants
|
||||
to read data from the server.
|
||||
*/
|
||||
|
||||
static int client_mpvio_read_packet(struct st_plugin_vio *mpv, uchar **buf)
|
||||
{
|
||||
MCPVIO_EXT *mpvio= (MCPVIO_EXT*)mpv;
|
||||
MYSQL *mysql= mpvio->mysql;
|
||||
ulong pkt_len;
|
||||
|
||||
/* there are cached data left, feed it to a plugin */
|
||||
if (mpvio->cached_server_reply.pkt)
|
||||
{
|
||||
*buf= mpvio->cached_server_reply.pkt;
|
||||
mpvio->cached_server_reply.pkt= 0;
|
||||
mpvio->packets_read++;
|
||||
return mpvio->cached_server_reply.pkt_len;
|
||||
}
|
||||
|
||||
if (mpvio->packets_read == 0)
|
||||
{
|
||||
/*
|
||||
the server handshake packet came from the wrong plugin,
|
||||
or it's mysql_change_user(). Either way, there is no data
|
||||
for a plugin to read. send a dummy packet to the server
|
||||
to initiate a dialog.
|
||||
*/
|
||||
if (client_mpvio_write_packet(mpv, 0, 0))
|
||||
return (int)packet_error;
|
||||
}
|
||||
|
||||
/* otherwise read the data */
|
||||
pkt_len= net_safe_read(mysql);
|
||||
mpvio->last_read_packet_len= pkt_len;
|
||||
*buf= mysql->net.read_pos;
|
||||
|
||||
/* was it a request to change plugins ? */
|
||||
if (**buf == 254)
|
||||
return (int)packet_error; /* if yes, this plugin shan't continue */
|
||||
|
||||
/*
|
||||
the server sends \1\255 or \1\254 instead of just \255 or \254 -
|
||||
for us to not confuse it with an error or "change plugin" packets.
|
||||
We remove this escaping \1 here.
|
||||
|
||||
See also server_mpvio_write_packet() where the escaping is done.
|
||||
*/
|
||||
if (pkt_len && **buf == 1)
|
||||
{
|
||||
(*buf)++;
|
||||
pkt_len--;
|
||||
}
|
||||
mpvio->packets_read++;
|
||||
return pkt_len;
|
||||
}
|
||||
|
||||
/**
|
||||
vio->write_packet() callback method for client authentication plugins
|
||||
|
||||
This function is called by a client authentication plugin, when it wants
|
||||
to send data to the server.
|
||||
|
||||
It transparently wraps the data into a change user or authentication
|
||||
handshake packet, if neccessary.
|
||||
*/
|
||||
|
||||
static int client_mpvio_write_packet(struct st_plugin_vio *mpv,
|
||||
const uchar *pkt, size_t pkt_len)
|
||||
{
|
||||
int res;
|
||||
MCPVIO_EXT *mpvio= (MCPVIO_EXT*)mpv;
|
||||
|
||||
if (mpvio->packets_written == 0)
|
||||
{
|
||||
if (mpvio->mysql_change_user)
|
||||
res= send_change_user_packet(mpvio, pkt, pkt_len);
|
||||
else
|
||||
res= send_client_reply_packet(mpvio, pkt, pkt_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
NET *net= &mpvio->mysql->net;
|
||||
if (mpvio->mysql->thd)
|
||||
res= 1; /* no chit-chat in embedded */
|
||||
else
|
||||
res= my_net_write(net, (char *)pkt, pkt_len) || net_flush(net);
|
||||
if (res)
|
||||
my_set_error(mpvio->mysql, CR_SERVER_LOST, SQLSTATE_UNKNOWN,
|
||||
ER(CR_SERVER_LOST_EXTENDED),
|
||||
"sending authentication information",
|
||||
errno);
|
||||
}
|
||||
mpvio->packets_written++;
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
fills MYSQL_PLUGIN_VIO_INFO structure with the information about the
|
||||
connection
|
||||
*/
|
||||
|
||||
void mpvio_info(Vio *vio, MYSQL_PLUGIN_VIO_INFO *info)
|
||||
{
|
||||
bzero(info, sizeof(*info));
|
||||
switch (vio->type) {
|
||||
case VIO_TYPE_TCPIP:
|
||||
info->protocol= MYSQL_VIO_TCP;
|
||||
info->socket= vio->sd;
|
||||
return;
|
||||
case VIO_TYPE_SOCKET:
|
||||
info->protocol= MYSQL_VIO_SOCKET;
|
||||
info->socket= vio->sd;
|
||||
return;
|
||||
case VIO_TYPE_SSL:
|
||||
{
|
||||
struct sockaddr addr;
|
||||
SOCKET_SIZE_TYPE addrlen= sizeof(addr);
|
||||
if (getsockname(vio->sd, &addr, &addrlen))
|
||||
return;
|
||||
info->protocol= addr.sa_family == AF_UNIX ?
|
||||
MYSQL_VIO_SOCKET : MYSQL_VIO_TCP;
|
||||
info->socket= vio->sd;
|
||||
return;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
case VIO_TYPE_NAMEDPIPE:
|
||||
info->protocol= MYSQL_VIO_PIPE;
|
||||
info->handle= vio->hPipe;
|
||||
return;
|
||||
/* not supported yet
|
||||
case VIO_TYPE_SHARED_MEMORY:
|
||||
info->protocol= MYSQL_VIO_MEMORY;
|
||||
info->handle= vio->handle_file_map;
|
||||
return;
|
||||
*/
|
||||
#endif
|
||||
default: DBUG_ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void client_mpvio_info(MYSQL_PLUGIN_VIO *vio,
|
||||
MYSQL_PLUGIN_VIO_INFO *info)
|
||||
{
|
||||
MCPVIO_EXT *mpvio= (MCPVIO_EXT*)vio;
|
||||
mpvio_info(mpvio->mysql->net.vio, info);
|
||||
}
|
||||
|
||||
/**
|
||||
Client side of the plugin driver authentication.
|
||||
|
||||
@note this is used by both the mysql_real_connect and mysql_change_user
|
||||
|
||||
@param mysql mysql
|
||||
@param data pointer to the plugin auth data (scramble) in the
|
||||
handshake packet
|
||||
@param data_len the length of the data
|
||||
@param data_plugin a plugin that data were prepared for
|
||||
or 0 if it's mysql_change_user()
|
||||
@param db initial db to use, can be 0
|
||||
|
||||
@retval 0 ok
|
||||
@retval 1 error
|
||||
*/
|
||||
|
||||
int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
|
||||
const char *data_plugin, const char *db)
|
||||
{
|
||||
const char *auth_plugin_name;
|
||||
auth_plugin_t *auth_plugin;
|
||||
MCPVIO_EXT mpvio;
|
||||
ulong pkt_length;
|
||||
int res;
|
||||
|
||||
/* determine the default/initial plugin to use */
|
||||
if (mysql->options.extension && mysql->options.extension->default_auth &&
|
||||
mysql->server_capabilities & CLIENT_PLUGIN_AUTH)
|
||||
{
|
||||
auth_plugin_name= mysql->options.extension->default_auth;
|
||||
if (!(auth_plugin= (auth_plugin_t*) mysql_client_find_plugin(mysql,
|
||||
auth_plugin_name, MYSQL_CLIENT_AUTHENTICATION_PLUGIN)))
|
||||
return 1; /* oops, not found */
|
||||
}
|
||||
else
|
||||
{
|
||||
auth_plugin= mysql->server_capabilities & CLIENT_PROTOCOL_41 ?
|
||||
&native_password_client_plugin : &old_password_client_plugin;
|
||||
auth_plugin_name= auth_plugin->name;
|
||||
}
|
||||
|
||||
mysql->net.last_errno= 0; /* just in case */
|
||||
|
||||
if (data_plugin && strcmp(data_plugin, auth_plugin_name))
|
||||
{
|
||||
/* data was prepared for a different plugin, don't show it to this one */
|
||||
data= 0;
|
||||
data_len= 0;
|
||||
}
|
||||
|
||||
mpvio.mysql_change_user= data_plugin == 0;
|
||||
mpvio.cached_server_reply.pkt= (uchar*)data;
|
||||
mpvio.cached_server_reply.pkt_len= data_len;
|
||||
mpvio.read_packet= client_mpvio_read_packet;
|
||||
mpvio.write_packet= client_mpvio_write_packet;
|
||||
mpvio.info= client_mpvio_info;
|
||||
mpvio.mysql= mysql;
|
||||
mpvio.packets_read= mpvio.packets_written= 0;
|
||||
mpvio.db= db;
|
||||
mpvio.plugin= auth_plugin;
|
||||
|
||||
res= auth_plugin->authenticate_user((struct st_plugin_vio *)&mpvio, mysql);
|
||||
|
||||
compile_time_assert(CR_OK == -1);
|
||||
compile_time_assert(CR_ERROR == 0);
|
||||
if (res > CR_OK && mysql->net.read_pos[0] != 254)
|
||||
{
|
||||
/*
|
||||
the plugin returned an error. write it down in mysql,
|
||||
unless the error code is CR_ERROR and mysql->net.last_errno
|
||||
is already set (the plugin has done it)
|
||||
*/
|
||||
if (res > CR_ERROR)
|
||||
my_set_error(mysql, res, SQLSTATE_UNKNOWN, 0);
|
||||
else
|
||||
if (!mysql->net.last_errno)
|
||||
my_set_error(mysql, CR_UNKNOWN_ERROR, SQLSTATE_UNKNOWN, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* read the OK packet (or use the cached value in mysql->net.read_pos */
|
||||
if (res == CR_OK)
|
||||
pkt_length= net_safe_read(mysql);
|
||||
else /* res == CR_OK_HANDSHAKE_COMPLETE */
|
||||
pkt_length= mpvio.last_read_packet_len;
|
||||
|
||||
if (pkt_length == packet_error)
|
||||
{
|
||||
if (mysql->net.last_errno == CR_SERVER_LOST)
|
||||
my_set_error(mysql, CR_SERVER_LOST, SQLSTATE_UNKNOWN,
|
||||
ER(CR_SERVER_LOST_EXTENDED),
|
||||
"reading authorization packet",
|
||||
errno);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (mysql->net.read_pos[0] == 254)
|
||||
{
|
||||
/* The server asked to use a different authentication plugin */
|
||||
if (pkt_length == 1)
|
||||
{
|
||||
/* old "use short scramble" packet */
|
||||
auth_plugin_name= old_password_plugin_name;
|
||||
mpvio.cached_server_reply.pkt= (uchar*)mysql->scramble_buff;
|
||||
mpvio.cached_server_reply.pkt_len= SCRAMBLE_LENGTH + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* new "use different plugin" packet */
|
||||
uint len;
|
||||
auth_plugin_name= (char*)mysql->net.read_pos + 1;
|
||||
len= strlen(auth_plugin_name); /* safe as my_net_read always appends \0 */
|
||||
mpvio.cached_server_reply.pkt_len= pkt_length - len - 2;
|
||||
mpvio.cached_server_reply.pkt= mysql->net.read_pos + len + 2;
|
||||
}
|
||||
|
||||
if (!(auth_plugin= (auth_plugin_t *) mysql_client_find_plugin(mysql,
|
||||
auth_plugin_name, MYSQL_CLIENT_AUTHENTICATION_PLUGIN)))
|
||||
return 1;
|
||||
|
||||
mpvio.plugin= auth_plugin;
|
||||
res= auth_plugin->authenticate_user((struct st_plugin_vio *)&mpvio, mysql);
|
||||
|
||||
if (res > CR_OK)
|
||||
{
|
||||
if (res > CR_ERROR)
|
||||
my_set_error(mysql, res, SQLSTATE_UNKNOWN, 0);
|
||||
else
|
||||
if (!mysql->net.last_errno)
|
||||
my_set_error(mysql, CR_UNKNOWN_ERROR, SQLSTATE_UNKNOWN, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (res != CR_OK_HANDSHAKE_COMPLETE)
|
||||
{
|
||||
/* Read what server thinks about out new auth message report */
|
||||
if (net_safe_read(mysql) == packet_error)
|
||||
{
|
||||
if (mysql->net.last_errno == CR_SERVER_LOST)
|
||||
my_set_error(mysql, CR_SERVER_LOST, SQLSTATE_UNKNOWN,
|
||||
ER(CR_SERVER_LOST_EXTENDED),
|
||||
"reading final connect information",
|
||||
errno);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
net->read_pos[0] should always be 0 here if the server implements
|
||||
the protocol correctly
|
||||
*/
|
||||
return mysql->net.read_pos[0] != 0;
|
||||
}
|
||||
|
828
libmysql/my_charset.c
Normal file
828
libmysql/my_charset.c
Normal file
@ -0,0 +1,828 @@
|
||||
/****************************************************************************
|
||||
Copyright (C) 2011 Monty Program 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 see <http://www.gnu.org/licenses>
|
||||
or write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St., Fifth Floor, Boston, MA 02110, USA
|
||||
*****************************************************************************/
|
||||
|
||||
/* The implementation for character set support was ported from PHP's mysqlnd
|
||||
extension, written by Andrey Hristov, Georg Richter and Ulf Wendel
|
||||
|
||||
Original file header:
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 2006-2011 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Georg Richter <georg@mysql.com> |
|
||||
| Andrey Hristov <andrey@mysql.com> |
|
||||
| Ulf Wendel <uwendel@mysql.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <strings.h>
|
||||
#include <string.h>
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif
|
||||
#include <my_global.h>
|
||||
#include <m_ctype.h>
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 2006-2011 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Georg Richter <georg@mysql.com> |
|
||||
| Andrey Hristov <andrey@mysql.com> |
|
||||
| Ulf Wendel <uwendel@mysql.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* {{{ utf8 functions */
|
||||
static unsigned int check_mb_utf8mb3_sequence(const char *start, const char *end)
|
||||
{
|
||||
uchar c;
|
||||
|
||||
if (start >= end) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
c = (uchar) start[0];
|
||||
|
||||
if (c < 0x80) {
|
||||
return 1; /* single byte character */
|
||||
}
|
||||
if (c < 0xC2) {
|
||||
return 0; /* invalid mb character */
|
||||
}
|
||||
if (c < 0xE0) {
|
||||
if (start + 2 > end) {
|
||||
return 0; /* too small */
|
||||
}
|
||||
if (!(((uchar)start[1] ^ 0x80) < 0x40)) {
|
||||
return 0;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
if (c < 0xF0) {
|
||||
if (start + 3 > end) {
|
||||
return 0; /* too small */
|
||||
}
|
||||
if (!(((uchar)start[1] ^ 0x80) < 0x40 && ((uchar)start[2] ^ 0x80) < 0x40 &&
|
||||
(c >= 0xE1 || (uchar)start[1] >= 0xA0))) {
|
||||
return 0; /* invalid utf8 character */
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static unsigned int check_mb_utf8_sequence(const char *start, const char *end)
|
||||
{
|
||||
uchar c;
|
||||
|
||||
if (start >= end) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
c = (uchar) start[0];
|
||||
|
||||
if (c < 0x80) {
|
||||
return 1; /* single byte character */
|
||||
}
|
||||
if (c < 0xC2) {
|
||||
return 0; /* invalid mb character */
|
||||
}
|
||||
if (c < 0xE0) {
|
||||
if (start + 2 > end) {
|
||||
return 0; /* too small */
|
||||
}
|
||||
if (!(((uchar)start[1] ^ 0x80) < 0x40)) {
|
||||
return 0;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
if (c < 0xF0) {
|
||||
if (start + 3 > end) {
|
||||
return 0; /* too small */
|
||||
}
|
||||
if (!(((uchar)start[1] ^ 0x80) < 0x40 && ((uchar)start[2] ^ 0x80) < 0x40 &&
|
||||
(c >= 0xE1 || (uchar)start[1] >= 0xA0))) {
|
||||
return 0; /* invalid utf8 character */
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
if (c < 0xF5) {
|
||||
if (start + 4 > end) { /* We need 4 characters */
|
||||
return 0; /* too small */
|
||||
}
|
||||
|
||||
/*
|
||||
UTF-8 quick four-byte mask:
|
||||
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||
Encoding allows to encode U+00010000..U+001FFFFF
|
||||
|
||||
The maximum character defined in the Unicode standard is U+0010FFFF.
|
||||
Higher characters U+00110000..U+001FFFFF are not used.
|
||||
|
||||
11110000.10010000.10xxxxxx.10xxxxxx == F0.90.80.80 == U+00010000 (min)
|
||||
11110100.10001111.10111111.10111111 == F4.8F.BF.BF == U+0010FFFF (max)
|
||||
|
||||
Valid codes:
|
||||
[F0][90..BF][80..BF][80..BF]
|
||||
[F1][80..BF][80..BF][80..BF]
|
||||
[F2][80..BF][80..BF][80..BF]
|
||||
[F3][80..BF][80..BF][80..BF]
|
||||
[F4][80..8F][80..BF][80..BF]
|
||||
*/
|
||||
|
||||
if (!(((uchar)start[1] ^ 0x80) < 0x40 &&
|
||||
((uchar)start[2] ^ 0x80) < 0x40 &&
|
||||
((uchar)start[3] ^ 0x80) < 0x40 &&
|
||||
(c >= 0xf1 || (uchar)start[1] >= 0x90) &&
|
||||
(c <= 0xf3 || (uchar)start[1] <= 0x8F)))
|
||||
{
|
||||
return 0; /* invalid utf8 character */
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int check_mb_utf8mb3_valid(const char *start, const char *end)
|
||||
{
|
||||
unsigned int len = check_mb_utf8mb3_sequence(start, end);
|
||||
return (len > 1)? len:0;
|
||||
}
|
||||
|
||||
static unsigned int check_mb_utf8_valid(const char *start, const char *end)
|
||||
{
|
||||
unsigned int len = check_mb_utf8_sequence(start, end);
|
||||
return (len > 1)? len:0;
|
||||
}
|
||||
|
||||
|
||||
static unsigned int mysql_mbcharlen_utf8mb3(unsigned int utf8)
|
||||
{
|
||||
if (utf8 < 0x80) {
|
||||
return 1; /* single byte character */
|
||||
}
|
||||
if (utf8 < 0xC2) {
|
||||
return 0; /* invalid multibyte header */
|
||||
}
|
||||
if (utf8 < 0xE0) {
|
||||
return 2; /* double byte character */
|
||||
}
|
||||
if (utf8 < 0xF0) {
|
||||
return 3; /* triple byte character */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static unsigned int mysql_mbcharlen_utf8(unsigned int utf8)
|
||||
{
|
||||
if (utf8 < 0x80) {
|
||||
return 1; /* single byte character */
|
||||
}
|
||||
if (utf8 < 0xC2) {
|
||||
return 0; /* invalid multibyte header */
|
||||
}
|
||||
if (utf8 < 0xE0) {
|
||||
return 2; /* double byte character */
|
||||
}
|
||||
if (utf8 < 0xF0) {
|
||||
return 3; /* triple byte character */
|
||||
}
|
||||
if (utf8 < 0xF8) {
|
||||
return 4; /* four byte character */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ big5 functions */
|
||||
#define valid_big5head(c) (0xA1 <= (unsigned int)(c) && (unsigned int)(c) <= 0xF9)
|
||||
#define valid_big5tail(c) ((0x40 <= (unsigned int)(c) && (unsigned int)(c) <= 0x7E) || \
|
||||
(0xA1 <= (unsigned int)(c) && (unsigned int)(c) <= 0xFE))
|
||||
|
||||
#define isbig5code(c,d) (isbig5head(c) && isbig5tail(d))
|
||||
|
||||
static unsigned int check_mb_big5(const char *start, const char *end)
|
||||
{
|
||||
return (valid_big5head(*(start)) && (end - start) > 1 && valid_big5tail(*(start + 1)) ? 2 : 0);
|
||||
}
|
||||
|
||||
|
||||
static unsigned int mysql_mbcharlen_big5(unsigned int big5)
|
||||
{
|
||||
return (valid_big5head(big5)) ? 2 : 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ cp932 functions */
|
||||
#define valid_cp932head(c) ((0x81 <= (c) && (c) <= 0x9F) || (0xE0 <= (c) && c <= 0xFC))
|
||||
#define valid_cp932tail(c) ((0x40 <= (c) && (c) <= 0x7E) || (0x80 <= (c) && c <= 0xFC))
|
||||
|
||||
|
||||
static unsigned int check_mb_cp932(const char *start, const char *end)
|
||||
{
|
||||
return (valid_cp932head((uchar)start[0]) && (end - start > 1) &&
|
||||
valid_cp932tail((uchar)start[1])) ? 2 : 0;
|
||||
}
|
||||
|
||||
|
||||
static unsigned int mysql_mbcharlen_cp932(unsigned int cp932)
|
||||
{
|
||||
return (valid_cp932head((uchar)cp932)) ? 2 : 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ euckr functions */
|
||||
#define valid_euckr(c) ((0xA1 <= (uchar)(c) && (uchar)(c) <= 0xFE))
|
||||
|
||||
static unsigned int check_mb_euckr(const char *start, const char *end)
|
||||
{
|
||||
if (end - start <= 1) {
|
||||
return 0; /* invalid length */
|
||||
}
|
||||
if (*(uchar *)start < 0x80) {
|
||||
return 0; /* invalid euckr character */
|
||||
}
|
||||
if (valid_euckr(start[1])) {
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static unsigned int mysql_mbcharlen_euckr(unsigned int kr)
|
||||
{
|
||||
return (valid_euckr(kr)) ? 2 : 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ eucjpms functions */
|
||||
#define valid_eucjpms(c) (((c) & 0xFF) >= 0xA1 && ((c) & 0xFF) <= 0xFE)
|
||||
#define valid_eucjpms_kata(c) (((c) & 0xFF) >= 0xA1 && ((c) & 0xFF) <= 0xDF)
|
||||
#define valid_eucjpms_ss2(c) (((c) & 0xFF) == 0x8E)
|
||||
#define valid_eucjpms_ss3(c) (((c) & 0xFF) == 0x8F)
|
||||
|
||||
static unsigned int check_mb_eucjpms(const char *start, const char *end)
|
||||
{
|
||||
if (*((uchar *)start) < 0x80) {
|
||||
return 0; /* invalid eucjpms character */
|
||||
}
|
||||
if (valid_eucjpms(start[0]) && (end - start) > 1 && valid_eucjpms(start[1])) {
|
||||
return 2;
|
||||
}
|
||||
if (valid_eucjpms_ss2(start[0]) && (end - start) > 1 && valid_eucjpms_kata(start[1])) {
|
||||
return 2;
|
||||
}
|
||||
if (valid_eucjpms_ss3(start[0]) && (end - start) > 2 && valid_eucjpms(start[1]) &&
|
||||
valid_eucjpms(start[2])) {
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static unsigned int mysql_mbcharlen_eucjpms(unsigned int jpms)
|
||||
{
|
||||
if (valid_eucjpms(jpms) || valid_eucjpms_ss2(jpms)) {
|
||||
return 2;
|
||||
}
|
||||
if (valid_eucjpms_ss3(jpms)) {
|
||||
return 3;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ gb2312 functions */
|
||||
#define valid_gb2312_head(c) (0xA1 <= (uchar)(c) && (uchar)(c) <= 0xF7)
|
||||
#define valid_gb2312_tail(c) (0xA1 <= (uchar)(c) && (uchar)(c) <= 0xFE)
|
||||
|
||||
|
||||
static unsigned int check_mb_gb2312(const char *start, const char *end)
|
||||
{
|
||||
return (valid_gb2312_head((unsigned int)start[0]) && end - start > 1 &&
|
||||
valid_gb2312_tail((unsigned int)start[1])) ? 2 : 0;
|
||||
}
|
||||
|
||||
|
||||
static unsigned int mysql_mbcharlen_gb2312(unsigned int gb)
|
||||
{
|
||||
return (valid_gb2312_head(gb)) ? 2 : 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ gbk functions */
|
||||
#define valid_gbk_head(c) (0x81<=(uchar)(c) && (uchar)(c)<=0xFE)
|
||||
#define valid_gbk_tail(c) ((0x40<=(uchar)(c) && (uchar)(c)<=0x7E) || (0x80<=(uchar)(c) && (uchar)(c)<=0xFE))
|
||||
|
||||
static unsigned int check_mb_gbk(const char *start, const char *end)
|
||||
{
|
||||
return (valid_gbk_head(start[0]) && (end) - (start) > 1 && valid_gbk_tail(start[1])) ? 2 : 0;
|
||||
}
|
||||
|
||||
static unsigned int mysql_mbcharlen_gbk(unsigned int gbk)
|
||||
{
|
||||
return (valid_gbk_head(gbk) ? 2 : 1);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ sjis functions */
|
||||
#define valid_sjis_head(c) ((0x81 <= (c) && (c) <= 0x9F) || (0xE0 <= (c) && (c) <= 0xFC))
|
||||
#define valid_sjis_tail(c) ((0x40 <= (c) && (c) <= 0x7E) || (0x80 <= (c) && (c) <= 0xFC))
|
||||
|
||||
|
||||
static unsigned int check_mb_sjis(const char *start, const char *end)
|
||||
{
|
||||
return (valid_sjis_head((uchar)start[0]) && (end - start) > 1 && valid_sjis_tail((uchar)start[1])) ? 2 : 0;
|
||||
}
|
||||
|
||||
|
||||
static unsigned int mysql_mbcharlen_sjis(unsigned int sjis)
|
||||
{
|
||||
return (valid_sjis_head((uchar)sjis)) ? 2 : 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ ucs2 functions */
|
||||
static unsigned int check_mb_ucs2(const char *start __attribute((unused)), const char *end __attribute((unused)))
|
||||
{
|
||||
return 2; /* always 2 */
|
||||
}
|
||||
|
||||
static unsigned int mysql_mbcharlen_ucs2(unsigned int ucs2 __attribute((unused)))
|
||||
{
|
||||
return 2; /* always 2 */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ ujis functions */
|
||||
#define valid_ujis(c) ((0xA1 <= ((c)&0xFF) && ((c)&0xFF) <= 0xFE))
|
||||
#define valid_ujis_kata(c) ((0xA1 <= ((c)&0xFF) && ((c)&0xFF) <= 0xDF))
|
||||
#define valid_ujis_ss2(c) (((c)&0xFF) == 0x8E)
|
||||
#define valid_ujis_ss3(c) (((c)&0xFF) == 0x8F)
|
||||
|
||||
static unsigned int check_mb_ujis(const char *start, const char *end)
|
||||
{
|
||||
if (*(uchar*)start < 0x80) {
|
||||
return 0; /* invalid ujis character */
|
||||
}
|
||||
if (valid_ujis(*(start)) && valid_ujis(*((start)+1))) {
|
||||
return 2;
|
||||
}
|
||||
if (valid_ujis_ss2(*(start)) && valid_ujis_kata(*((start)+1))) {
|
||||
return 2;
|
||||
}
|
||||
if (valid_ujis_ss3(*(start)) && (end-start) > 2 && valid_ujis(*((start)+1)) && valid_ujis(*((start)+2))) {
|
||||
return 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static unsigned int mysql_mbcharlen_ujis(unsigned int ujis)
|
||||
{
|
||||
return (valid_ujis(ujis)? 2: valid_ujis_ss2(ujis)? 2: valid_ujis_ss3(ujis)? 3: 1);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
|
||||
/* {{{ utf16 functions */
|
||||
#define UTF16_HIGH_HEAD(x) ((((uchar) (x)) & 0xFC) == 0xD8)
|
||||
#define UTF16_LOW_HEAD(x) ((((uchar) (x)) & 0xFC) == 0xDC)
|
||||
|
||||
static unsigned int check_mb_utf16(const char *start, const char *end)
|
||||
{
|
||||
if (start + 2 > end) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (UTF16_HIGH_HEAD(*start)) {
|
||||
return (start + 4 <= end) && UTF16_LOW_HEAD(start[2]) ? 4 : 0;
|
||||
}
|
||||
|
||||
if (UTF16_LOW_HEAD(*start)) {
|
||||
return 0;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
static uint mysql_mbcharlen_utf16(unsigned int utf16)
|
||||
{
|
||||
return UTF16_HIGH_HEAD(utf16) ? 4 : 2;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ utf32 functions */
|
||||
static uint
|
||||
check_mb_utf32(const char *start __attribute((unused)), const char *end __attribute((unused)))
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
|
||||
static uint
|
||||
mysql_mbcharlen_utf32(unsigned int utf32 __attribute((unused)))
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
The server compiles sometimes the full utf-8 (the mb4) as utf8m4, and the old as utf8,
|
||||
for BC reasons. Sometimes, utf8mb4 is just utf8 but the old charsets are utf8mb3.
|
||||
Change easily now, with a macro, could be made compilastion dependable.
|
||||
*/
|
||||
|
||||
#define UTF8_MB4 "utf8mb4"
|
||||
#define UTF8_MB3 "utf8"
|
||||
|
||||
/* {{{ mysql_charsets */
|
||||
const CHARSET_INFO compiled_charsets[] =
|
||||
{
|
||||
{ 1, 1, "big5","big5_chinese_ci", "", "", 1, 2, mysql_mbcharlen_big5, check_mb_big5},
|
||||
{ 3, 1, "dec8", "dec8_swedisch_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 4, 1, "cp850", "cp850_general_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 6, 1, "hp8", "hp8_english_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 7, 1, "koi8r", "koi8r_general_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 8, 1, "latin1", "latin1_swedish_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 9, 1, "latin2", "latin2_general_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 10, 1, "swe7", "swe7_swedish_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 11, 1, "ascii", "ascii_general_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 12, 1, "ujis", "ujis_japanese_ci", "", "", 1, 3, mysql_mbcharlen_ujis, check_mb_ujis},
|
||||
{ 13, 1, "sjis", "sjis_japanese_ci", "", "", 1, 2, mysql_mbcharlen_sjis, check_mb_sjis},
|
||||
{ 16, 1, "hebrew", "hebrew_general_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 18, 1, "tis620", "tis620_thai_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 19, 1, "euckr", "euckr_korean_ci", "", "", 1, 2, mysql_mbcharlen_euckr, check_mb_euckr},
|
||||
{ 22, 1, "koi8u", "koi8u_general_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 24, 1, "gb2312", "gb2312_chinese_ci", "", "", 1, 2, mysql_mbcharlen_gb2312, check_mb_gb2312},
|
||||
{ 25, 1, "greek", "greek_general_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 26, 1, "cp1250", "cp1250_general_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 28, 1, "gbk", "gbk_chinese_ci", "", "", 1, 2, mysql_mbcharlen_gbk, check_mb_gbk},
|
||||
{ 30, 1, "latin5", "latin5_turkish_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 32, 1, "armscii8", "armscii8_general_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 33, 1, UTF8_MB3, UTF8_MB3"_general_ci", "UTF-8 Unicode", "", 1, 3, mysql_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
|
||||
{ 35, 1, "ucs2", "ucs2_general_ci", "UCS-2 Unicode", "", 2, 2, mysql_mbcharlen_ucs2, check_mb_ucs2},
|
||||
{ 36, 1, "cp866", "cp866_general_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 37, 1, "keybcs2", "keybcs2_general_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 38, 1, "macce", "macce_general_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 39, 1, "macroman", "macroman_general_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 40, 1, "cp852", "cp852_general_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 41, 1, "latin7", "latin7_general_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 51, 1, "cp1251", "cp1251_general_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 57, 1, "cp1256", "cp1256_general_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 59, 1, "cp1257", "cp1257_general_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 63, 1, "binary", "binary", "", "", 1, 1, NULL, NULL},
|
||||
{ 92, 1, "geostd8", "geostd8_general_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 95, 1, "cp932", "cp932_japanese_ci", "", "", 1, 2, mysql_mbcharlen_cp932, check_mb_cp932},
|
||||
{ 97, 1, "eucjpms", "eucjpms_japanese_ci", "", "", 1, 3, mysql_mbcharlen_eucjpms, check_mb_eucjpms},
|
||||
{ 2, 1, "latin2", "latin2_czech_cs", "", "", 1, 1, NULL, NULL},
|
||||
{ 5, 1, "latin1", "latin1_german_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 14, 1, "cp1251", "cp1251_bulgarian_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 15, 1, "latin1", "latin1_danish_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 17, 1, "filename", "filename", "", "", 1, 5, NULL, NULL},
|
||||
{ 20, 1, "latin7", "latin7_estonian_cs", "", "", 1, 1, NULL, NULL},
|
||||
{ 21, 1, "latin2", "latin2_hungarian_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 23, 1, "cp1251", "cp1251_ukrainian_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 27, 1, "latin2", "latin2_croatian_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 29, 1, "cp1257", "cp1257_lithunian_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 31, 1, "latin1", "latin1_german2_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 34, 1, "cp1250", "cp1250_czech_cs", "", "", 1, 1, NULL, NULL},
|
||||
{ 42, 1, "latin7", "latin7_general_cs", "", "", 1, 1, NULL, NULL},
|
||||
{ 43, 1, "macce", "macce_bin", "", "", 1, 1, NULL, NULL},
|
||||
{ 44, 1, "cp1250", "cp1250_croatian_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 45, 1, UTF8_MB4, UTF8_MB4"_general_ci", "UTF-8 Unicode", "", 1, 4, mysql_mbcharlen_utf8, check_mb_utf8_valid},
|
||||
{ 46, 1, UTF8_MB4, UTF8_MB4"_bin", "UTF-8 Unicode", "", 1, 4, mysql_mbcharlen_utf8, check_mb_utf8_valid},
|
||||
{ 47, 1, "latin1", "latin1_bin", "", "", 1, 1, NULL, NULL},
|
||||
{ 48, 1, "latin1", "latin1_general_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 49, 1, "latin1", "latin1_general_cs", "", "", 1, 1, NULL, NULL},
|
||||
{ 50, 1, "cp1251", "cp1251_bin", "", "", 1, 1, NULL, NULL},
|
||||
{ 52, 1, "cp1251", "cp1251_general_cs", "", "", 1, 1, NULL, NULL},
|
||||
{ 53, 1, "macroman", "macroman_bin", "", "", 1, 1, NULL, NULL},
|
||||
{ 54, 1, "utf16", "utf16_general_ci", "UTF_16 Unicode", "", 2, 4, mysql_mbcharlen_utf16, check_mb_utf16},
|
||||
{ 55, 1, "utf16", "utf16_bin", "UTF-16 Unicode", "", 2, 4, mysql_mbcharlen_utf16, check_mb_utf16},
|
||||
{ 58, 1, "cp1257", "cp1257_bin", "", "", 1, 1, NULL, NULL},
|
||||
#ifdef USED_TO_BE_SO_BEFORE_MYSQL_5_5
|
||||
{ 60, 1, "armascii8", "armascii8_bin", "", "", 1, 1, NULL, NULL},
|
||||
#endif
|
||||
{ 60, 1, "utf32", "utf32_general_ci", "UTF-32 Unicode", "", 4, 4, mysql_mbcharlen_utf32, check_mb_utf32},
|
||||
{ 61, 1, "utf32", "utf32_bin", "UTF-32 Unicode", "", 4, 4, mysql_mbcharlen_utf32, check_mb_utf32},
|
||||
{ 65, 1, "ascii", "ascii_bin", "", "", 1, 1, NULL, NULL},
|
||||
{ 66, 1, "cp1250", "cp1250_bin", "", "", 1, 1, NULL, NULL},
|
||||
{ 67, 1, "cp1256", "cp1256_bin", "", "", 1, 1, NULL, NULL},
|
||||
{ 68, 1, "cp866", "cp866_bin", "", "", 1, 1, NULL, NULL},
|
||||
{ 69, 1, "dec8", "dec8_bin", "", "", 1, 1, NULL, NULL},
|
||||
{ 70, 1, "greek", "greek_bin", "", "", 1, 1, NULL, NULL},
|
||||
{ 71, 1, "hebew", "hebrew_bin", "", "", 1, 1, NULL, NULL},
|
||||
{ 72, 1, "hp8", "hp8_bin", "", "", 1, 1, NULL, NULL},
|
||||
{ 73, 1, "keybcs2", "keybcs2_bin", "", "", 1, 1, NULL, NULL},
|
||||
{ 74, 1, "koi8r", "koi8r_bin", "", "", 1, 1, NULL, NULL},
|
||||
{ 75, 1, "koi8u", "koi8u_bin", "", "", 1, 1, NULL, NULL},
|
||||
{ 77, 1, "latin2", "latin2_bin", "", "", 1, 1, NULL, NULL},
|
||||
{ 78, 1, "latin5", "latin5_bin", "", "", 1, 1, NULL, NULL},
|
||||
{ 79, 1, "latin7", "latin7_bin", "", "", 1, 1, NULL, NULL},
|
||||
{ 80, 1, "cp850", "cp850_bin", "", "", 1, 1, NULL, NULL},
|
||||
{ 81, 1, "cp852", "cp852_bin", "", "", 1, 1, NULL, NULL},
|
||||
{ 82, 1, "swe7", "swe7_bin", "", "", 1, 1, NULL, NULL},
|
||||
{ 93, 1, "geostd8", "geostd8_bin", "", "", 1, 1, NULL, NULL},
|
||||
{ 83, 1, UTF8_MB3, UTF8_MB3"_bin", "UTF-8 Unicode", "", 1, 3, mysql_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
|
||||
{ 84, 1, "big5", "big5_bin", "", "", 1, 2, mysql_mbcharlen_big5, check_mb_big5},
|
||||
{ 85, 1, "euckr", "euckr_bin", "", "", 1, 2, mysql_mbcharlen_euckr, check_mb_euckr},
|
||||
{ 86, 1, "gb2312", "gb2312_bin", "", "", 1, 2, mysql_mbcharlen_gb2312, check_mb_gb2312},
|
||||
{ 87, 1, "gbk", "gbk_bin", "", "", 1, 2, mysql_mbcharlen_gbk, check_mb_gbk},
|
||||
{ 88, 1, "sjis", "sjis_bin", "", "", 1, 2, mysql_mbcharlen_sjis, check_mb_sjis},
|
||||
{ 89, 1, "tis620", "tis620_bin", "", "", 1, 1, NULL, NULL},
|
||||
{ 90, 1, "ucs2", "ucs2_bin", "UCS-2 Unicode", "", 2, 2, mysql_mbcharlen_ucs2, check_mb_ucs2},
|
||||
{ 91, 1, "ujis", "ujis_bin", "", "", 1, 3, mysql_mbcharlen_ujis, check_mb_ujis},
|
||||
{ 94, 1, "latin1", "latin1_spanish_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 96, 1, "cp932", "cp932_bin", "", "", 1, 2, mysql_mbcharlen_cp932, check_mb_cp932},
|
||||
{ 99, 1, "cp1250", "cp1250_polish_ci", "", "", 1, 1, NULL, NULL},
|
||||
{ 98, 1, "eucjpms", "eucjpms_bin", "", "", 1, 3, mysql_mbcharlen_eucjpms, check_mb_eucjpms},
|
||||
{ 128, 1, "ucs2", "ucs2_unicode_ci", "", "", 2, 2, mysql_mbcharlen_ucs2, check_mb_ucs2},
|
||||
{ 129, 1, "ucs2", "ucs2_icelandic_ci", "", "", 2, 2, mysql_mbcharlen_ucs2, check_mb_ucs2},
|
||||
{ 130, 1, "ucs2", "ucs2_latvian_ci", "", "", 2, 2, mysql_mbcharlen_ucs2, check_mb_ucs2},
|
||||
{ 131, 1, "ucs2", "ucs2_romanian_ci", "", "", 2, 2, mysql_mbcharlen_ucs2, check_mb_ucs2},
|
||||
{ 132, 1, "ucs2", "ucs2_slovenian_ci", "", "", 2, 2, mysql_mbcharlen_ucs2, check_mb_ucs2},
|
||||
{ 133, 1, "ucs2", "ucs2_polish_ci", "", "", 2, 2, mysql_mbcharlen_ucs2, check_mb_ucs2},
|
||||
{ 134, 1, "ucs2", "ucs2_estonian_ci", "", "", 2, 2, mysql_mbcharlen_ucs2, check_mb_ucs2},
|
||||
{ 135, 1, "ucs2", "ucs2_spanish_ci", "", "", 2, 2, mysql_mbcharlen_ucs2, check_mb_ucs2},
|
||||
{ 136, 1, "ucs2", "ucs2_swedish_ci", "", "", 2, 2, mysql_mbcharlen_ucs2, check_mb_ucs2},
|
||||
{ 137, 1, "ucs2", "ucs2_turkish_ci", "", "", 2, 2, mysql_mbcharlen_ucs2, check_mb_ucs2},
|
||||
{ 138, 1, "ucs2", "ucs2_czech_ci", "", "", 2, 2, mysql_mbcharlen_ucs2, check_mb_ucs2},
|
||||
{ 139, 1, "ucs2", "ucs2_danish_ci", "", "", 2, 2, mysql_mbcharlen_ucs2, check_mb_ucs2},
|
||||
{ 140, 1, "ucs2", "ucs2_lithunian_ci", "", "", 2, 2, mysql_mbcharlen_ucs2, check_mb_ucs2},
|
||||
{ 141, 1, "ucs2", "ucs2_slovak_ci", "", "", 2, 2, mysql_mbcharlen_ucs2, check_mb_ucs2},
|
||||
{ 142, 1, "ucs2", "ucs2_spanish2_ci", "", "", 2, 2, mysql_mbcharlen_ucs2, check_mb_ucs2},
|
||||
{ 143, 1, "ucs2", "ucs2_roman_ci", "", "", 2, 2, mysql_mbcharlen_ucs2, check_mb_ucs2},
|
||||
{ 144, 1, "ucs2", "ucs2_persian_ci", "", "", 2, 2, mysql_mbcharlen_ucs2, check_mb_ucs2},
|
||||
{ 145, 1, "ucs2", "ucs2_esperanto_ci", "", "", 2, 2, mysql_mbcharlen_ucs2, check_mb_ucs2},
|
||||
{ 146, 1, "ucs2", "ucs2_hungarian_ci", "", "", 2, 2, mysql_mbcharlen_ucs2, check_mb_ucs2},
|
||||
{ 147, 1, "ucs2", "ucs2_sinhala_ci", "", "", 2, 2, mysql_mbcharlen_ucs2, check_mb_ucs2},
|
||||
{ 149, 1, "ucs2", "ucs2_croatian_ci", "", "", 2, 2, mysql_mbcharlen_ucs2, check_mb_ucs2}, /* MDB */
|
||||
|
||||
{ 192, 1, UTF8_MB3, UTF8_MB3"_general_ci", "", "", 1, 3, mysql_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
|
||||
{ 193, 1, UTF8_MB3, UTF8_MB3"_icelandic_ci", "", "", 1, 3, mysql_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
|
||||
{ 194, 1, UTF8_MB3, UTF8_MB3"_latvian_ci", "", "", 1, 3, mysql_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
|
||||
{ 195, 1, UTF8_MB3, UTF8_MB3"_romanian_ci", "", "", 1, 3, mysql_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
|
||||
{ 196, 1, UTF8_MB3, UTF8_MB3"_slovenian_ci", "", "", 1, 3, mysql_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
|
||||
{ 197, 1, UTF8_MB3, UTF8_MB3"_polish_ci", "", "", 1, 3, mysql_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
|
||||
{ 198, 1, UTF8_MB3, UTF8_MB3"_estonian_ci", "", "", 1, 3, mysql_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
|
||||
{ 119, 1, UTF8_MB3, UTF8_MB3"_spanish_ci", "", "", 1, 3, mysql_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
|
||||
{ 200, 1, UTF8_MB3, UTF8_MB3"_swedish_ci", "", "", 1, 3, mysql_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
|
||||
{ 201, 1, UTF8_MB3, UTF8_MB3"_turkish_ci", "", "", 1, 3, mysql_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
|
||||
{ 202, 1, UTF8_MB3, UTF8_MB3"_czech_ci", "", "", 1, 3, mysql_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
|
||||
{ 203, 1, UTF8_MB3, UTF8_MB3"_danish_ci", "", "", 1, 3, mysql_mbcharlen_utf8mb3, check_mb_utf8mb3_valid },
|
||||
{ 204, 1, UTF8_MB3, UTF8_MB3"_lithunian_ci", "", "", 1, 3, mysql_mbcharlen_utf8mb3, check_mb_utf8mb3_valid },
|
||||
{ 205, 1, UTF8_MB3, UTF8_MB3"_slovak_ci", "", "", 1, 3, mysql_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
|
||||
{ 206, 1, UTF8_MB3, UTF8_MB3"_spanish2_ci", "", "", 1, 3, mysql_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
|
||||
{ 207, 1, UTF8_MB3, UTF8_MB3"_roman_ci", "", "", 1, 3, mysql_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
|
||||
{ 208, 1, UTF8_MB3, UTF8_MB3"_persian_ci", "", "", 1, 3, mysql_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
|
||||
{ 209, 1, UTF8_MB3, UTF8_MB3"_esperanto_ci", "", "", 1, 3, mysql_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
|
||||
{ 210, 1, UTF8_MB3, UTF8_MB3"_hungarian_ci", "", "", 1, 3, mysql_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
|
||||
{ 211, 1, UTF8_MB3, UTF8_MB3"_sinhala_ci", "", "", 1, 3, mysql_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
|
||||
{ 213, 1, UTF8_MB3, UTF8_MB3"_croatian_ci", "", "", 1, 3, mysql_mbcharlen_utf8mb3, check_mb_utf8mb3_valid}, /*MDB*/
|
||||
|
||||
{ 224, 1, UTF8_MB4, UTF8_MB4"_unicode_ci", "", "", 1, 4, mysql_mbcharlen_utf8, check_mb_utf8_valid},
|
||||
{ 225, 1, UTF8_MB4, UTF8_MB4"_icelandic_ci", "", "", 1, 4, mysql_mbcharlen_utf8, check_mb_utf8_valid},
|
||||
{ 226, 1, UTF8_MB4, UTF8_MB4"_latvian_ci", "", "", 1, 4, mysql_mbcharlen_utf8, check_mb_utf8_valid},
|
||||
{ 227, 1, UTF8_MB4, UTF8_MB4"_romanian_ci", "", "", 1, 4, mysql_mbcharlen_utf8, check_mb_utf8_valid},
|
||||
{ 228, 1, UTF8_MB4, UTF8_MB4"_slovenian_ci", "", "", 1, 4, mysql_mbcharlen_utf8, check_mb_utf8_valid},
|
||||
{ 229, 1, UTF8_MB4, UTF8_MB4"_polish_ci", "", "", 1, 4, mysql_mbcharlen_utf8, check_mb_utf8_valid},
|
||||
{ 230, 1, UTF8_MB4, UTF8_MB4"_estonian_ci", "", "", 1, 4, mysql_mbcharlen_utf8, check_mb_utf8_valid},
|
||||
{ 231, 1, UTF8_MB4, UTF8_MB4"_spanish_ci", "", "", 1, 4, mysql_mbcharlen_utf8, check_mb_utf8_valid},
|
||||
{ 232, 1, UTF8_MB4, UTF8_MB4"_swedish_ci", "", "", 1, 4, mysql_mbcharlen_utf8, check_mb_utf8_valid},
|
||||
{ 233, 1, UTF8_MB4, UTF8_MB4"_turkish_ci", "", "", 1, 4, mysql_mbcharlen_utf8, check_mb_utf8_valid},
|
||||
{ 234, 1, UTF8_MB4, UTF8_MB4"_czech_ci", "", "", 1, 4, mysql_mbcharlen_utf8, check_mb_utf8_valid},
|
||||
{ 235, 1, UTF8_MB4, UTF8_MB4"_danish_ci", "", "", 1, 4, mysql_mbcharlen_utf8, check_mb_utf8_valid},
|
||||
{ 236, 1, UTF8_MB4, UTF8_MB4"_lithuanian_ci", "", "", 1, 4, mysql_mbcharlen_utf8, check_mb_utf8_valid},
|
||||
{ 237, 1, UTF8_MB4, UTF8_MB4"_slovak_ci", "", "", 1, 4, mysql_mbcharlen_utf8, check_mb_utf8_valid},
|
||||
{ 238, 1, UTF8_MB4, UTF8_MB4"_spanish2_ci", "", "", 1, 4, mysql_mbcharlen_utf8, check_mb_utf8_valid},
|
||||
{ 239, 1, UTF8_MB4, UTF8_MB4"_roman_ci", "", "", 1, 4, mysql_mbcharlen_utf8, check_mb_utf8_valid},
|
||||
{ 240, 1, UTF8_MB4, UTF8_MB4"_persian_ci", "", "", 1, 4, mysql_mbcharlen_utf8, check_mb_utf8_valid},
|
||||
{ 241, 1, UTF8_MB4, UTF8_MB4"_esperanto_ci", "", "", 1, 4, mysql_mbcharlen_utf8, check_mb_utf8_valid},
|
||||
{ 242, 1, UTF8_MB4, UTF8_MB4"_hungarian_ci", "", "", 1, 4, mysql_mbcharlen_utf8, check_mb_utf8_valid},
|
||||
{ 243, 1, UTF8_MB4, UTF8_MB4"_sinhala_ci", "", "", 1, 4, mysql_mbcharlen_utf8, check_mb_utf8_valid},
|
||||
|
||||
{ 254, 1, UTF8_MB3, UTF8_MB3"_general_cs", "", "", 1, 3, mysql_mbcharlen_utf8, check_mb_utf8_valid},
|
||||
{ 0, 0, NULL, NULL, NULL, NULL, 0, 0, NULL, NULL}
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysql_find_charset_nr */
|
||||
const CHARSET_INFO * mysql_find_charset_nr(unsigned int charsetnr)
|
||||
{
|
||||
const CHARSET_INFO * c = compiled_charsets;
|
||||
DBUG_ENTER("mysql_find_charset_nr");
|
||||
|
||||
do {
|
||||
if (c->nr == charsetnr) {
|
||||
DBUG_PRINT("info", ("found character set %d %s", c->nr, c->csname));
|
||||
DBUG_RETURN(c);
|
||||
}
|
||||
++c;
|
||||
} while (c[0].nr != 0);
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysql_find_charset_name */
|
||||
CHARSET_INFO * mysql_find_charset_name(const char *name)
|
||||
{
|
||||
CHARSET_INFO *c = (CHARSET_INFO *)compiled_charsets;
|
||||
DBUG_ENTER("mysql_find_charset_nr");
|
||||
|
||||
do {
|
||||
if (!strcasecmp(c->csname, name)) {
|
||||
DBUG_PRINT("info", ("found character set %d %s", c->nr, c->csname));
|
||||
DBUG_RETURN(c);
|
||||
}
|
||||
++c;
|
||||
} while (c[0].nr != 0);
|
||||
return NULL;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysql_cset_escape_quotes */
|
||||
size_t mysql_cset_escape_quotes(const CHARSET_INFO *cset, char *newstr,
|
||||
const char * escapestr, size_t escapestr_len )
|
||||
{
|
||||
const char *newstr_s = newstr;
|
||||
const char *newstr_e = newstr + 2 * escapestr_len;
|
||||
const char *end = escapestr + escapestr_len;
|
||||
my_bool escape_overflow = FALSE;
|
||||
|
||||
DBUG_ENTER("mysql_cset_escape_quotes");
|
||||
|
||||
for (;escapestr < end; escapestr++) {
|
||||
unsigned int len = 0;
|
||||
/* check unicode characters */
|
||||
|
||||
if (cset->char_maxlen > 1 && (len = cset->mb_valid(escapestr, end))) {
|
||||
|
||||
/* check possible overflow */
|
||||
if ((newstr + len) > newstr_e) {
|
||||
escape_overflow = TRUE;
|
||||
break;
|
||||
}
|
||||
/* copy mb char without escaping it */
|
||||
while (len--) {
|
||||
*newstr++ = *escapestr++;
|
||||
}
|
||||
escapestr--;
|
||||
continue;
|
||||
}
|
||||
if (*escapestr == '\'') {
|
||||
if (newstr + 2 > newstr_e) {
|
||||
escape_overflow = TRUE;
|
||||
break;
|
||||
}
|
||||
*newstr++ = '\'';
|
||||
*newstr++ = '\'';
|
||||
} else {
|
||||
if (newstr + 1 > newstr_e) {
|
||||
escape_overflow = TRUE;
|
||||
break;
|
||||
}
|
||||
*newstr++ = *escapestr;
|
||||
}
|
||||
}
|
||||
*newstr = '\0';
|
||||
|
||||
if (escape_overflow) {
|
||||
DBUG_RETURN((size_t)~0);
|
||||
}
|
||||
DBUG_RETURN((size_t)(newstr - newstr_s));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysql_cset_escape_slashes */
|
||||
size_t mysql_cset_escape_slashes(const CHARSET_INFO * cset, char *newstr,
|
||||
const char * escapestr, size_t escapestr_len )
|
||||
{
|
||||
const char *newstr_s = newstr;
|
||||
const char *newstr_e = newstr + 2 * escapestr_len;
|
||||
const char *end = escapestr + escapestr_len;
|
||||
my_bool escape_overflow = FALSE;
|
||||
|
||||
DBUG_ENTER("mysql_cset_escape_slashes");
|
||||
DBUG_PRINT("info", ("charset=%s", cset->name));
|
||||
|
||||
for (;escapestr < end; escapestr++) {
|
||||
char esc = '\0';
|
||||
unsigned int len = 0;
|
||||
|
||||
/* check unicode characters */
|
||||
if (cset->char_maxlen > 1 && (len = cset->mb_valid(escapestr, end))) {
|
||||
/* check possible overflow */
|
||||
if ((newstr + len) > newstr_e) {
|
||||
escape_overflow = TRUE;
|
||||
break;
|
||||
}
|
||||
/* copy mb char without escaping it */
|
||||
while (len--) {
|
||||
*newstr++ = *escapestr++;
|
||||
}
|
||||
escapestr--;
|
||||
continue;
|
||||
}
|
||||
if (cset->char_maxlen > 1 && cset->mb_charlen(*escapestr) > 1) {
|
||||
esc = *escapestr;
|
||||
} else {
|
||||
switch (*escapestr) {
|
||||
case 0:
|
||||
esc = '0';
|
||||
break;
|
||||
case '\n':
|
||||
esc = 'n';
|
||||
break;
|
||||
case '\r':
|
||||
esc = 'r';
|
||||
break;
|
||||
case '\\':
|
||||
case '\'':
|
||||
case '"':
|
||||
esc = *escapestr;
|
||||
break;
|
||||
case '\032':
|
||||
esc = 'Z';
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (esc) {
|
||||
if (newstr + 2 > newstr_e) {
|
||||
escape_overflow = TRUE;
|
||||
break;
|
||||
}
|
||||
/* copy escaped character */
|
||||
*newstr++ = '\\';
|
||||
*newstr++ = esc;
|
||||
} else {
|
||||
if (newstr + 1 > newstr_e) {
|
||||
escape_overflow = TRUE;
|
||||
break;
|
||||
}
|
||||
/* copy non escaped character */
|
||||
*newstr++ = *escapestr;
|
||||
}
|
||||
}
|
||||
*newstr = '\0';
|
||||
|
||||
if (escape_overflow) {
|
||||
DBUG_RETURN((size_t)~0);
|
||||
}
|
||||
DBUG_RETURN((size_t)(newstr - newstr_s));
|
||||
}
|
||||
/* }}} */
|
@ -20,7 +20,7 @@
|
||||
#include <my_dir.h>
|
||||
#include "mysys_err.h"
|
||||
#include <errno.h>
|
||||
#if defined(MSDOS) || defined(__WIN__) || defined(__EMX__) || defined(OS2)
|
||||
#if defined(MSDOS) || defined(_WIN32) || defined(__EMX__) || defined(OS2)
|
||||
#include <share.h>
|
||||
#endif
|
||||
|
||||
@ -48,7 +48,7 @@ File my_create(const char *FileName, int CreateFlags, int access_flags,
|
||||
#elif defined(VMS)
|
||||
fd = open((my_string) FileName, access_flags | O_CREAT, 0,
|
||||
"ctx=stm","ctx=bin");
|
||||
#elif defined(MSDOS) || defined(__WIN__) || defined(__EMX__) || defined(OS2)
|
||||
#elif defined(MSDOS) || defined(_WIN32) || defined(__EMX__) || defined(OS2)
|
||||
if (access_flags & O_SHARE)
|
||||
fd = sopen((my_string) FileName, access_flags | O_CREAT | O_BINARY,
|
||||
SH_DENYNO, MY_S_IREAD | MY_S_IWRITE);
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include <assert.h>
|
||||
#if !defined(MSDOS) && !defined(__WIN__)
|
||||
#if !defined(MSDOS) && !defined(_WIN32)
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#include <my_net.h>
|
||||
|
@ -23,7 +23,7 @@
|
||||
#ifdef HAVE_GETWD
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
#if defined(MSDOS) || defined(__WIN__)
|
||||
#if defined(MSDOS) || defined(_WIN32)
|
||||
#include <m_ctype.h>
|
||||
#include <dos.h>
|
||||
#include <direct.h>
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include <my_static.c>
|
||||
#include <m_ctype.h>
|
||||
#endif
|
||||
#ifdef __WIN__
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
#include <locale.h>
|
||||
#include <crtdbg.h>
|
||||
@ -72,7 +72,7 @@ void my_init(void)
|
||||
pthread_init(); /* Must be called before DBUG_ENTER */
|
||||
#endif
|
||||
my_thread_global_init();
|
||||
#if !defined( __WIN__) && !defined(OS2)
|
||||
#ifndef _WIN32
|
||||
sigfillset(&my_signals); /* signals blocked by mf_brkhant */
|
||||
#endif
|
||||
#endif /* THREAD */
|
||||
@ -100,7 +100,7 @@ void my_init(void)
|
||||
#endif
|
||||
DBUG_PRINT("exit",("home: '%s'",home_dir));
|
||||
}
|
||||
#ifdef __WIN__
|
||||
#ifdef _WIN32
|
||||
win32_init_tcp_ip();
|
||||
#endif
|
||||
DBUG_VOID_RETURN;
|
||||
@ -145,12 +145,12 @@ Voluntary context switches %ld, Involuntary context switches %ld\n",
|
||||
rus.ru_msgsnd, rus.ru_msgrcv, rus.ru_nsignals,
|
||||
rus.ru_nvcsw, rus.ru_nivcsw);
|
||||
#endif
|
||||
#if defined(MSDOS) && !defined(__WIN__)
|
||||
#if defined(MSDOS) && !defined(_WIN32)
|
||||
fprintf(info_file,"\nRun time: %.1f\n",(double) clock()/CLOCKS_PER_SEC);
|
||||
#endif
|
||||
#if defined(SAFEMALLOC)
|
||||
TERMINATE(stderr); /* Give statistic on screen */
|
||||
#elif defined(__WIN__) && defined(_MSC_VER)
|
||||
#elif defined(_WIN32) && defined(_MSC_VER)
|
||||
_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
|
||||
_CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDERR );
|
||||
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
|
||||
@ -169,14 +169,14 @@ Voluntary context switches %ld, Involuntary context switches %ld\n",
|
||||
my_thread_end();
|
||||
my_thread_global_end();
|
||||
#endif
|
||||
#ifdef __WIN__
|
||||
#ifdef _WIN32
|
||||
if (have_tcpip);
|
||||
WSACleanup( );
|
||||
#endif /* __WIN__ */
|
||||
#endif /* _WIN32 */
|
||||
my_init_done=0;
|
||||
} /* my_end */
|
||||
|
||||
#ifdef __WIN__
|
||||
#ifdef _WIN32
|
||||
|
||||
/*
|
||||
This code is specially for running MySQL, but it should work in
|
||||
|
@ -40,7 +40,7 @@
|
||||
# if defined(HAVE_NDIR_H)
|
||||
# include <ndir.h>
|
||||
# endif
|
||||
# if defined(MSDOS) || defined(__WIN__)
|
||||
# if defined(MSDOS) || defined(_WIN32)
|
||||
# include <dos.h>
|
||||
# ifdef __BORLANDC__
|
||||
# include <dir.h>
|
||||
@ -88,7 +88,7 @@ static int comp_names(struct fileinfo *a, struct fileinfo *b)
|
||||
} /* comp_names */
|
||||
|
||||
|
||||
#if !defined(MSDOS) && !defined(__WIN__)
|
||||
#if !defined(MSDOS) && !defined(_WIN32)
|
||||
|
||||
MY_DIR *my_dir(const char *path, myf MyFlags)
|
||||
{
|
||||
@ -336,7 +336,7 @@ my_string directory_file_name (my_string dst, const char *src)
|
||||
#endif /* VMS */
|
||||
} /* directory_file_name */
|
||||
|
||||
#elif defined(__WIN__)
|
||||
#elif defined(_WIN32)
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
|
255
libmysql/my_loaddata.c
Normal file
255
libmysql/my_loaddata.c
Normal file
@ -0,0 +1,255 @@
|
||||
/************************************************************************************
|
||||
Copyright (C) 2000, 2011 MySQL AB & MySQL Finland AB & TCX DataKonsult AB,
|
||||
Monty Program 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 see <http://www.gnu.org/licenses>
|
||||
or write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St., Fifth Floor, Boston, MA 02110, USA
|
||||
|
||||
Part of this code includes code from the PHP project which
|
||||
is freely available from http://www.php.net
|
||||
*************************************************************************************/
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 2006-2011 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Georg Richter <georg@mysql.com> |
|
||||
| Andrey Hristov <andrey@mysql.com> |
|
||||
| Ulf Wendel <uwendel@mysql.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "my_global.h"
|
||||
#include <my_sys.h>
|
||||
#include <mysys_err.h>
|
||||
#include <m_string.h>
|
||||
#include "errmsg.h"
|
||||
#include "mysql.h"
|
||||
#include <string.h>
|
||||
|
||||
typedef struct st_mysql_infile_info
|
||||
{
|
||||
int fd;
|
||||
int error_no;
|
||||
char error_msg[MYSQL_ERRMSG_SIZE + 1];
|
||||
const char *filename;
|
||||
} MYSQL_INFILE_INFO;
|
||||
|
||||
/* {{{ mysql_local_infile_init */
|
||||
static
|
||||
int mysql_local_infile_init(void **ptr, const char *filename, void *userdata)
|
||||
{
|
||||
MYSQL_INFILE_INFO *info;
|
||||
|
||||
DBUG_ENTER("mysql_local_infile_init");
|
||||
|
||||
info = (MYSQL_INFILE_INFO *)my_malloc(sizeof(MYSQL_INFILE_INFO), MYF(MY_ZEROFILL));
|
||||
if (!info) {
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
*ptr = info;
|
||||
|
||||
info->filename = filename;
|
||||
info->fd = my_open(info->filename, O_RDONLY, MYF(0));
|
||||
|
||||
if (info->fd < 0)
|
||||
{
|
||||
my_snprintf((char *)info->error_msg, sizeof(info->error_msg),
|
||||
"Can't open file '%-.64s'.", filename);
|
||||
info->error_no = EE_FILENOTFOUND;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysql_local_infile_read */
|
||||
static
|
||||
int mysql_local_infile_read(void *ptr, char * buf, unsigned int buf_len)
|
||||
{
|
||||
MYSQL_INFILE_INFO *info = (MYSQL_INFILE_INFO *)ptr;
|
||||
int count;
|
||||
|
||||
DBUG_ENTER("mysql_local_infile_read");
|
||||
|
||||
count= my_read(info->fd, buf, buf_len, MYF(0));
|
||||
|
||||
if (count < 0)
|
||||
{
|
||||
strcpy(info->error_msg, "Error reading file");
|
||||
info->error_no = EE_READ;
|
||||
}
|
||||
DBUG_RETURN(count);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysql_local_infile_error */
|
||||
static
|
||||
int mysql_local_infile_error(void *ptr, char *error_buf, unsigned int error_buf_len)
|
||||
{
|
||||
MYSQL_INFILE_INFO *info = (MYSQL_INFILE_INFO *)ptr;
|
||||
|
||||
DBUG_ENTER("mysql_local_infile_error");
|
||||
|
||||
if (info) {
|
||||
strncpy(error_buf, info->error_msg, error_buf_len);
|
||||
DBUG_RETURN(info->error_no);
|
||||
}
|
||||
|
||||
strncpy(error_buf, "Unknown error", error_buf_len);
|
||||
DBUG_RETURN(CR_UNKNOWN_ERROR);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysql_local_infile_end */
|
||||
static
|
||||
void mysql_local_infile_end(void *ptr)
|
||||
{
|
||||
MYSQL_INFILE_INFO *info = (MYSQL_INFILE_INFO *)ptr;
|
||||
|
||||
DBUG_ENTER("mysql_local_infile_end");
|
||||
|
||||
if (info)
|
||||
{
|
||||
if (info->fd)
|
||||
{
|
||||
my_close(info->fd, MYF(0));
|
||||
info->fd= 0;
|
||||
}
|
||||
my_free(ptr, MYF(0));
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysql_local_infile_default */
|
||||
void mysql_set_local_infile_default(MYSQL *conn)
|
||||
{
|
||||
DBUG_ENTER("mysql_local_infile_default");
|
||||
conn->options.local_infile_init = mysql_local_infile_init;
|
||||
conn->options.local_infile_read = mysql_local_infile_read;
|
||||
conn->options.local_infile_error = mysql_local_infile_error;
|
||||
conn->options.local_infile_end = mysql_local_infile_end;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mysql_set_local_infile_handler */
|
||||
void STDCALL mysql_set_local_infile_handler(MYSQL *conn,
|
||||
int (*local_infile_init)(void **, const char *, void *),
|
||||
int (*local_infile_read)(void *, char *, uint),
|
||||
void (*local_infile_end)(void *),
|
||||
int (*local_infile_error)(void *, char *, uint),
|
||||
void *userdata)
|
||||
{
|
||||
DBUG_ENTER("mysql_set_local_infile_handler");
|
||||
conn->options.local_infile_init= local_infile_init;
|
||||
conn->options.local_infile_read= local_infile_read;
|
||||
conn->options.local_infile_end= local_infile_end;
|
||||
conn->options.local_infile_error= local_infile_error;
|
||||
conn->options.local_infile_userdata = userdata;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mysql_handle_local_infile */
|
||||
my_bool mysql_handle_local_infile(MYSQL *conn, const char *filename)
|
||||
{
|
||||
unsigned int buflen= 4096;
|
||||
unsigned int bufread;
|
||||
unsigned char *buf= NULL;
|
||||
void *info= NULL;
|
||||
my_bool result= 1;
|
||||
|
||||
DBUG_ENTER("mysql_handle_local_infile");
|
||||
|
||||
if (!(conn->options.client_flag & CLIENT_LOCAL_FILES)) {
|
||||
my_set_error(conn, CR_UNKNOWN_ERROR, SQLSTATE_UNKNOWN, "Load data local infile forbidden");
|
||||
/* write empty packet to server */
|
||||
my_net_write(&conn->net, "", 0);
|
||||
net_flush(&conn->net);
|
||||
goto infile_error;
|
||||
}
|
||||
|
||||
/* check if all callback functions exist */
|
||||
if (!conn->options.local_infile_init || !conn->options.local_infile_end ||
|
||||
!conn->options.local_infile_read || !conn->options.local_infile_error)
|
||||
mysql_set_local_infile_default(conn);
|
||||
|
||||
/* allocate buffer for reading data */
|
||||
buf = (uchar *)my_malloc(buflen, MYF(0));
|
||||
|
||||
/* init handler: allocate read buffer and open file */
|
||||
if (conn->options.local_infile_init(&info, filename,
|
||||
conn->options.local_infile_userdata))
|
||||
{
|
||||
char tmp_buf[MYSQL_ERRMSG_SIZE];
|
||||
int tmp_errno;
|
||||
|
||||
tmp_errno= conn->options.local_infile_error(info, tmp_buf, sizeof(tmp_buf));
|
||||
my_set_error(conn, tmp_errno, SQLSTATE_UNKNOWN, tmp_buf);
|
||||
my_net_write(&conn->net, "", 0);
|
||||
net_flush(&conn->net);
|
||||
goto infile_error;
|
||||
}
|
||||
|
||||
/* read data */
|
||||
while ((bufread= conn->options.local_infile_read(info, (char *)buf, buflen)) > 0)
|
||||
{
|
||||
if (my_net_write(&conn->net, (char *)buf, bufread))
|
||||
{
|
||||
my_set_error(conn, CR_SERVER_LOST, SQLSTATE_UNKNOWN, NULL);
|
||||
goto infile_error;
|
||||
}
|
||||
}
|
||||
|
||||
/* send empty packet for eof */
|
||||
if (my_net_write(&conn->net, "", 0) || net_flush(&conn->net))
|
||||
{
|
||||
my_set_error(conn, CR_SERVER_LOST, SQLSTATE_UNKNOWN, NULL);
|
||||
goto infile_error;
|
||||
}
|
||||
|
||||
/* error during read occured */
|
||||
if (bufread < 0)
|
||||
{
|
||||
char tmp_buf[MYSQL_ERRMSG_SIZE];
|
||||
int tmp_errno= conn->options.local_infile_error(info, tmp_buf, sizeof(tmp_buf));
|
||||
my_set_error(conn, tmp_errno, SQLSTATE_UNKNOWN, tmp_buf);
|
||||
goto infile_error;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
|
||||
infile_error:
|
||||
conn->options.local_infile_end(info);
|
||||
my_free((char *)buf, MYF(0));
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
/* }}} */
|
@ -25,7 +25,7 @@
|
||||
|
||||
/* My memory allocator */
|
||||
|
||||
gptr my_malloc(unsigned int Size, myf MyFlags)
|
||||
gptr my_malloc(size_t Size, myf MyFlags)
|
||||
{
|
||||
gptr point;
|
||||
DBUG_ENTER("my_malloc");
|
||||
@ -65,7 +65,7 @@ void my_no_flags_free(gptr ptr)
|
||||
|
||||
/* malloc and copy */
|
||||
|
||||
gptr my_memdup(const byte *from, uint length, myf MyFlags)
|
||||
gptr my_memdup(const byte *from, size_t length, myf MyFlags)
|
||||
{
|
||||
gptr ptr;
|
||||
if ((ptr=my_malloc(length,MyFlags)) != 0)
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <m_string.h>
|
||||
|
||||
/* for thread safe my_inet_ntoa */
|
||||
#if !defined(MSDOS) && !defined(__WIN__)
|
||||
#if !defined(MSDOS) && !defined(_WIN32)
|
||||
#include <netdb.h>
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
@ -32,7 +32,7 @@
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#endif /* !defined(MSDOS) && !defined(__WIN__) */
|
||||
#endif /* !defined(MSDOS) && !defined(_WIN32) */
|
||||
|
||||
void my_inet_ntoa(struct in_addr in, char *buf)
|
||||
{
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
gptr my_once_alloc(unsigned int Size, myf MyFlags)
|
||||
{
|
||||
uint get_size,max_left;
|
||||
size_t get_size,max_left;
|
||||
gptr point;
|
||||
reg1 USED_MEM *next;
|
||||
reg2 USED_MEM **prev;
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include "mysys_err.h"
|
||||
#include <my_dir.h>
|
||||
#include <errno.h>
|
||||
#if defined(MSDOS) || defined(__WIN__) || defined(__EMX__) || defined(OS2)
|
||||
#if defined(MSDOS) || defined(_WIN32) || defined(__EMX__) || defined(OS2)
|
||||
#include <share.h>
|
||||
#endif
|
||||
|
||||
@ -35,7 +35,7 @@ File my_open(const char *FileName, int Flags, myf MyFlags)
|
||||
DBUG_ENTER("my_open");
|
||||
DBUG_PRINT("my",("Name: '%s' Flags: %d MyFlags: %d",
|
||||
FileName, Flags, MyFlags));
|
||||
#if defined(MSDOS) || defined(__WIN__) || defined(__EMX__) || defined(OS2)
|
||||
#if defined(MSDOS) || defined(_WIN32) || defined(__EMX__) || defined(OS2)
|
||||
if (Flags & O_SHARE)
|
||||
fd = sopen((my_string) FileName, (Flags & ~O_SHARE) | O_BINARY, SH_DENYNO,
|
||||
MY_S_IREAD | MY_S_IWRITE);
|
||||
|
@ -1,146 +0,0 @@
|
||||
/* 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 */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include "mysys_err.h"
|
||||
#include <errno.h>
|
||||
#ifdef HAVE_PREAD
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
/* Read a chunk of bytes from a file */
|
||||
|
||||
uint my_pread(File Filedes, byte *Buffer, uint Count, my_off_t offset,
|
||||
myf MyFlags)
|
||||
{
|
||||
uint readbytes;
|
||||
int error;
|
||||
DBUG_ENTER("my_pread");
|
||||
DBUG_PRINT("my",("Fd: %d Seek: %lu Buffer: %lx Count: %u MyFlags: %d",
|
||||
Filedes, (ulong) offset, Buffer, Count, MyFlags));
|
||||
|
||||
for (;;)
|
||||
{
|
||||
#ifndef __WIN__
|
||||
errno=0; /* Linux doesn't reset this */
|
||||
#endif
|
||||
#ifndef HAVE_PREAD
|
||||
pthread_mutex_lock(&my_file_info[Filedes].mutex);
|
||||
readbytes= (uint) -1;
|
||||
error= (lseek(Filedes, offset, MY_SEEK_SET) == -1L ||
|
||||
(readbytes = (uint) read(Filedes, Buffer, Count)) != Count);
|
||||
pthread_mutex_unlock(&my_file_info[Filedes].mutex);
|
||||
#else
|
||||
error=((readbytes = (uint) pread(Filedes, Buffer, Count, offset)) != Count);
|
||||
#endif
|
||||
if (error)
|
||||
{
|
||||
my_errno=errno;
|
||||
DBUG_PRINT("warning",("Read only %ld bytes off %ld from %d, errno: %d",
|
||||
readbytes,Count,Filedes,my_errno));
|
||||
#ifdef THREAD
|
||||
if (readbytes == 0 && errno == EINTR)
|
||||
continue; /* Interrupted */
|
||||
#endif
|
||||
if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
|
||||
{
|
||||
if ((int) readbytes == -1)
|
||||
my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG),
|
||||
my_filename(Filedes),my_errno);
|
||||
else if (MyFlags & (MY_NABP | MY_FNABP))
|
||||
my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG),
|
||||
my_filename(Filedes),my_errno);
|
||||
}
|
||||
if ((int) readbytes == -1 || (MyFlags & (MY_FNABP | MY_NABP)))
|
||||
DBUG_RETURN(MY_FILE_ERROR); /* Return with error */
|
||||
}
|
||||
if (MyFlags & (MY_NABP | MY_FNABP))
|
||||
DBUG_RETURN(0); /* Read went ok; Return 0 */
|
||||
DBUG_RETURN(readbytes); /* purecov: inspected */
|
||||
}
|
||||
} /* my_pread */
|
||||
|
||||
|
||||
/* Write a chunk of bytes to a file */
|
||||
|
||||
uint my_pwrite(int Filedes, const byte *Buffer, uint Count, my_off_t offset,
|
||||
myf MyFlags)
|
||||
{
|
||||
uint writenbytes,errors;
|
||||
ulong written;
|
||||
DBUG_ENTER("my_pwrite");
|
||||
DBUG_PRINT("my",("Fd: %d Seek: %lu Buffer: %lx Count: %d MyFlags: %d",
|
||||
Filedes, (ulong) offset,Buffer, Count, MyFlags));
|
||||
errors=0; written=0L;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
#ifndef HAVE_PREAD
|
||||
int error;
|
||||
writenbytes= (uint) -1;
|
||||
pthread_mutex_lock(&my_file_info[Filedes].mutex);
|
||||
error=(lseek(Filedes, offset, MY_SEEK_SET) != -1L &&
|
||||
(writenbytes = (uint) write(Filedes, Buffer, Count)) == Count);
|
||||
pthread_mutex_unlock(&my_file_info[Filedes].mutex);
|
||||
if (error)
|
||||
break;
|
||||
#else
|
||||
if ((writenbytes = (uint) pwrite(Filedes, Buffer, Count,offset)) == Count)
|
||||
break;
|
||||
#endif
|
||||
if ((int) writenbytes != -1)
|
||||
{ /* Safegueard */
|
||||
written+=writenbytes;
|
||||
Buffer+=writenbytes;
|
||||
Count-=writenbytes;
|
||||
offset+=writenbytes;
|
||||
}
|
||||
my_errno=errno;
|
||||
DBUG_PRINT("error",("Write only %d bytes",writenbytes));
|
||||
#ifndef NO_BACKGROUND
|
||||
#ifdef THREAD
|
||||
if (my_thread_var->abort)
|
||||
MyFlags&= ~ MY_WAIT_IF_FULL; /* End if aborted by user */
|
||||
#endif
|
||||
if (my_errno == ENOSPC && (MyFlags & MY_WAIT_IF_FULL))
|
||||
{
|
||||
if (!(errors++ % MY_WAIT_GIVE_USER_A_MESSAGE))
|
||||
my_error(EE_DISK_FULL,MYF(ME_BELL | ME_NOREFRESH),
|
||||
my_filename(Filedes));
|
||||
VOID(sleep(MY_WAIT_FOR_USER_TO_FIX_PANIC));
|
||||
continue;
|
||||
}
|
||||
if ((writenbytes == 0 && my_errno == EINTR) ||
|
||||
(writenbytes > 0 && (uint) writenbytes != (uint) -1))
|
||||
continue; /* Retry */
|
||||
#endif
|
||||
if (MyFlags & (MY_NABP | MY_FNABP))
|
||||
{
|
||||
if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
|
||||
{
|
||||
my_error(EE_WRITE, MYF(ME_BELL+ME_WAITTANG),
|
||||
my_filename(Filedes),my_errno);
|
||||
}
|
||||
DBUG_RETURN(MY_FILE_ERROR); /* Error on read */
|
||||
}
|
||||
else
|
||||
break; /* Return bytes written */
|
||||
}
|
||||
if (MyFlags & (MY_NABP | MY_FNABP))
|
||||
DBUG_RETURN(0); /* Want only errors */
|
||||
DBUG_RETURN(writenbytes+written); /* purecov: inspected */
|
||||
} /* my_write */
|
@ -26,6 +26,49 @@
|
||||
#include <thr_alarm.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
int
|
||||
pthread_cond_init (pthread_cond_t *cv, const pthread_condattr_t *attr)
|
||||
{
|
||||
DBUG_ENTER("pthread_cond_init");
|
||||
/* Initialize the count to 0 */
|
||||
cv->waiting = 0;
|
||||
|
||||
/* Create an auto-reset and manual-reset event */
|
||||
if (!(cv->events[SIGNAL] = CreateEvent (NULL, FALSE, FALSE, NULL)) ||
|
||||
!(cv->events[BROADCAST] = CreateEvent (NULL, TRUE, FALSE, NULL)))
|
||||
{
|
||||
DBUG_RETURN(GetLastError());
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
int pthread_cond_timedwait(pthread_cond_t *cond,
|
||||
pthread_mutex_t *mutex,
|
||||
struct timespec *abstime)
|
||||
{
|
||||
int result= 0;
|
||||
return result == WAIT_TIMEOUT ? ETIMEDOUT : 0;
|
||||
}
|
||||
|
||||
int pthread_cond_wait(pthread_cond_t *cv, pthread_mutex_t *mutex)
|
||||
{
|
||||
return pthread_cond_timedwait(cv,mutex,NULL);
|
||||
}
|
||||
|
||||
int pthread_cond_destroy(pthread_cond_t *cv)
|
||||
{
|
||||
DeleteCriticalSection(&cv->waiters_count_lock);
|
||||
|
||||
if (CloseHandle(cv->events[SIGNAL]) == 0 ||
|
||||
CloseHandle(cv->events[BROADCAST]) == 0)
|
||||
return EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if (defined(__BSD__) || defined(_BSDI_VERSION)) && !defined(HAVE_mit_thread)
|
||||
#define SCHED_POLICY SCHED_RR
|
||||
#else
|
||||
@ -144,7 +187,7 @@ struct tm *localtime_r(const time_t *clock, struct tm *res)
|
||||
** Author: Gary Wisniewski <garyw@spidereye.com.au>, much modified by Monty
|
||||
****************************************************************************/
|
||||
|
||||
#if !defined(HAVE_SIGWAIT) && !defined(HAVE_mit_thread) && !defined(sigwait) && !defined(__WIN__) && !defined(HAVE_rts_threads) && !defined(HAVE_NONPOSIX_SIGWAIT) && !defined(HAVE_DEC_3_2_THREADS) && !defined(OS2)
|
||||
#if !defined(HAVE_SIGWAIT) && !defined(HAVE_mit_thread) && !defined(sigwait) && !defined(_WIN32) && !defined(HAVE_rts_threads) && !defined(HAVE_NONPOSIX_SIGWAIT) && !defined(HAVE_DEC_3_2_THREADS) && !defined(OS2)
|
||||
|
||||
#if !defined(DONT_USE_SIGSUSPEND)
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
/* My memory re allocator */
|
||||
|
||||
gptr my_realloc(gptr oldpoint, uint Size, myf MyFlags)
|
||||
gptr my_realloc(gptr oldpoint, size_t Size, myf MyFlags)
|
||||
{
|
||||
gptr point;
|
||||
DBUG_ENTER("my_realloc");
|
||||
|
@ -70,8 +70,8 @@ uint sf_malloc_prehunc=0, /* If you have problem with core- */
|
||||
sf_malloc_endhunc=0, /* dump when malloc-message.... */
|
||||
/* set theese to 64 or 128 */
|
||||
sf_malloc_quick=0; /* set if no calls to sanity */
|
||||
long lCurMemory = 0L; /* Current memory usage */
|
||||
long lMaxMemory = 0L; /* Maximum memory usage */
|
||||
size_t lCurMemory = 0L; /* Current memory usage */
|
||||
size_t lMaxMemory = 0L; /* Maximum memory usage */
|
||||
uint cNewCount = 0; /* Number of times NEW() was called */
|
||||
byte *sf_min_adress= (byte*) ~(unsigned long) 0L,
|
||||
*sf_max_adress= (byte*) 0L;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -17,8 +17,28 @@
|
||||
51 Franklin St., Fifth Floor, Boston, MA 02110, USA
|
||||
*****************************************************************************/
|
||||
|
||||
/* The implementation for preoared statements was ported from PHP's mysqlnd
|
||||
extension, written by Andrey Hristov, Georg Richter and Ulf Wendel */
|
||||
/* The implementation for prepared statements was ported from PHP's mysqlnd
|
||||
extension, written by Andrey Hristov, Georg Richter and Ulf Wendel
|
||||
|
||||
Original file header:
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 2006-2011 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Georg Richter <georg@mysql.com> |
|
||||
| Andrey Hristov <andrey@mysql.com> |
|
||||
| Ulf Wendel <uwendel@mysql.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "my_global.h"
|
||||
#include <my_sys.h>
|
||||
@ -33,8 +53,10 @@
|
||||
#define UINT_MAX32 0xFFFFFFFFL
|
||||
#define UINT_MAX24 0x00FFFFFF
|
||||
#define UINT_MAX16 0xFFFF
|
||||
#ifndef INT_MIN8
|
||||
#define INT_MIN8 (~0x7F)
|
||||
#define INT_MAX8 0x7F
|
||||
#endif
|
||||
#define UINT_MAX8 0xFF
|
||||
|
||||
#if defined(HAVE_LONG_LONG) && !defined(LONGLONG_MIN)
|
||||
@ -101,7 +123,7 @@ static longlong my_atoll(const char *number, const char *end, int *error)
|
||||
{
|
||||
char buffer[255];
|
||||
longlong llval= 0;
|
||||
int i;
|
||||
size_t i;
|
||||
/* set error at the following conditions:
|
||||
- string contains invalid character(s)
|
||||
- length > 254
|
||||
@ -155,7 +177,7 @@ double my_atod(const char *number, const char *end, int *error)
|
||||
return val;
|
||||
}
|
||||
|
||||
my_bool str_to_TIME(const char *str, uint length, MYSQL_TIME *tm)
|
||||
my_bool str_to_TIME(const char *str, size_t length, MYSQL_TIME *tm)
|
||||
{
|
||||
my_bool is_time=0, is_date=0, has_time_frac=0;
|
||||
char *p= (char *)str;
|
||||
@ -197,7 +219,7 @@ my_bool str_to_TIME(const char *str, uint length, MYSQL_TIME *tm)
|
||||
}
|
||||
|
||||
|
||||
static void convert_from_string(MYSQL_BIND *r_param, char *buffer, uint len)
|
||||
static void convert_from_string(MYSQL_BIND *r_param, char *buffer, size_t len)
|
||||
{
|
||||
int error= 0;
|
||||
switch (r_param->buffer_type)
|
||||
@ -230,7 +252,7 @@ static void convert_from_string(MYSQL_BIND *r_param, char *buffer, uint len)
|
||||
case MYSQL_TYPE_LONGLONG:
|
||||
{
|
||||
longlong val= my_atoll(buffer, buffer + len, &error);
|
||||
*r_param->error= error > 0;
|
||||
*r_param->error= error > 0; /* no need to check for truncation */
|
||||
longlongstore(r_param->buffer, val);
|
||||
r_param->buffer_length= sizeof(longlong);
|
||||
}
|
||||
@ -238,18 +260,16 @@ static void convert_from_string(MYSQL_BIND *r_param, char *buffer, uint len)
|
||||
case MYSQL_TYPE_DOUBLE:
|
||||
{
|
||||
double val= my_atod(buffer, buffer + len, &error);
|
||||
*r_param->error= error > 0;
|
||||
*r_param->error= error > 0; /* no need to check for truncation */
|
||||
float8store(r_param->buffer, val);
|
||||
//*(double *)r_param->buffer= r_param->is_unsigned ? (ulonglong)val : (double)val;
|
||||
r_param->buffer_length= sizeof(double);
|
||||
}
|
||||
break;
|
||||
case MYSQL_TYPE_FLOAT:
|
||||
{
|
||||
float val= my_atod(buffer, buffer + len, &error);
|
||||
*r_param->error= error > 0;
|
||||
float val= (float)my_atod(buffer, buffer + len, &error);
|
||||
*r_param->error= error > 0; /* no need to check for truncation */
|
||||
float4store(r_param->buffer, val);
|
||||
// *(float *)r_param->buffer= r_param->is_unsigned ? (ulonglong)val : (float)val;
|
||||
r_param->buffer_length= sizeof(float);
|
||||
}
|
||||
break;
|
||||
@ -285,7 +305,7 @@ static void convert_from_string(MYSQL_BIND *r_param, char *buffer, uint len)
|
||||
((char *)r_param->buffer)[copylen]= '\0';
|
||||
*r_param->error= (copylen > r_param->buffer_length);
|
||||
|
||||
*r_param->length= len;
|
||||
*r_param->length= (ulong)len;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -340,7 +360,7 @@ static void convert_from_long(MYSQL_BIND *r_param, const MYSQL_FIELD *field, lon
|
||||
char *endptr;
|
||||
uint len;
|
||||
|
||||
endptr= int10_to_str(val, buffer, is_unsigned ? 10 : -10);
|
||||
endptr= longlong10_to_str(val, buffer, is_unsigned ? 10 : -10);
|
||||
len= (uint)(endptr - buffer);
|
||||
|
||||
/* check if field flag is zerofill */
|
||||
@ -485,31 +505,52 @@ static void convert_from_float(MYSQL_BIND *r_param, const MYSQL_FIELD *field, do
|
||||
case MYSQL_TYPE_SHORT:
|
||||
case MYSQL_TYPE_YEAR:
|
||||
{
|
||||
ushort sval= (r_param->is_unsigned) ? (ushort)val : (short)val;
|
||||
shortstore(buf, sval);
|
||||
*r_param->error= check_trunc_val != (r_param->is_unsigned ? *(ushort *)buf : *(short *)buf);
|
||||
if (r_param->is_unsigned)
|
||||
{
|
||||
ushort sval= (ushort)val;
|
||||
shortstore(buf, sval);
|
||||
*r_param->error= check_trunc_val != (double)sval;
|
||||
} else {
|
||||
short sval= (short)val;
|
||||
shortstore(buf, sval);
|
||||
*r_param->error= check_trunc_val != (double)sval;
|
||||
}
|
||||
r_param->buffer_length= 2;
|
||||
}
|
||||
break;
|
||||
case MYSQL_TYPE_LONG:
|
||||
{
|
||||
ulong lval= (r_param->is_unsigned) ? (ulong)val : (long)val;
|
||||
longstore(buf, lval);
|
||||
*r_param->error= check_trunc_val != (r_param->is_unsigned ? (double)(*(uint32 *)buf) : (double)(*(uint32 *)buf));
|
||||
if (r_param->is_unsigned)
|
||||
{
|
||||
uint32 lval= (uint32)val;
|
||||
longstore(buf, lval);
|
||||
*r_param->error= (check_trunc_val != (double)lval);
|
||||
} else {
|
||||
int32 lval= (int32)val;
|
||||
longstore(buf, lval);
|
||||
*r_param->error= (check_trunc_val != (double)lval);
|
||||
}
|
||||
r_param->buffer_length= 4;
|
||||
}
|
||||
break;
|
||||
case MYSQL_TYPE_LONGLONG:
|
||||
{
|
||||
ulong llval= (r_param->is_unsigned) ? (ulonglong)val : (ulonglong)val;
|
||||
longlongstore(buf, llval);
|
||||
*r_param->error= check_trunc_val != (r_param->is_unsigned ? *(ulonglong *)buf : *(longlong *)buf);
|
||||
if (r_param->is_unsigned)
|
||||
{
|
||||
ulonglong llval= (ulonglong)val;
|
||||
longlongstore(buf, llval);
|
||||
*r_param->error= (check_trunc_val != (double)llval);
|
||||
} else {
|
||||
longlong llval= (longlong)val;
|
||||
longlongstore(buf, llval);
|
||||
*r_param->error= (check_trunc_val != (double)llval);
|
||||
}
|
||||
r_param->buffer_length= 8;
|
||||
}
|
||||
break;
|
||||
case MYSQL_TYPE_FLOAT:
|
||||
{
|
||||
float fval= (double)val;
|
||||
float fval= (float)val;
|
||||
memcpy(buf, &fval, sizeof(float));
|
||||
*r_param->error= (*(float*)buf != fval);
|
||||
r_param->buffer_length= 4;
|
||||
@ -526,14 +567,14 @@ static void convert_from_float(MYSQL_BIND *r_param, const MYSQL_FIELD *field, do
|
||||
#define MAX_DOUBLE_STRING_REP_LENGTH 300
|
||||
char buff[MAX_DOUBLE_STRING_REP_LENGTH];
|
||||
char *end;
|
||||
int length;
|
||||
size_t length;
|
||||
|
||||
length= MIN(MAX_DOUBLE_STRING_REP_LENGTH - 1, r_param->buffer_length);
|
||||
|
||||
/* TODO: move this to a header shared between client and server. */
|
||||
if (field->decimals >= NOT_FIXED_DEC)
|
||||
{
|
||||
sprintf(buff, "%-*.*g", length-1, DBL_DIG, val);
|
||||
sprintf(buff, "%-*.*g", (int) length-1, DBL_DIG, val);
|
||||
length= strlen(buff);
|
||||
}
|
||||
else
|
||||
@ -630,7 +671,7 @@ static void convert_to_datetime(MYSQL_TIME *t, unsigned char **row, uint len, en
|
||||
{
|
||||
unsigned char *to= *row;
|
||||
int has_date= 0, has_time= 0;
|
||||
int offset= 7;
|
||||
uint offset= 7;
|
||||
|
||||
if (type == MYSQL_TYPE_TIME)
|
||||
{
|
||||
@ -740,28 +781,13 @@ static
|
||||
void ps_fetch_string(MYSQL_BIND *r_param, const MYSQL_FIELD *field,
|
||||
unsigned char **row)
|
||||
{
|
||||
/* C-API differs from PHP. While PHP just converts string to string,
|
||||
C-API needs to convert the string to the defined type with in
|
||||
the result bind buffer.
|
||||
*/
|
||||
ulong field_length= net_field_length(row);
|
||||
|
||||
convert_from_string(r_param, (char *)*row, field_length);
|
||||
/* switch (r_param->buffer_type)
|
||||
{
|
||||
case MYSQL_TYPE_STRING:
|
||||
case MYSQL_TYPE_VAR_STRING:
|
||||
case MYSQL_TYPE_DECIMAL:
|
||||
{
|
||||
ulong c= MIN(r_param->buffer_length, field_length);
|
||||
|
||||
memcpy(r_param->buffer, (char *)*row, c);
|
||||
|
||||
if (c < r_param->buffer_length)
|
||||
((char *)r_param->buffer)[c]= 0;
|
||||
r_param->buffer_length= field_length;
|
||||
*r_param->error= c < field_length;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
convert_from_string(r_param, (char *)*row, field_length);
|
||||
break;
|
||||
} */
|
||||
(*row) += field_length;
|
||||
}
|
||||
/* }}} */
|
||||
@ -831,7 +857,7 @@ void mysql_init_ps_subsystem(void)
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_DATE].pack_len = 5;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_DATE].max_len = 10;
|
||||
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_NEWDATE].func = ps_fetch_datetime;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_NEWDATE].func = ps_fetch_string;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_NEWDATE].pack_len = MYSQL_PS_SKIP_RESULT_W_LEN;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_NEWDATE].max_len = -1;
|
||||
|
@ -75,8 +75,8 @@ my_bool my_thread_global_init(void)
|
||||
pthread_mutex_init(&THR_LOCK_heap,MY_MUTEX_INIT_FAST);
|
||||
pthread_mutex_init(&THR_LOCK_net,MY_MUTEX_INIT_FAST);
|
||||
pthread_mutex_init(&THR_LOCK_charset,MY_MUTEX_INIT_FAST);
|
||||
#if defined( __WIN__) || defined(OS2)
|
||||
win_pthread_init();
|
||||
#ifdef _WIN32
|
||||
/* win_pthread_init(); */
|
||||
#endif
|
||||
#ifndef HAVE_LOCALTIME_R
|
||||
pthread_mutex_init(&LOCK_localtime_r,MY_MUTEX_INIT_SLOW);
|
||||
@ -115,10 +115,10 @@ static long thread_id=0;
|
||||
my_bool my_thread_init(void)
|
||||
{
|
||||
struct st_my_thread_var *tmp;
|
||||
#if !defined(__WIN__) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
|
||||
#if !defined(_WIN32) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
|
||||
pthread_mutex_lock(&THR_LOCK_lock);
|
||||
#endif
|
||||
#if !defined(__WIN__) || defined(USE_TLS)
|
||||
#if !defined(_WIN32) || defined(USE_TLS)
|
||||
if (my_pthread_getspecific(struct st_my_thread_var *,THR_KEY_mysys))
|
||||
{
|
||||
pthread_mutex_unlock(&THR_LOCK_lock);
|
||||
@ -137,7 +137,7 @@ my_bool my_thread_init(void)
|
||||
#else
|
||||
if (THR_KEY_mysys.id) /* Already initialized */
|
||||
{
|
||||
#if !defined(__WIN__) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
|
||||
#if !defined(_WIN32) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
|
||||
pthread_mutex_unlock(&THR_LOCK_lock);
|
||||
#endif
|
||||
return 0;
|
||||
@ -147,7 +147,7 @@ my_bool my_thread_init(void)
|
||||
tmp->id= ++thread_id;
|
||||
pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST);
|
||||
pthread_cond_init(&tmp->suspend, NULL);
|
||||
#if !defined(__WIN__) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
|
||||
#if !defined(_WIN32) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
|
||||
pthread_mutex_unlock(&THR_LOCK_lock);
|
||||
#endif
|
||||
return 0;
|
||||
@ -169,11 +169,11 @@ void my_thread_end(void)
|
||||
pthread_cond_destroy(&tmp->suspend);
|
||||
#endif
|
||||
pthread_mutex_destroy(&tmp->mutex);
|
||||
#if (!defined(__WIN__) && !defined(OS2)) || defined(USE_TLS)
|
||||
#if (!defined(_WIN32) && !defined(OS2)) || defined(USE_TLS)
|
||||
free(tmp);
|
||||
#endif
|
||||
}
|
||||
#if (!defined(__WIN__) && !defined(OS2)) || defined(USE_TLS)
|
||||
#if (!defined(_WIN32) && !defined(OS2)) || defined(USE_TLS)
|
||||
pthread_setspecific(THR_KEY_mysys,0);
|
||||
#endif
|
||||
}
|
||||
|
119
libmysql/my_vsnprintf.c
Normal file
119
libmysql/my_vsnprintf.c
Normal file
@ -0,0 +1,119 @@
|
||||
/* 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 */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include "mysys_err.h"
|
||||
#include <m_string.h>
|
||||
#include <stdarg.h>
|
||||
#include <m_ctype.h>
|
||||
|
||||
|
||||
int my_snprintf(char* to, size_t n, const char* fmt, ...)
|
||||
{
|
||||
int result;
|
||||
va_list args;
|
||||
va_start(args,fmt);
|
||||
result= my_vsnprintf(to, n, fmt, args);
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
|
||||
{
|
||||
char *start=to, *end=to+n-1;
|
||||
for (; *fmt ; fmt++)
|
||||
{
|
||||
if (fmt[0] != '%')
|
||||
{
|
||||
if (to == end) /* End of buffer */
|
||||
break;
|
||||
*to++= *fmt; /* Copy ordinary char */
|
||||
continue;
|
||||
}
|
||||
/* Skipp if max size is used (to be compatible with printf) */
|
||||
fmt++;
|
||||
while (isdigit(*fmt) || *fmt == '.' || *fmt == '-')
|
||||
fmt++;
|
||||
if (*fmt == 'l')
|
||||
fmt++;
|
||||
if (*fmt == 's') /* String parameter */
|
||||
{
|
||||
reg2 char *par = va_arg(ap, char *);
|
||||
uint plen;
|
||||
if (!par) par = (char*)"(null)";
|
||||
plen = (uint) strlen(par);
|
||||
if ((uint) (end-to) > plen) /* Replace if possible */
|
||||
{
|
||||
to=strmov(to,par);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */
|
||||
{
|
||||
register int iarg;
|
||||
if ((uint) (end-to) < 16)
|
||||
break;
|
||||
iarg = va_arg(ap, int);
|
||||
if (*fmt == 'd')
|
||||
to=int10_to_str((long) iarg,to, -10);
|
||||
else
|
||||
to=int10_to_str((long) (uint) iarg,to,10);
|
||||
continue;
|
||||
}
|
||||
/* We come here on '%%', unknown code or too long parameter */
|
||||
if (to == end)
|
||||
break;
|
||||
*to++='%'; /* % used as % or unknown code */
|
||||
}
|
||||
*to='\0'; /* End of errmessage */
|
||||
return (uint) (to - start);
|
||||
}
|
||||
|
||||
|
||||
#ifdef MAIN
|
||||
static void my_printf(const char * fmt, ...)
|
||||
{
|
||||
char buf[32];
|
||||
int n;
|
||||
va_list ar;
|
||||
va_start(ar, fmt);
|
||||
n = my_vsnprintf(buf, sizeof(buf),fmt, ar);
|
||||
printf(buf);
|
||||
printf("n=%d, strlen=%d\n", n, strlen(buf));
|
||||
va_end(ar);
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
my_printf("Hello\n");
|
||||
my_printf("Hello int, %d\n", 1);
|
||||
my_printf("Hello string '%s'\n", "I am a string");
|
||||
my_printf("Hello hack hack hack hack hack hack hack %d\n", 1);
|
||||
my_printf("Hello %d hack %d\n", 1, 4);
|
||||
my_printf("Hello %d hack hack hack hack hack %d\n", 1, 4);
|
||||
my_printf("Hello '%s' hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\n", "hack");
|
||||
my_printf("Hello hhhhhhhhhhhhhh %d sssssssssssssss\n", 1);
|
||||
my_printf("Hello %u\n", 1);
|
||||
my_printf("conn %ld to: '%-.64s' user: '%-.32s' host:\
|
||||
`%-.64s' (%-.64s)", 1, 0,0,0,0);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
139
libmysql/net.c
139
libmysql/net.c
@ -22,9 +22,6 @@
|
||||
** 3 byte length & 1 byte package-number.
|
||||
*/
|
||||
|
||||
#ifdef __WIN__
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#include <my_global.h>
|
||||
#include <violite.h>
|
||||
#include <my_sys.h>
|
||||
@ -40,23 +37,17 @@
|
||||
|
||||
#define MAX_PACKET_LENGTH (256L*256L*256L-1)
|
||||
|
||||
#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=MAX_PACKET_LENGTH;
|
||||
ulong max_allowed_packet=1024L * 1024L * 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)
|
||||
#if !defined(_WIN32) && !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__)
|
||||
#if !defined(MSDOS) && !defined(_WIN32) && !defined(HAVE_BROKEN_NETINET_INCLUDES) && !defined(__BEOS__)
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip.h>
|
||||
@ -108,7 +99,7 @@ extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received;
|
||||
*/
|
||||
|
||||
#define TEST_BLOCKING 8
|
||||
static int net_write_buff(NET *net,const char *packet,uint len);
|
||||
static int net_write_buff(NET *net,const char *packet, size_t len);
|
||||
|
||||
|
||||
/* Init with packet info */
|
||||
@ -134,7 +125,7 @@ int my_net_init(NET *net, Vio* vio)
|
||||
if (vio != 0) /* If real connection */
|
||||
{
|
||||
net->fd = vio_fd(vio); /* For perl DBI/DBD */
|
||||
#if defined(MYSQL_SERVER) && !defined(___WIN__) && !defined(__EMX__) && !defined(OS2)
|
||||
#if defined(MYSQL_SERVER) && !defined(__WIN32) && !defined(__EMX__) && !defined(OS2)
|
||||
if (!(test_flags & TEST_BLOCKING))
|
||||
vio_blocking(vio, FALSE);
|
||||
#endif
|
||||
@ -151,29 +142,35 @@ void net_end(NET *net)
|
||||
|
||||
/* Realloc the packet buffer */
|
||||
|
||||
static my_bool net_realloc(NET *net, ulong length)
|
||||
static my_bool net_realloc(NET *net, size_t length)
|
||||
{
|
||||
uchar *buff;
|
||||
ulong pkt_length;
|
||||
|
||||
DBUG_ENTER("net_realloc");
|
||||
DBUG_PRINT("info", ("length: %lu max_allowed_packet: %lu",
|
||||
(ulong)length, max_allowed_packet));
|
||||
|
||||
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;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
|
||||
if (!(buff=(uchar*) my_realloc((char*) net->buff, pkt_length, MYF(MY_WME))))
|
||||
{
|
||||
DBUG_PRINT("info", ("Out of memory"));
|
||||
net->error=1;
|
||||
#ifdef MYSQL_SERVER
|
||||
net->last_errno=ER_OUT_OF_RESOURCES;
|
||||
#endif
|
||||
return 1;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
net->buff=net->write_pos=buff;
|
||||
net->buff_end=buff+(net->max_packet=pkt_length);
|
||||
return 0;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/* Remove unwanted characters from connection */
|
||||
@ -228,7 +225,7 @@ int net_flush(NET *net)
|
||||
*/
|
||||
|
||||
int
|
||||
my_net_write(NET *net,const char *packet,ulong len)
|
||||
my_net_write(NET *net, const char *packet, size_t len)
|
||||
{
|
||||
uchar buff[NET_HEADER_SIZE];
|
||||
if (len >= MAX_PACKET_LENGTH)
|
||||
@ -245,39 +242,62 @@ my_net_write(NET *net,const char *packet,ulong len)
|
||||
}
|
||||
|
||||
int
|
||||
net_write_command(NET *net,uchar command,const char *packet,ulong len)
|
||||
net_write_command(NET *net, uchar command,
|
||||
const char *packet, size_t len)
|
||||
{
|
||||
uchar buff[NET_HEADER_SIZE+1];
|
||||
uint length=len+1; /* 1 extra byte for command */
|
||||
size_t buff_size= NET_HEADER_SIZE + 1;
|
||||
size_t length= 1 + len; /* 1 extra byte for command */
|
||||
int rc;
|
||||
|
||||
buff[4]=command;
|
||||
|
||||
if (length >= MAX_PACKET_LENGTH)
|
||||
{
|
||||
net->error=1;
|
||||
net->last_errno=ER_NET_PACKET_TOO_LARGE;
|
||||
return 1;
|
||||
len= MAX_PACKET_LENGTH - 1;
|
||||
do
|
||||
{
|
||||
int3store(buff, MAX_PACKET_LENGTH);
|
||||
buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++);
|
||||
|
||||
if (net_write_buff(net, (char *)buff, buff_size) ||
|
||||
net_write_buff(net, packet, len))
|
||||
return(1);
|
||||
packet+= len;
|
||||
length-= MAX_PACKET_LENGTH;
|
||||
len= MAX_PACKET_LENGTH;
|
||||
buff_size= NET_HEADER_SIZE; /* don't send command for further packets */
|
||||
} while (length >= MAX_PACKET_LENGTH);
|
||||
len= length;
|
||||
}
|
||||
int3store(buff,length);
|
||||
buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++);
|
||||
buff[4]=command;
|
||||
rc= test (net_write_buff(net,buff,5) || net_write_buff(net,packet,len) || net_flush(net));
|
||||
rc= test (net_write_buff(net,(char *)buff, buff_size) ||
|
||||
net_write_buff(net,packet,len) ||
|
||||
net_flush(net));
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
net_write_buff(NET *net,const char *packet,uint len)
|
||||
net_write_buff(NET *net,const char *packet, size_t len)
|
||||
{
|
||||
uint left_length=(uint) (net->buff_end - net->write_pos);
|
||||
size_t left_length=(size_t) (net->buff_end - net->write_pos);
|
||||
|
||||
while (len > left_length)
|
||||
if (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;
|
||||
if (net->write_pos != net->buff)
|
||||
{
|
||||
memcpy((char*) net->write_pos,packet,left_length);
|
||||
if (net_real_write(net,(char*) net->buff,
|
||||
(size_t)(net->write_pos - net->buff) + left_length))
|
||||
return 1;
|
||||
packet+=left_length;
|
||||
len-=left_length;
|
||||
net->write_pos= net->buff;
|
||||
}
|
||||
if (len > net->max_packet)
|
||||
return(test(net_real_write(net, packet, len)));
|
||||
}
|
||||
memcpy((char*) net->write_pos,packet,len);
|
||||
net->write_pos+=len;
|
||||
@ -292,7 +312,7 @@ net_real_write(NET *net,const char *packet,ulong len)
|
||||
int length;
|
||||
char *pos,*end;
|
||||
thr_alarm_t alarmed;
|
||||
#if !defined(__WIN__) && !defined(__EMX__) && !defined(OS2)
|
||||
#if !defined(_WIN32) && !defined(__EMX__) && !defined(OS2)
|
||||
ALARM alarm_buff;
|
||||
#endif
|
||||
uint retry_count=0;
|
||||
@ -350,7 +370,7 @@ net_real_write(NET *net,const char *packet,ulong len)
|
||||
if ((int) (length=vio_write(net->vio,pos,(int) (end-pos))) <= 0)
|
||||
{
|
||||
my_bool interrupted = vio_should_retry(net->vio);
|
||||
#if (!defined(__WIN__) && !defined(__EMX__) && !defined(OS2))
|
||||
#if (!defined(_WIN32) && !defined(__EMX__) && !defined(OS2))
|
||||
if ((interrupted || length==0) && !thr_alarm_in_use(&alarmed))
|
||||
{
|
||||
if (!thr_alarm(&alarmed,(uint) net_write_timeout,&alarm_buff))
|
||||
@ -375,7 +395,7 @@ net_real_write(NET *net,const char *packet,ulong len)
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* (!defined(__WIN__) && !defined(__EMX__)) */
|
||||
#endif /* (!defined(_WIN32) && !defined(__EMX__)) */
|
||||
if (thr_alarm_in_use(&alarmed) && !thr_got_alarm(&alarmed) &&
|
||||
interrupted)
|
||||
{
|
||||
@ -403,7 +423,7 @@ net_real_write(NET *net,const char *packet,ulong len)
|
||||
pos+=length;
|
||||
statistic_add(bytes_sent,length,&LOCK_bytes_sent);
|
||||
}
|
||||
#ifndef __WIN__
|
||||
#ifndef _WIN32
|
||||
end:
|
||||
#endif
|
||||
#ifdef HAVE_COMPRESS
|
||||
@ -462,18 +482,18 @@ static void my_net_skip_rest(NET *net, ulong remain, thr_alarm_t *alarmed,
|
||||
|
||||
|
||||
static ulong
|
||||
my_real_read(NET *net, ulong *complen)
|
||||
my_real_read(NET *net, size_t *complen)
|
||||
{
|
||||
uchar *pos;
|
||||
ulong length;
|
||||
size_t length;
|
||||
uint i,retry_count=0;
|
||||
ulong len=packet_error;
|
||||
thr_alarm_t alarmed;
|
||||
#if (!defined(__WIN__) && !defined(__EMX__) && !defined(OS2)) || defined(MYSQL_SERVER)
|
||||
#if (!defined(_WIN32) && !defined(__EMX__) && !defined(OS2)) || 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 :
|
||||
size_t remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE :
|
||||
NET_HEADER_SIZE);
|
||||
*complen = 0;
|
||||
|
||||
@ -496,7 +516,7 @@ my_real_read(NET *net, ulong *complen)
|
||||
|
||||
DBUG_PRINT("info",("vio_read returned %d, errno: %d",
|
||||
length, vio_errno(net->vio)));
|
||||
#if (!defined(__WIN__) && !defined(__EMX__) && !defined(OS2)) || defined(MYSQL_SERVER)
|
||||
#if (!defined(_WIN32) && !defined(__EMX__) && !defined(OS2)) || 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
|
||||
@ -533,7 +553,7 @@ my_real_read(NET *net, ulong *complen)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif /* (!defined(__WIN__) && !defined(__EMX__)) || defined(MYSQL_SERVER) */
|
||||
#endif /* (!defined(_WIN32) && !defined(__EMX__)) || defined(MYSQL_SERVER) */
|
||||
if (thr_alarm_in_use(&alarmed) && !thr_got_alarm(&alarmed) &&
|
||||
interrupted)
|
||||
{ /* Probably in MIT threads */
|
||||
@ -554,10 +574,6 @@ my_real_read(NET *net, ulong *complen)
|
||||
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;
|
||||
@ -597,12 +613,14 @@ my_real_read(NET *net, ulong *complen)
|
||||
#endif
|
||||
|
||||
len=uint3korr(net->buff+net->where_b);
|
||||
if (!len)
|
||||
goto end;
|
||||
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))
|
||||
if (net_realloc(net,helping))
|
||||
{
|
||||
#ifdef MYSQL_SERVER
|
||||
if (i == 1)
|
||||
@ -635,7 +653,22 @@ ulong my_net_read(NET *net)
|
||||
if (!net->compress)
|
||||
{
|
||||
#endif
|
||||
len = my_real_read (net,&complen);
|
||||
len = my_real_read (net,(size_t *)&complen);
|
||||
if (len == MAX_PACKET_LENGTH)
|
||||
{
|
||||
/* multi packet read */
|
||||
size_t length= 0;
|
||||
ulong last_pos= net->where_b;
|
||||
|
||||
do
|
||||
{
|
||||
length+= len;
|
||||
net->where_b+= len;
|
||||
} while (len == MAX_PACKET_LENGTH);
|
||||
net->where_b= last_pos;
|
||||
if (len != packet_error)
|
||||
len+= length;
|
||||
}
|
||||
net->read_pos = net->buff + net->where_b;
|
||||
if (len != packet_error)
|
||||
net->read_pos[len]=0; /* Safeguard for mysql_use_result */
|
||||
@ -675,7 +708,7 @@ ulong my_net_read(NET *net)
|
||||
net->buf_length=0;
|
||||
}
|
||||
|
||||
if ((len = my_real_read(net,&complen)) == packet_error)
|
||||
if ((len = my_real_read(net,(size_t *)&complen)) == packet_error)
|
||||
break;
|
||||
if (my_uncompress((byte*) net->buff + net->where_b, &len, &complen))
|
||||
{
|
||||
|
@ -68,11 +68,12 @@ double rnd(struct rand_struct *rand_st)
|
||||
return (((double) rand_st->seed1)/rand_st->max_value_dbl);
|
||||
}
|
||||
|
||||
void hash_password(ulong *result, const char *password)
|
||||
void hash_password(ulong *result, const char *password, size_t len)
|
||||
{
|
||||
register ulong nr=1345345333L, add=7, nr2=0x12345671L;
|
||||
ulong tmp;
|
||||
for (; *password ; password++)
|
||||
const char *password_end= password + len;
|
||||
for (; password < password_end; password++)
|
||||
{
|
||||
if (*password == ' ' || *password == '\t')
|
||||
continue; /* skipp space in password */
|
||||
@ -86,13 +87,6 @@ void hash_password(ulong *result, const char *password)
|
||||
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 unsigned int char_val(char X)
|
||||
{
|
||||
return (uint) (X >= '0' && X <= '9' ? X-'0' :
|
||||
@ -100,67 +94,11 @@ static inline unsigned int char_val(char X)
|
||||
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;
|
||||
}
|
||||
|
||||
/* scramble for 4.1 servers
|
||||
* Code based on php_nysqlnd_scramble function from PHP's mysqlnd extension,
|
||||
* written by Andrey Hristov (andrey@php.net)
|
||||
@ -202,6 +140,68 @@ void my_scramble_41(const unsigned char *buffer, const char *scramble, const cha
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void make_scrambled_password(char *to,const char *password)
|
||||
{
|
||||
ulong hash_res[2];
|
||||
hash_password(hash_res,password, strlen(password));
|
||||
sprintf(to,"%08lx%08lx",hash_res[0],hash_res[1]);
|
||||
}
|
||||
|
||||
/*
|
||||
** 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_323(char *to,const char *message,const char *password)
|
||||
{
|
||||
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, strlen(password));
|
||||
hash_password(hash_message, message, strlen(message));
|
||||
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);
|
||||
{ /* 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,
|
||||
@ -212,7 +212,7 @@ my_bool check_scramble(const char *scrambled, const char *message,
|
||||
char buff[16],*to,extra; /* Big enough for check */
|
||||
const char *pos;
|
||||
|
||||
hash_password(hash_message,message);
|
||||
hash_password(hash_message,message, strlen(message));
|
||||
if (old_ver)
|
||||
old_randominit(&rand_st,hash_pass[0] ^ hash_message[0]);
|
||||
else
|
||||
|
@ -121,7 +121,7 @@ static int _checkchunk(struct remember *pRec, const char *sFile, uint uLine);
|
||||
* Allocate some memory.
|
||||
*/
|
||||
|
||||
gptr _mymalloc (uint uSize, const char *sFile, uint uLine, myf MyFlags)
|
||||
gptr _mymalloc (size_t uSize, const char *sFile, uint uLine, myf MyFlags)
|
||||
{
|
||||
struct remember *pTmp;
|
||||
DBUG_ENTER("_mymalloc");
|
||||
@ -154,9 +154,9 @@ gptr _mymalloc (uint uSize, const char *sFile, uint uLine, myf MyFlags)
|
||||
my_errno=errno;
|
||||
sprintf(buff,"Out of memory at line %d, '%s'", uLine, sFile);
|
||||
my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG));
|
||||
sprintf(buff,"needed %d byte (%ldk), memory in use: %ld bytes (%ldk)",
|
||||
uSize, (uSize + 1023L) / 1024L,
|
||||
lMaxMemory, (lMaxMemory + 1023L) / 1024L);
|
||||
sprintf(buff,"needed %ld byte (%ldk), memory in use: %lu bytes (%ldk)",
|
||||
(long) uSize, (long) ((uSize + 1023L) / 1024L),
|
||||
(long) lMaxMemory, (long) (lMaxMemory + 1023L) / 1024L);
|
||||
my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG));
|
||||
}
|
||||
DBUG_PRINT("error",("Out of memory, in use: %ld at line %d, '%s'",
|
||||
@ -211,7 +211,7 @@ gptr _mymalloc (uint uSize, const char *sFile, uint uLine, myf MyFlags)
|
||||
* Free then old memoryblock
|
||||
*/
|
||||
|
||||
gptr _myrealloc (register gptr pPtr, register uint uSize,
|
||||
gptr _myrealloc (register gptr pPtr, register size_t uSize,
|
||||
const char *sFile, uint uLine, myf MyFlags)
|
||||
{
|
||||
struct remember *pRec;
|
||||
@ -242,7 +242,7 @@ gptr _myrealloc (register gptr pPtr, register uint uSize,
|
||||
|
||||
if ((ptr=_mymalloc(uSize,sFile,uLine,MyFlags))) /* Allocate new area */
|
||||
{
|
||||
uSize=min(uSize,pRec-> uDataSize); /* Move as much as possibly */
|
||||
uSize=min(uSize,pRec->uDataSize); /* Move as much as possibly */
|
||||
memcpy((byte*) ptr,pPtr,(size_t) uSize); /* Copy old data */
|
||||
_myfree(pPtr,sFile,uLine,0); /* Free not needed area */
|
||||
}
|
||||
@ -393,10 +393,10 @@ void TERMINATE (FILE *file)
|
||||
{
|
||||
if (file)
|
||||
{
|
||||
fprintf(file, "Memory that was not free'ed (%ld bytes):\n",lCurMemory);
|
||||
fprintf(file, "Memory that was not free'ed (%zu bytes):\n",lCurMemory);
|
||||
(void) fflush(file);
|
||||
}
|
||||
DBUG_PRINT("safe",("Memory that was not free'ed (%ld bytes):",lCurMemory));
|
||||
DBUG_PRINT("safe",("Memory that was not free'ed (%zu bytes):",lCurMemory));
|
||||
while (pPtr)
|
||||
{
|
||||
if (file)
|
||||
@ -418,7 +418,7 @@ void TERMINATE (FILE *file)
|
||||
/* Report the memory usage statistics */
|
||||
if (file)
|
||||
{
|
||||
fprintf (file, "Maximum memory usage: %ld bytes (%ldk)\n",
|
||||
fprintf (file, "Maximum memory usage: %zu bytes (%ldk)\n",
|
||||
lMaxMemory, (lMaxMemory + 1023L) / 1024L);
|
||||
(void) fflush(file);
|
||||
}
|
||||
@ -434,7 +434,7 @@ void TERMINATE (FILE *file)
|
||||
static int _checkchunk (register struct remember *pRec, const char *sFile,
|
||||
uint uLine)
|
||||
{
|
||||
reg1 uint uSize;
|
||||
reg1 size_t uSize;
|
||||
reg2 my_string magicp;
|
||||
reg3 int flag=0;
|
||||
|
||||
@ -454,7 +454,7 @@ static int _checkchunk (register struct remember *pRec, const char *sFile,
|
||||
}
|
||||
|
||||
/* Check for a possible overrun */
|
||||
uSize = pRec -> uDataSize;
|
||||
uSize = pRec->uDataSize;
|
||||
magicp = &(pRec -> aData[uSize+sf_malloc_prehunc]);
|
||||
if (*magicp++ != MAGICEND0 ||
|
||||
*magicp++ != MAGICEND1 ||
|
||||
@ -502,12 +502,12 @@ int _sanity (const char *sFile, uint uLine)
|
||||
|
||||
/* malloc and copy */
|
||||
|
||||
gptr _my_memdup(const byte *from, uint length, const char *sFile, uint uLine,
|
||||
gptr _my_memdup(const byte *from, size_t length, const char *sFile, uint uLine,
|
||||
myf MyFlags)
|
||||
{
|
||||
gptr ptr;
|
||||
if ((ptr=_mymalloc(length,sFile,uLine,MyFlags)) != 0)
|
||||
memcpy((byte*) ptr, (byte*) from,(size_t) length);
|
||||
memcpy((byte*) ptr, (byte*) from, length);
|
||||
return(ptr);
|
||||
} /*_my_memdup */
|
||||
|
||||
@ -516,7 +516,7 @@ my_string _my_strdup(const char *from, const char *sFile, uint uLine,
|
||||
myf MyFlags)
|
||||
{
|
||||
gptr ptr;
|
||||
uint length=(uint) strlen(from)+1;
|
||||
size_t length= strlen(from)+1;
|
||||
if ((ptr=_mymalloc(length,sFile,uLine,MyFlags)) != 0)
|
||||
memcpy((byte*) ptr, (byte*) from,(size_t) length);
|
||||
return((my_string) ptr);
|
||||
|
@ -102,7 +102,7 @@ void MYSQL_SHA1Init(MYSQL_SHA1_CTX * context)
|
||||
context.
|
||||
*/
|
||||
void MYSQL_SHA1Update(MYSQL_SHA1_CTX * context, const unsigned char *input,
|
||||
unsigned int inputLen)
|
||||
size_t inputLen)
|
||||
{
|
||||
unsigned int i, index, partLen;
|
||||
|
||||
|
@ -1,810 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2007 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Marcus Boerger <helly@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id: spprintf.c,v 1.25.2.2.2.10.2.1 2007/10/01 15:22:41 iliaa Exp $ */
|
||||
|
||||
/* This is the spprintf implementation.
|
||||
* It has emerged from apache snprintf. See original header:
|
||||
*/
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1995-1998 The Apache Group. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the Apache Group
|
||||
* for use in the Apache HTTP server project (http://www.apache.org/)."
|
||||
*
|
||||
* 4. The names "Apache Server" and "Apache Group" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission.
|
||||
*
|
||||
* 5. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the Apache Group
|
||||
* for use in the Apache HTTP server project (http://www.apache.org/)."
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Group and was originally based
|
||||
* on public domain software written at the National Center for
|
||||
* Supercomputing Applications, University of Illinois, Urbana-Champaign.
|
||||
* For more information on the Apache Group and the Apache HTTP server
|
||||
* project, please see <http://www.apache.org/>.
|
||||
*
|
||||
* This code is based on, and used with the permission of, the
|
||||
* SIO stdio-replacement strx_* functions by Panos Tsirigotis
|
||||
* <panos@alumni.cs.colorado.edu> for xinetd.
|
||||
*/
|
||||
#include "my_global.h"
|
||||
#include <my_sys.h>
|
||||
#include <mysys_err.h>
|
||||
#include <m_string.h>
|
||||
#include <m_ctype.h>
|
||||
#include "mysql.h"
|
||||
#include "mysql_priv.h"
|
||||
#include "mysql_version.h"
|
||||
#include "mysqld_error.h"
|
||||
#include "errmsg.h"
|
||||
|
||||
#include "mysql_mm.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LOCALE_H
|
||||
#include <locale.h>
|
||||
#define LCONV_DECIMAL_POINT (*lconv->decimal_point)
|
||||
#else
|
||||
#define LCONV_DECIMAL_POINT '.'
|
||||
#endif
|
||||
|
||||
#include "snprintf.h"
|
||||
|
||||
#define NUL '\0'
|
||||
#define INT_NULL ((int *)0)
|
||||
|
||||
#define S_NULL "(null)"
|
||||
#define S_NULL_LEN 6
|
||||
|
||||
#define FLOAT_DIGITS 6
|
||||
#define EXPONENT_LENGTH 10
|
||||
|
||||
#include "smart_str.h"
|
||||
|
||||
/* {{{ macros */
|
||||
|
||||
/*
|
||||
* NUM_BUF_SIZE is the size of the buffer used for arithmetic conversions
|
||||
*
|
||||
* XXX: this is a magic number; do not decrease it
|
||||
*/
|
||||
#define NUM_BUF_SIZE 512
|
||||
|
||||
/*
|
||||
* The INS_CHAR macro inserts a character in the buffer.
|
||||
*
|
||||
* NOTE: Evaluation of the ch argument should not have any side-effects
|
||||
*/
|
||||
#define INS_CHAR_NR(xbuf, ch) do { \
|
||||
smart_str_appendc(xbuf, ch); \
|
||||
} while (0)
|
||||
|
||||
#define INS_STRING(xbuf, s, slen) do { \
|
||||
smart_str_appendl(xbuf, s, slen); \
|
||||
} while (0)
|
||||
|
||||
#define INS_CHAR(xbuf, ch) \
|
||||
INS_CHAR_NR(xbuf, ch)
|
||||
|
||||
/*
|
||||
* Macro that does padding. The padding is done by printing
|
||||
* the character ch.
|
||||
*/
|
||||
#define PAD(xbuf, count, ch) do { \
|
||||
if ((count) > 0) { \
|
||||
size_t newlen; \
|
||||
smart_str_alloc(xbuf, (count), 0); \
|
||||
memset(xbuf->c + xbuf->len, ch, (count)); \
|
||||
xbuf->len += (count); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define NUM(c) (c - '0')
|
||||
|
||||
#define STR_TO_DEC(str, num) do { \
|
||||
num = NUM(*str++); \
|
||||
while (isdigit((int)*str)) { \
|
||||
num *= 10; \
|
||||
num += NUM(*str++); \
|
||||
if (num >= INT_MAX / 10) { \
|
||||
while (isdigit((int)*str++)); \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* This macro does zero padding so that the precision
|
||||
* requirement is satisfied. The padding is done by
|
||||
* adding '0's to the left of the string that is going
|
||||
* to be printed.
|
||||
*/
|
||||
#define FIX_PRECISION(adjust, precision, s, s_len) do { \
|
||||
if (adjust) \
|
||||
while (s_len < precision) { \
|
||||
*--s = '0'; \
|
||||
s_len++; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* Do format conversion placing the output in buffer
|
||||
*/
|
||||
static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) /* {{{ */
|
||||
{
|
||||
register char *s = NULL;
|
||||
char *q;
|
||||
int s_len;
|
||||
|
||||
register int min_width = 0;
|
||||
int precision = 0;
|
||||
enum {
|
||||
LEFT, RIGHT
|
||||
} adjust;
|
||||
char pad_char;
|
||||
char prefix_char;
|
||||
|
||||
double fp_num;
|
||||
wide_int i_num = (wide_int) 0;
|
||||
u_wide_int ui_num;
|
||||
|
||||
char num_buf[NUM_BUF_SIZE];
|
||||
char char_buf[2]; /* for printing %% and %<unknown> */
|
||||
|
||||
#ifdef HAVE_LOCALE_H
|
||||
struct lconv *lconv = NULL;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Flag variables
|
||||
*/
|
||||
length_modifier_e modifier;
|
||||
boolean_e alternate_form;
|
||||
boolean_e print_sign;
|
||||
boolean_e print_blank;
|
||||
boolean_e adjust_precision;
|
||||
boolean_e adjust_width;
|
||||
bool_int is_negative;
|
||||
|
||||
while (*fmt) {
|
||||
if (*fmt != '%') {
|
||||
INS_CHAR(xbuf, *fmt);
|
||||
} else {
|
||||
/*
|
||||
* Default variable settings
|
||||
*/
|
||||
adjust = RIGHT;
|
||||
alternate_form = print_sign = print_blank = NO;
|
||||
pad_char = ' ';
|
||||
prefix_char = NUL;
|
||||
|
||||
fmt++;
|
||||
|
||||
/*
|
||||
* Try to avoid checking for flags, width or precision
|
||||
*/
|
||||
if (isascii((int)*fmt) && !islower((int)*fmt)) {
|
||||
/*
|
||||
* Recognize flags: -, #, BLANK, +
|
||||
*/
|
||||
for (;; fmt++) {
|
||||
if (*fmt == '-')
|
||||
adjust = LEFT;
|
||||
else if (*fmt == '+')
|
||||
print_sign = YES;
|
||||
else if (*fmt == '#')
|
||||
alternate_form = YES;
|
||||
else if (*fmt == ' ')
|
||||
print_blank = YES;
|
||||
else if (*fmt == '0')
|
||||
pad_char = '0';
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if a width was specified
|
||||
*/
|
||||
if (isdigit((int)*fmt)) {
|
||||
STR_TO_DEC(fmt, min_width);
|
||||
adjust_width = YES;
|
||||
} else if (*fmt == '*') {
|
||||
min_width = va_arg(ap, int);
|
||||
fmt++;
|
||||
adjust_width = YES;
|
||||
if (min_width < 0) {
|
||||
adjust = LEFT;
|
||||
min_width = -min_width;
|
||||
}
|
||||
} else
|
||||
adjust_width = NO;
|
||||
|
||||
/*
|
||||
* Check if a precision was specified
|
||||
*
|
||||
* XXX: an unreasonable amount of precision may be specified
|
||||
* resulting in overflow of num_buf. Currently we
|
||||
* ignore this possibility.
|
||||
*/
|
||||
if (*fmt == '.') {
|
||||
adjust_precision = YES;
|
||||
fmt++;
|
||||
if (isdigit((int)*fmt)) {
|
||||
STR_TO_DEC(fmt, precision);
|
||||
} else if (*fmt == '*') {
|
||||
precision = va_arg(ap, int);
|
||||
fmt++;
|
||||
if (precision < 0)
|
||||
precision = 0;
|
||||
} else
|
||||
precision = 0;
|
||||
} else
|
||||
adjust_precision = NO;
|
||||
} else
|
||||
adjust_precision = adjust_width = NO;
|
||||
|
||||
/*
|
||||
* Modifier check
|
||||
*/
|
||||
switch (*fmt) {
|
||||
case 'L':
|
||||
fmt++;
|
||||
modifier = LM_LONG_DOUBLE;
|
||||
break;
|
||||
case 'I':
|
||||
fmt++;
|
||||
#if SIZEOF_LONG_LONG
|
||||
if (*fmt == '6' && *(fmt+1) == '4') {
|
||||
fmt += 2;
|
||||
modifier = LM_LONG_LONG;
|
||||
} else
|
||||
#endif
|
||||
if (*fmt == '3' && *(fmt+1) == '2') {
|
||||
fmt += 2;
|
||||
modifier = LM_LONG;
|
||||
} else {
|
||||
#ifdef _WIN64
|
||||
modifier = LM_LONG_LONG;
|
||||
#else
|
||||
modifier = LM_LONG;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
fmt++;
|
||||
#if SIZEOF_LONG_LONG
|
||||
if (*fmt == 'l') {
|
||||
fmt++;
|
||||
modifier = LM_LONG_LONG;
|
||||
} else
|
||||
#endif
|
||||
modifier = LM_LONG;
|
||||
break;
|
||||
case 'z':
|
||||
fmt++;
|
||||
modifier = LM_SIZE_T;
|
||||
break;
|
||||
case 'j':
|
||||
fmt++;
|
||||
#if SIZEOF_INTMAX_T
|
||||
modifier = LM_INTMAX_T;
|
||||
#else
|
||||
modifier = LM_SIZE_T;
|
||||
#endif
|
||||
break;
|
||||
case 't':
|
||||
fmt++;
|
||||
#if SIZEOF_PTRDIFF_T
|
||||
modifier = LM_PTRDIFF_T;
|
||||
#else
|
||||
modifier = LM_SIZE_T;
|
||||
#endif
|
||||
break;
|
||||
case 'h':
|
||||
fmt++;
|
||||
if (*fmt == 'h') {
|
||||
fmt++;
|
||||
}
|
||||
/* these are promoted to int, so no break */
|
||||
default:
|
||||
modifier = LM_STD;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Argument extraction and printing.
|
||||
* First we determine the argument type.
|
||||
* Then, we convert the argument to a string.
|
||||
* On exit from the switch, s points to the string that
|
||||
* must be printed, s_len has the length of the string
|
||||
* The precision requirements, if any, are reflected in s_len.
|
||||
*
|
||||
* NOTE: pad_char may be set to '0' because of the 0 flag.
|
||||
* It is reset to ' ' by non-numeric formats
|
||||
*/
|
||||
switch (*fmt) {
|
||||
case 'u':
|
||||
switch(modifier) {
|
||||
default:
|
||||
i_num = (wide_int) va_arg(ap, unsigned int);
|
||||
break;
|
||||
case LM_LONG_DOUBLE:
|
||||
goto fmt_error;
|
||||
case LM_LONG:
|
||||
i_num = (wide_int) va_arg(ap, unsigned long int);
|
||||
break;
|
||||
case LM_SIZE_T:
|
||||
i_num = (wide_int) va_arg(ap, size_t);
|
||||
break;
|
||||
#if SIZEOF_LONG_LONG
|
||||
case LM_LONG_LONG:
|
||||
i_num = (wide_int) va_arg(ap, u_wide_int);
|
||||
break;
|
||||
#endif
|
||||
#if SIZEOF_INTMAX_T
|
||||
case LM_INTMAX_T:
|
||||
i_num = (wide_int) va_arg(ap, uintmax_t);
|
||||
break;
|
||||
#endif
|
||||
#if SIZEOF_PTRDIFF_T
|
||||
case LM_PTRDIFF_T:
|
||||
i_num = (wide_int) va_arg(ap, ptrdiff_t);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* The rest also applies to other integer formats, so fall
|
||||
* into that case.
|
||||
*/
|
||||
case 'd':
|
||||
case 'i':
|
||||
/*
|
||||
* Get the arg if we haven't already.
|
||||
*/
|
||||
if ((*fmt) != 'u') {
|
||||
switch(modifier) {
|
||||
default:
|
||||
i_num = (wide_int) va_arg(ap, int);
|
||||
break;
|
||||
case LM_LONG_DOUBLE:
|
||||
goto fmt_error;
|
||||
case LM_LONG:
|
||||
i_num = (wide_int) va_arg(ap, long int);
|
||||
break;
|
||||
case LM_SIZE_T:
|
||||
#if SIZEOF_SSIZE_T
|
||||
i_num = (wide_int) va_arg(ap, ssize_t);
|
||||
#else
|
||||
i_num = (wide_int) va_arg(ap, size_t);
|
||||
#endif
|
||||
break;
|
||||
#if SIZEOF_LONG_LONG
|
||||
case LM_LONG_LONG:
|
||||
i_num = (wide_int) va_arg(ap, wide_int);
|
||||
break;
|
||||
#endif
|
||||
#if SIZEOF_INTMAX_T
|
||||
case LM_INTMAX_T:
|
||||
i_num = (wide_int) va_arg(ap, intmax_t);
|
||||
break;
|
||||
#endif
|
||||
#if SIZEOF_PTRDIFF_T
|
||||
case LM_PTRDIFF_T:
|
||||
i_num = (wide_int) va_arg(ap, ptrdiff_t);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
s = ap_php_conv_10(i_num, (*fmt) == 'u', &is_negative,
|
||||
&num_buf[NUM_BUF_SIZE], &s_len);
|
||||
FIX_PRECISION(adjust_precision, precision, s, s_len);
|
||||
|
||||
if (*fmt != 'u') {
|
||||
if (is_negative)
|
||||
prefix_char = '-';
|
||||
else if (print_sign)
|
||||
prefix_char = '+';
|
||||
else if (print_blank)
|
||||
prefix_char = ' ';
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 'o':
|
||||
switch(modifier) {
|
||||
default:
|
||||
ui_num = (u_wide_int) va_arg(ap, unsigned int);
|
||||
break;
|
||||
case LM_LONG_DOUBLE:
|
||||
goto fmt_error;
|
||||
case LM_LONG:
|
||||
ui_num = (u_wide_int) va_arg(ap, unsigned long int);
|
||||
break;
|
||||
case LM_SIZE_T:
|
||||
ui_num = (u_wide_int) va_arg(ap, size_t);
|
||||
break;
|
||||
#if SIZEOF_LONG_LONG
|
||||
case LM_LONG_LONG:
|
||||
ui_num = (u_wide_int) va_arg(ap, u_wide_int);
|
||||
break;
|
||||
#endif
|
||||
#if SIZEOF_INTMAX_T
|
||||
case LM_INTMAX_T:
|
||||
ui_num = (u_wide_int) va_arg(ap, uintmax_t);
|
||||
break;
|
||||
#endif
|
||||
#if SIZEOF_PTRDIFF_T
|
||||
case LM_PTRDIFF_T:
|
||||
ui_num = (u_wide_int) va_arg(ap, ptrdiff_t);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
s = ap_php_conv_p2(ui_num, 3, *fmt,
|
||||
&num_buf[NUM_BUF_SIZE], &s_len);
|
||||
FIX_PRECISION(adjust_precision, precision, s, s_len);
|
||||
if (alternate_form && *s != '0') {
|
||||
*--s = '0';
|
||||
s_len++;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 'x':
|
||||
case 'X':
|
||||
switch(modifier) {
|
||||
default:
|
||||
ui_num = (u_wide_int) va_arg(ap, unsigned int);
|
||||
break;
|
||||
case LM_LONG_DOUBLE:
|
||||
goto fmt_error;
|
||||
case LM_LONG:
|
||||
ui_num = (u_wide_int) va_arg(ap, unsigned long int);
|
||||
break;
|
||||
case LM_SIZE_T:
|
||||
ui_num = (u_wide_int) va_arg(ap, size_t);
|
||||
break;
|
||||
#if SIZEOF_LONG_LONG
|
||||
case LM_LONG_LONG:
|
||||
ui_num = (u_wide_int) va_arg(ap, u_wide_int);
|
||||
break;
|
||||
#endif
|
||||
#if SIZEOF_INTMAX_T
|
||||
case LM_INTMAX_T:
|
||||
ui_num = (u_wide_int) va_arg(ap, uintmax_t);
|
||||
break;
|
||||
#endif
|
||||
#if SIZEOF_PTRDIFF_T
|
||||
case LM_PTRDIFF_T:
|
||||
ui_num = (u_wide_int) va_arg(ap, ptrdiff_t);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
s = ap_php_conv_p2(ui_num, 4, *fmt,
|
||||
&num_buf[NUM_BUF_SIZE], &s_len);
|
||||
FIX_PRECISION(adjust_precision, precision, s, s_len);
|
||||
if (alternate_form && i_num != 0) {
|
||||
*--s = *fmt; /* 'x' or 'X' */
|
||||
*--s = '0';
|
||||
s_len += 2;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 's':
|
||||
case 'v':
|
||||
s = va_arg(ap, char *);
|
||||
if (s != NULL) {
|
||||
s_len = strlen(s);
|
||||
if (adjust_precision && precision < s_len)
|
||||
s_len = precision;
|
||||
} else {
|
||||
s = S_NULL;
|
||||
s_len = S_NULL_LEN;
|
||||
}
|
||||
pad_char = ' ';
|
||||
break;
|
||||
|
||||
|
||||
case 'f':
|
||||
case 'F':
|
||||
case 'e':
|
||||
case 'E':
|
||||
switch(modifier) {
|
||||
case LM_LONG_DOUBLE:
|
||||
fp_num = (double) va_arg(ap, long double);
|
||||
break;
|
||||
case LM_STD:
|
||||
fp_num = va_arg(ap, double);
|
||||
break;
|
||||
default:
|
||||
goto fmt_error;
|
||||
}
|
||||
|
||||
if (zend_isnan(fp_num)) {
|
||||
s = "nan";
|
||||
s_len = 3;
|
||||
} else if (zend_isinf(fp_num)) {
|
||||
s = "inf";
|
||||
s_len = 3;
|
||||
} else {
|
||||
#ifdef HAVE_LOCALE_H
|
||||
if (!lconv) {
|
||||
lconv = localeconv();
|
||||
}
|
||||
#endif
|
||||
s = php_conv_fp((*fmt == 'f')?'F':*fmt, fp_num, alternate_form,
|
||||
(adjust_precision == NO) ? FLOAT_DIGITS : precision,
|
||||
(*fmt == 'f')?LCONV_DECIMAL_POINT:'.',
|
||||
&is_negative, &num_buf[1], &s_len);
|
||||
if (is_negative)
|
||||
prefix_char = '-';
|
||||
else if (print_sign)
|
||||
prefix_char = '+';
|
||||
else if (print_blank)
|
||||
prefix_char = ' ';
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 'g':
|
||||
case 'k':
|
||||
case 'G':
|
||||
case 'H':
|
||||
switch(modifier) {
|
||||
case LM_LONG_DOUBLE:
|
||||
fp_num = (double) va_arg(ap, long double);
|
||||
break;
|
||||
case LM_STD:
|
||||
fp_num = va_arg(ap, double);
|
||||
break;
|
||||
default:
|
||||
goto fmt_error;
|
||||
}
|
||||
|
||||
if (zend_isnan(fp_num)) {
|
||||
s = "NAN";
|
||||
s_len = 3;
|
||||
break;
|
||||
} else if (zend_isinf(fp_num)) {
|
||||
if (fp_num > 0) {
|
||||
s = "INF";
|
||||
s_len = 3;
|
||||
} else {
|
||||
s = "-INF";
|
||||
s_len = 4;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (adjust_precision == NO)
|
||||
precision = FLOAT_DIGITS;
|
||||
else if (precision == 0)
|
||||
precision = 1;
|
||||
/*
|
||||
* * We use &num_buf[ 1 ], so that we have room for the sign
|
||||
*/
|
||||
#ifdef HAVE_LOCALE_H
|
||||
if (!lconv) {
|
||||
lconv = localeconv();
|
||||
}
|
||||
#endif
|
||||
s = php_gcvt(fp_num, precision, (*fmt=='H' || *fmt == 'k') ? '.' : LCONV_DECIMAL_POINT, (*fmt == 'G' || *fmt == 'H')?'E':'e', &num_buf[1]);
|
||||
if (*s == '-')
|
||||
prefix_char = *s++;
|
||||
else if (print_sign)
|
||||
prefix_char = '+';
|
||||
else if (print_blank)
|
||||
prefix_char = ' ';
|
||||
|
||||
s_len = strlen(s);
|
||||
|
||||
if (alternate_form && (q = strchr(s, '.')) == NULL)
|
||||
s[s_len++] = '.';
|
||||
break;
|
||||
|
||||
|
||||
case 'c':
|
||||
char_buf[0] = (char) (va_arg(ap, int));
|
||||
s = &char_buf[0];
|
||||
s_len = 1;
|
||||
pad_char = ' ';
|
||||
break;
|
||||
|
||||
|
||||
case '%':
|
||||
char_buf[0] = '%';
|
||||
s = &char_buf[0];
|
||||
s_len = 1;
|
||||
pad_char = ' ';
|
||||
break;
|
||||
|
||||
|
||||
case 'n':
|
||||
*(va_arg(ap, int *)) = xbuf->len;
|
||||
goto skip_output;
|
||||
|
||||
/*
|
||||
* Always extract the argument as a "char *" pointer. We
|
||||
* should be using "void *" but there are still machines
|
||||
* that don't understand it.
|
||||
* If the pointer size is equal to the size of an unsigned
|
||||
* integer we convert the pointer to a hex number, otherwise
|
||||
* we print "%p" to indicate that we don't handle "%p".
|
||||
*/
|
||||
case 'p':
|
||||
if (sizeof(char *) <= sizeof(u_wide_int)) {
|
||||
ui_num = (u_wide_int)((size_t) va_arg(ap, char *));
|
||||
s = ap_php_conv_p2(ui_num, 4, 'x',
|
||||
&num_buf[NUM_BUF_SIZE], &s_len);
|
||||
if (ui_num != 0) {
|
||||
*--s = 'x';
|
||||
*--s = '0';
|
||||
s_len += 2;
|
||||
}
|
||||
} else {
|
||||
s = "%p";
|
||||
s_len = 2;
|
||||
}
|
||||
pad_char = ' ';
|
||||
break;
|
||||
|
||||
|
||||
case NUL:
|
||||
/*
|
||||
* The last character of the format string was %.
|
||||
* We ignore it.
|
||||
*/
|
||||
continue;
|
||||
|
||||
|
||||
fmt_error:
|
||||
/*
|
||||
* The default case is for unrecognized %'s.
|
||||
* We print %<char> to help the user identify what
|
||||
* option is not understood.
|
||||
* This is also useful in case the user wants to pass
|
||||
* the output of format_converter to another function
|
||||
* that understands some other %<char> (like syslog).
|
||||
* Note that we can't point s inside fmt because the
|
||||
* unknown <char> could be preceded by width etc.
|
||||
*/
|
||||
default:
|
||||
char_buf[0] = '%';
|
||||
char_buf[1] = *fmt;
|
||||
s = char_buf;
|
||||
s_len = 2;
|
||||
pad_char = ' ';
|
||||
break;
|
||||
}
|
||||
|
||||
if (prefix_char != NUL) {
|
||||
*--s = prefix_char;
|
||||
s_len++;
|
||||
}
|
||||
if (adjust_width && adjust == RIGHT && min_width > s_len) {
|
||||
if (pad_char == '0' && prefix_char != NUL) {
|
||||
INS_CHAR(xbuf, *s);
|
||||
s++;
|
||||
s_len--;
|
||||
min_width--;
|
||||
}
|
||||
PAD(xbuf, min_width - s_len, pad_char);
|
||||
}
|
||||
/*
|
||||
* Print the string s.
|
||||
*/
|
||||
INS_STRING(xbuf, s, s_len);
|
||||
|
||||
if (adjust_width && adjust == LEFT && min_width > s_len)
|
||||
PAD(xbuf, min_width - s_len, pad_char);
|
||||
}
|
||||
skip_output:
|
||||
fmt++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* This is the general purpose conversion function.
|
||||
*/
|
||||
int vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap) /* {{{ */
|
||||
{
|
||||
smart_str xbuf;
|
||||
memset(&xbuf, 0, sizeof(xbuf));
|
||||
|
||||
xbuf_format_converter(&xbuf, format, ap);
|
||||
|
||||
if (max_len && xbuf.len > max_len) {
|
||||
xbuf.len = max_len;
|
||||
}
|
||||
smart_str_0(&xbuf);
|
||||
|
||||
*pbuf = xbuf.c;
|
||||
|
||||
return xbuf.len;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
int spprintf(char **pbuf, size_t max_len, const char *format, ...) /* {{{ */
|
||||
{
|
||||
int cc;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
cc = vspprintf(pbuf, max_len, format, ap);
|
||||
va_end(ap);
|
||||
return (cc);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: sw=4 ts=4 fdm=marker
|
||||
* vim<600: sw=4 ts=4
|
||||
*/
|
@ -27,30 +27,22 @@
|
||||
#include <my_global.h>
|
||||
#include "m_string.h"
|
||||
|
||||
#if defined(MC68000) && defined(DS90)
|
||||
/**
|
||||
\fn char *strcend
|
||||
\brief returns a pointer to the first occurence of specified stopchar
|
||||
\param str char *
|
||||
\param stopchar char
|
||||
|
||||
char *strcend(const char *s, pchar c)
|
||||
{
|
||||
asm(" movl 4(a7),a0 ");
|
||||
asm(" movl 8(a7),d1 ");
|
||||
asm(".L2: movb (a0)+,d0 ");
|
||||
asm(" cmpb d0,d1 ");
|
||||
asm(" beq .L1 ");
|
||||
asm(" tstb d0 ");
|
||||
asm(" bne .L2 ");
|
||||
asm(".L1: movl a0,d0 ");
|
||||
asm(" subql #1,d0 ");
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
char *strcend(register const char *s, register pchar c)
|
||||
returns a poimter to the first occurence of stopchar or to null char,
|
||||
if stopchar wasn't found.
|
||||
*/
|
||||
char *strcend(register const char *str, register char stopchar)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (*s == (char) c) return (char*) s;
|
||||
if (!*s++) return (char*) s-1;
|
||||
if (*str == stopchar)
|
||||
return (char*) str;
|
||||
if (!*str++)
|
||||
return (char*) str-1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include <my_global.h>
|
||||
#include "m_string.h"
|
||||
|
||||
my_string strfill(my_string s,uint len,pchar fill)
|
||||
my_string strfill(my_string s, size_t len, pchar fill)
|
||||
{
|
||||
while (len--) *s++ = fill;
|
||||
*(s) = '\0';
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include <m_string.h>
|
||||
|
||||
my_bool init_dynamic_string(DYNAMIC_STRING *str, const char *init_str,
|
||||
uint init_alloc, uint alloc_increment)
|
||||
size_t init_alloc, size_t alloc_increment)
|
||||
{
|
||||
uint length;
|
||||
DBUG_ENTER("init_dynamic_string");
|
||||
@ -97,12 +97,12 @@ my_bool dynstr_append(DYNAMIC_STRING *str, const char *append)
|
||||
|
||||
|
||||
my_bool dynstr_append_mem(DYNAMIC_STRING *str, const char *append,
|
||||
uint length)
|
||||
size_t length)
|
||||
{
|
||||
char *new_ptr;
|
||||
if (str->length+length >= str->max_length)
|
||||
{
|
||||
uint new_length=(str->length+length+str->alloc_increment)/
|
||||
size_t new_length=(str->length+length+str->alloc_increment)/
|
||||
str->alloc_increment;
|
||||
new_length*=str->alloc_increment;
|
||||
if (!(new_ptr=(char*) my_realloc(str->str,new_length,MYF(MY_WME))))
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
#ifdef BAD_STRING_COMPILER
|
||||
|
||||
char *strmake(char *dst,const char *src,uint length)
|
||||
char *strmake(char *dst,const char *src, size_t length)
|
||||
{
|
||||
reg1 char *res;
|
||||
|
||||
@ -44,7 +44,7 @@ char *strmake(char *dst,const char *src,uint length)
|
||||
#define strmake strmake_overlapp /* Use orginal for overlapping str */
|
||||
#endif
|
||||
|
||||
char *strmake(register char *dst, register const char *src, uint length)
|
||||
char *strmake(register char *dst, register const char *src, size_t length)
|
||||
{
|
||||
while (length--)
|
||||
if (! (*dst++ = *src++))
|
||||
|
210
libmysql/strto.c
Normal file
210
libmysql/strto.c
Normal file
@ -0,0 +1,210 @@
|
||||
/* 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 */
|
||||
|
||||
/*
|
||||
strtol,strtoul,strtoll,strtoull
|
||||
convert string to long, unsigned long, long long or unsigned long long.
|
||||
strtoxx(char *src,char **ptr,int base)
|
||||
converts the string pointed to by src to an long of appropriate long and
|
||||
returnes it. It skips leading spaces and tabs (but not newlines, formfeeds,
|
||||
backspaces), then it accepts an optional sign and a sequence of digits
|
||||
in the specified radix.
|
||||
If the value of ptr is not (char **)NULL, a pointer to the character
|
||||
terminating the scan is returned in the location pointed to by ptr.
|
||||
Trailing spaces will NOT be skipped.
|
||||
|
||||
If an error is detected, the result will be LONG_MIN, 0 or LONG_MAX,
|
||||
(or LONGLONG..) and errno will be set to
|
||||
EDOM if there are no digits
|
||||
ERANGE if the result would overflow.
|
||||
the ptr will be set to src.
|
||||
This file is based on the strtol from the the GNU C Library.
|
||||
it can be compiled with the UNSIGNED and/or LONGLONG flag set
|
||||
*/
|
||||
|
||||
#define strtoll glob_strtoll /* Fix for True64 */
|
||||
|
||||
#include <global.h>
|
||||
#include "m_string.h"
|
||||
#include "m_ctype.h"
|
||||
#include "my_sys.h" /* defines errno */
|
||||
#include <errno.h>
|
||||
|
||||
#undef strtoull
|
||||
#undef strtoll
|
||||
#undef strtoul
|
||||
#undef strtol
|
||||
#ifdef USE_LONGLONG
|
||||
#define UTYPE_MAX (~(ulonglong) 0)
|
||||
#define TYPE_MIN LONGLONG_MIN
|
||||
#define TYPE_MAX LONGLONG_MAX
|
||||
#define longtype longlong
|
||||
#define ulongtype ulonglong
|
||||
#ifdef USE_UNSIGNED
|
||||
#define function ulongtype strtoull
|
||||
#else
|
||||
#define function longtype strtoll
|
||||
#endif
|
||||
#else
|
||||
#define UTYPE_MAX (ulong) ~0L
|
||||
#define TYPE_MIN LONG_MIN
|
||||
#define TYPE_MAX LONG_MAX
|
||||
#define longtype long
|
||||
#define ulongtype unsigned long
|
||||
#ifdef USE_UNSIGNED
|
||||
#define function ulongtype strtoul
|
||||
#else
|
||||
#define function longtype strtol
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Convert NPTR to an `unsigned long int' or `long int' in base BASE.
|
||||
If BASE is 0 the base is determined by the presence of a leading
|
||||
zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal.
|
||||
If BASE is < 2 or > 36, it is reset to 10.
|
||||
If ENDPTR is not NULL, a pointer to the character after the last
|
||||
one converted is stored in *ENDPTR. */
|
||||
|
||||
|
||||
function (const char *nptr,char **endptr,int base)
|
||||
{
|
||||
int negative;
|
||||
register ulongtype cutoff;
|
||||
register unsigned int cutlim;
|
||||
register ulongtype i;
|
||||
register const char *s;
|
||||
register unsigned char c;
|
||||
const char *save;
|
||||
int overflow;
|
||||
|
||||
if (base < 0 || base == 1 || base > 36)
|
||||
base = 10;
|
||||
|
||||
s = nptr;
|
||||
|
||||
/* Skip white space. */
|
||||
while (isspace (*s))
|
||||
++s;
|
||||
if (*s == '\0')
|
||||
{
|
||||
goto noconv;
|
||||
}
|
||||
|
||||
/* Check for a sign. */
|
||||
if (*s == '-')
|
||||
{
|
||||
negative = 1;
|
||||
++s;
|
||||
}
|
||||
else if (*s == '+')
|
||||
{
|
||||
negative = 0;
|
||||
++s;
|
||||
}
|
||||
else
|
||||
negative = 0;
|
||||
|
||||
if (base == 16 && s[0] == '0' && toupper (s[1]) == 'X')
|
||||
s += 2;
|
||||
|
||||
/* If BASE is zero, figure it out ourselves. */
|
||||
if (base == 0)
|
||||
{
|
||||
if (*s == '0')
|
||||
{
|
||||
if (toupper (s[1]) == 'X')
|
||||
{
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
else
|
||||
base = 8;
|
||||
}
|
||||
else
|
||||
base = 10;
|
||||
}
|
||||
|
||||
/* Save the pointer so we can check later if anything happened. */
|
||||
save = s;
|
||||
|
||||
cutoff = UTYPE_MAX / (unsigned long int) base;
|
||||
cutlim = (uint) (UTYPE_MAX % (unsigned long int) base);
|
||||
|
||||
overflow = 0;
|
||||
i = 0;
|
||||
for (c = *s; c != '\0'; c = *++s)
|
||||
{
|
||||
if (isdigit (c))
|
||||
c -= '0';
|
||||
else if (isalpha (c))
|
||||
c = toupper (c) - 'A' + 10;
|
||||
else
|
||||
break;
|
||||
if (c >= base)
|
||||
break;
|
||||
/* Check for overflow. */
|
||||
if (i > cutoff || (i == cutoff && c > cutlim))
|
||||
overflow = 1;
|
||||
else
|
||||
{
|
||||
i *= (ulongtype) base;
|
||||
i += c;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if anything actually happened. */
|
||||
if (s == save)
|
||||
goto noconv;
|
||||
|
||||
/* Store in ENDPTR the address of one character
|
||||
past the last character we converted. */
|
||||
if (endptr != NULL)
|
||||
*endptr = (char *) s;
|
||||
|
||||
#ifndef USE_UNSIGNED
|
||||
/* Check for a value that is within the range of
|
||||
`unsigned long int', but outside the range of `long int'. */
|
||||
if (negative)
|
||||
{
|
||||
if (i > (ulongtype) TYPE_MIN)
|
||||
overflow = 1;
|
||||
}
|
||||
else if (i > (ulongtype) TYPE_MAX)
|
||||
overflow = 1;
|
||||
#endif
|
||||
|
||||
if (overflow)
|
||||
{
|
||||
my_errno=ERANGE;
|
||||
#ifdef USE_UNSIGNED
|
||||
return UTYPE_MAX;
|
||||
#else
|
||||
return negative ? TYPE_MIN : TYPE_MAX;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return the result of the appropriate sign. */
|
||||
return (negative ? -((longtype) i) : (longtype) i);
|
||||
|
||||
noconv:
|
||||
/* There was no number to convert. */
|
||||
my_errno=EDOM;
|
||||
if (endptr != NULL)
|
||||
*endptr = (char *) nptr;
|
||||
return 0L;
|
||||
}
|
@ -21,5 +21,179 @@
|
||||
#include <m_string.h>
|
||||
#if !defined(HAVE_STRTOLL) && defined(HAVE_LONG_LONG)
|
||||
#define USE_LONGLONG
|
||||
#include "strto.c"
|
||||
|
||||
#define strtoll glob_strtoll /* Fix for True64 */
|
||||
|
||||
#include <global.h>
|
||||
#include "m_string.h"
|
||||
#include "m_ctype.h"
|
||||
#include "my_sys.h" /* defines errno */
|
||||
#include <errno.h>
|
||||
|
||||
#undef strtoull
|
||||
#undef strtoll
|
||||
#undef strtoul
|
||||
#undef strtol
|
||||
#ifdef USE_LONGLONG
|
||||
#define UTYPE_MAX (~(ulonglong) 0)
|
||||
#define TYPE_MIN LONGLONG_MIN
|
||||
#define TYPE_MAX LONGLONG_MAX
|
||||
#define longtype longlong
|
||||
#define ulongtype ulonglong
|
||||
#ifdef USE_UNSIGNED
|
||||
#define function ulongtype strtoull
|
||||
#else
|
||||
#define function longtype strtoll
|
||||
#endif
|
||||
#else
|
||||
#define UTYPE_MAX (ulong) ~0L
|
||||
#define TYPE_MIN LONG_MIN
|
||||
#define TYPE_MAX LONG_MAX
|
||||
#define longtype long
|
||||
#define ulongtype unsigned long
|
||||
#ifdef USE_UNSIGNED
|
||||
#define function ulongtype strtoul
|
||||
#else
|
||||
#define function longtype strtol
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Convert NPTR to an `unsigned long int' or `long int' in base BASE.
|
||||
If BASE is 0 the base is determined by the presence of a leading
|
||||
zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal.
|
||||
If BASE is < 2 or > 36, it is reset to 10.
|
||||
If ENDPTR is not NULL, a pointer to the character after the last
|
||||
one converted is stored in *ENDPTR. */
|
||||
|
||||
|
||||
function (const char *nptr,char **endptr,int base)
|
||||
{
|
||||
int negative;
|
||||
register ulongtype cutoff;
|
||||
register unsigned int cutlim;
|
||||
register ulongtype i;
|
||||
register const char *s;
|
||||
register unsigned char c;
|
||||
const char *save;
|
||||
int overflow;
|
||||
|
||||
if (base < 0 || base == 1 || base > 36)
|
||||
base = 10;
|
||||
|
||||
s = nptr;
|
||||
|
||||
/* Skip white space. */
|
||||
while (isspace (*s))
|
||||
++s;
|
||||
if (*s == '\0')
|
||||
{
|
||||
goto noconv;
|
||||
}
|
||||
|
||||
/* Check for a sign. */
|
||||
if (*s == '-')
|
||||
{
|
||||
negative = 1;
|
||||
++s;
|
||||
}
|
||||
else if (*s == '+')
|
||||
{
|
||||
negative = 0;
|
||||
++s;
|
||||
}
|
||||
else
|
||||
negative = 0;
|
||||
|
||||
if (base == 16 && s[0] == '0' && toupper (s[1]) == 'X')
|
||||
s += 2;
|
||||
|
||||
/* If BASE is zero, figure it out ourselves. */
|
||||
if (base == 0)
|
||||
{
|
||||
if (*s == '0')
|
||||
{
|
||||
if (toupper (s[1]) == 'X')
|
||||
{
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
else
|
||||
base = 8;
|
||||
}
|
||||
else
|
||||
base = 10;
|
||||
}
|
||||
|
||||
/* Save the pointer so we can check later if anything happened. */
|
||||
save = s;
|
||||
|
||||
cutoff = UTYPE_MAX / (unsigned long int) base;
|
||||
cutlim = (uint) (UTYPE_MAX % (unsigned long int) base);
|
||||
|
||||
overflow = 0;
|
||||
i = 0;
|
||||
for (c = *s; c != '\0'; c = *++s)
|
||||
{
|
||||
if (isdigit (c))
|
||||
c -= '0';
|
||||
else if (isalpha (c))
|
||||
c = toupper (c) - 'A' + 10;
|
||||
else
|
||||
break;
|
||||
if (c >= base)
|
||||
break;
|
||||
/* Check for overflow. */
|
||||
if (i > cutoff || (i == cutoff && c > cutlim))
|
||||
overflow = 1;
|
||||
else
|
||||
{
|
||||
i *= (ulongtype) base;
|
||||
i += c;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if anything actually happened. */
|
||||
if (s == save)
|
||||
goto noconv;
|
||||
|
||||
/* Store in ENDPTR the address of one character
|
||||
past the last character we converted. */
|
||||
if (endptr != NULL)
|
||||
*endptr = (char *) s;
|
||||
|
||||
#ifndef USE_UNSIGNED
|
||||
/* Check for a value that is within the range of
|
||||
`unsigned long int', but outside the range of `long int'. */
|
||||
if (negative)
|
||||
{
|
||||
if (i > (ulongtype) TYPE_MIN)
|
||||
overflow = 1;
|
||||
}
|
||||
else if (i > (ulongtype) TYPE_MAX)
|
||||
overflow = 1;
|
||||
#endif
|
||||
|
||||
if (overflow)
|
||||
{
|
||||
my_errno=ERANGE;
|
||||
#ifdef USE_UNSIGNED
|
||||
return UTYPE_MAX;
|
||||
#else
|
||||
return negative ? TYPE_MIN : TYPE_MAX;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return the result of the appropriate sign. */
|
||||
return (negative ? -((longtype) i) : (longtype) i);
|
||||
|
||||
noconv:
|
||||
/* There was no number to convert. */
|
||||
my_errno=EDOM;
|
||||
if (endptr != NULL)
|
||||
*endptr = (char *) nptr;
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
48
libmysql/strxnmov.c
Normal file
48
libmysql/strxnmov.c
Normal file
@ -0,0 +1,48 @@
|
||||
/* File : strxnmov.c
|
||||
Author : Richard A. O'Keefe.
|
||||
Updated: 2 June 1984
|
||||
Defines: strxnmov()
|
||||
|
||||
strxnmov(dst, len, src1, ..., srcn, NullS)
|
||||
moves the first len characters of the concatenation of src1,...,srcn
|
||||
to dst. If there aren't that many characters, a NUL character will
|
||||
be added to the end of dst to terminate it properly. This gives the
|
||||
same effect as calling strxcpy(buff, src1, ..., srcn, NullS) with a
|
||||
large enough buffer, and then calling strnmov(dst, buff, len).
|
||||
It is just like strnmov except that it concatenates multiple sources.
|
||||
Beware: the last argument should be the null character pointer.
|
||||
Take VERY great care not to omit it! Also be careful to use NullS
|
||||
and NOT to use 0, as on some machines 0 is not the same size as a
|
||||
character pointer, or not the same bit pattern as NullS.
|
||||
|
||||
Note: strxnmov is like strnmov in that it moves up to len
|
||||
characters; dst will be padded on the right with one NUL characters if
|
||||
needed.
|
||||
*/
|
||||
|
||||
#include <my_global.h>
|
||||
#include "m_string.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
char *strxnmov(char *dst, size_t len, const char *src, ...)
|
||||
{
|
||||
va_list pvar;
|
||||
char *end_of_dst=dst+len;
|
||||
|
||||
va_start(pvar,src);
|
||||
while (src != NullS)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (dst == end_of_dst)
|
||||
goto end;
|
||||
}
|
||||
while ((*dst++ = *src++));
|
||||
dst--;
|
||||
src = va_arg(pvar, char *);
|
||||
}
|
||||
*dst=0;
|
||||
end:
|
||||
va_end(pvar);
|
||||
return dst;
|
||||
}
|
@ -101,7 +101,7 @@ int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line)
|
||||
abort();
|
||||
}
|
||||
mp->count--;
|
||||
#ifdef __WIN__
|
||||
#ifdef _WIN32
|
||||
pthread_mutex_unlock(&mp->mutex);
|
||||
error=0;
|
||||
#else
|
||||
@ -112,7 +112,7 @@ int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line)
|
||||
fflush(stderr);
|
||||
abort();
|
||||
}
|
||||
#endif /* __WIN__ */
|
||||
#endif /* _WIN32 */
|
||||
pthread_mutex_unlock(&mp->global);
|
||||
return error;
|
||||
}
|
||||
@ -216,7 +216,7 @@ int safe_mutex_destroy(safe_mutex_t *mp, const char *file, uint line)
|
||||
fflush(stderr);
|
||||
abort();
|
||||
}
|
||||
#ifdef __WIN__
|
||||
#ifdef _WIN32
|
||||
pthread_mutex_destroy(&mp->global);
|
||||
pthread_mutex_destroy(&mp->mutex);
|
||||
#else
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
int find_type(my_string x, TYPELIB *typelib, uint full_name)
|
||||
{
|
||||
int find,pos,findpos;
|
||||
int find,pos,findpos= 0;
|
||||
reg1 my_string i;
|
||||
reg2 const char *j;
|
||||
DBUG_ENTER("find_type");
|
||||
|
@ -22,10 +22,9 @@
|
||||
the file descriptior.
|
||||
*/
|
||||
|
||||
#include <my_global.h>
|
||||
|
||||
#ifndef HAVE_VIO /* is Vio suppored by the Vio lib ? */
|
||||
|
||||
#include <my_global.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <violite.h>
|
||||
@ -42,7 +41,12 @@
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#if !defined(MSDOS) && !defined(__WIN__) && !defined(HAVE_BROKEN_NETINET_INCLUDES) && !defined(__BEOS__) && !defined(__FreeBSD__)
|
||||
#ifdef _WIN32
|
||||
#define socklen_t int
|
||||
#pragma comment (lib, "ws2_32")
|
||||
#endif
|
||||
|
||||
#if !defined(MSDOS) && !defined(_WIN32) && !defined(HAVE_BROKEN_NETINET_INCLUDES) && !defined(__BEOS__) && !defined(__FreeBSD__)
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#if !defined(alpha_linux_port)
|
||||
@ -54,28 +58,13 @@
|
||||
#define ioctlsocket ioctl
|
||||
#endif /* defined(__EMX__) */
|
||||
|
||||
#if defined(MSDOS) || defined(__WIN__)
|
||||
#if defined(MSDOS) || defined(_WIN32)
|
||||
#define O_NONBLOCK 1 /* For emulation of fcntl() */
|
||||
#endif
|
||||
#ifndef EWOULDBLOCK
|
||||
#define SOCKET_EWOULDBLOCK SOCKET_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;
|
||||
@ -95,6 +84,38 @@ static void vio_reset(Vio* vio, enum enum_vio_type type,
|
||||
vio->localhost= localhost;
|
||||
}
|
||||
|
||||
void vio_timeout(Vio *vio, int type, uint seconds)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
uint timeout= seconds * 1000; /* milli secs */
|
||||
#else
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec= seconds;
|
||||
timeout.tv_usec= 0;
|
||||
#endif
|
||||
|
||||
if (setsockopt(vio->sd, SOL_SOCKET, type,
|
||||
#ifdef _WIN32
|
||||
(const char *)&timeout,
|
||||
#else
|
||||
(const void *)&timeout,
|
||||
#endif
|
||||
sizeof(timeout)))
|
||||
{
|
||||
DBUG_PRINT("error", ("setsockopt failed. Errno: %d", errno));
|
||||
}
|
||||
}
|
||||
|
||||
void vio_read_timeout(Vio *vio, uint seconds)
|
||||
{
|
||||
vio_timeout(vio, SO_RCVTIMEO, seconds);
|
||||
}
|
||||
|
||||
void vio_write_timeout(Vio *vio, uint seconds)
|
||||
{
|
||||
vio_timeout(vio, SO_SNDTIMEO, seconds);
|
||||
}
|
||||
|
||||
/* 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)
|
||||
@ -108,14 +129,14 @@ Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost)
|
||||
sprintf(vio->desc,
|
||||
(vio->type == VIO_TYPE_SOCKET ? "socket (%d)" : "TCP/IP (%d)"),
|
||||
vio->sd);
|
||||
#if !defined(___WIN__) && !defined(__EMX__) && !defined(OS2)
|
||||
#if !defined(__WIN32) && !defined(__EMX__) && !defined(OS2)
|
||||
#if !defined(NO_FCNTL_NONBLOCK)
|
||||
vio->fcntl_mode = fcntl(sd, F_GETFL);
|
||||
#elif defined(HAVE_SYS_IOCTL_H) /* hpux */
|
||||
/* Non blocking sockets doesn't work good on HPUX 11.0 */
|
||||
(void) ioctl(sd,FIOSNBIO,0);
|
||||
#endif
|
||||
#else /* !defined(__WIN__) && !defined(__EMX__) */
|
||||
#else /* !defined(_WIN32) && !defined(__EMX__) */
|
||||
{
|
||||
/* set to blocking mode by default */
|
||||
ulong arg=0, r;
|
||||
@ -127,7 +148,7 @@ Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost)
|
||||
}
|
||||
|
||||
|
||||
#ifdef __WIN__
|
||||
#ifdef _WIN32
|
||||
|
||||
Vio *vio_new_win32pipe(HANDLE hPipe)
|
||||
{
|
||||
@ -166,7 +187,7 @@ int vio_read(Vio * vio, gptr buf, int size)
|
||||
int r;
|
||||
DBUG_ENTER("vio_read");
|
||||
DBUG_PRINT("enter", ("sd=%d size=%d", vio->sd, size));
|
||||
#if defined( __WIN__) || defined(OS2)
|
||||
#if defined( _WIN32) || defined(OS2)
|
||||
if (vio->type == VIO_TYPE_NAMEDPIPE)
|
||||
{
|
||||
DWORD length;
|
||||
@ -183,7 +204,7 @@ int vio_read(Vio * vio, gptr buf, int size)
|
||||
#else
|
||||
errno=0; /* For linux */
|
||||
r = read(vio->sd, buf, size);
|
||||
#endif /* __WIN__ */
|
||||
#endif /* _WIN32 */
|
||||
#ifndef DBUG_OFF
|
||||
if (r < 0)
|
||||
{
|
||||
@ -200,7 +221,7 @@ int vio_write(Vio * vio, const gptr buf, int size)
|
||||
int r;
|
||||
DBUG_ENTER("vio_write");
|
||||
DBUG_PRINT("enter", ("sd=%d size=%d", vio->sd, size));
|
||||
#if defined( __WIN__) || defined(OS2)
|
||||
#if defined( _WIN32) || defined(OS2)
|
||||
if ( vio->type == VIO_TYPE_NAMEDPIPE)
|
||||
{
|
||||
DWORD length;
|
||||
@ -216,7 +237,7 @@ int vio_write(Vio * vio, const gptr buf, int size)
|
||||
r = send(vio->sd, buf, size,0);
|
||||
#else
|
||||
r = write(vio->sd, buf, size);
|
||||
#endif /* __WIN__ */
|
||||
#endif /* _WIN32 */
|
||||
#ifndef DBUG_OFF
|
||||
if (r < 0)
|
||||
{
|
||||
@ -234,7 +255,7 @@ int vio_blocking(Vio * vio, my_bool set_blocking_mode)
|
||||
DBUG_ENTER("vio_blocking");
|
||||
DBUG_PRINT("enter", ("set_blocking_mode: %d", (int) set_blocking_mode));
|
||||
|
||||
#if !defined(___WIN__) && !defined(__EMX__) && !defined(OS2)
|
||||
#if !defined(__WIN32) && !defined(__EMX__) && !defined(OS2)
|
||||
#if !defined(NO_FCNTL_NONBLOCK)
|
||||
|
||||
if (vio->sd >= 0)
|
||||
@ -248,7 +269,7 @@ int vio_blocking(Vio * vio, my_bool set_blocking_mode)
|
||||
r = fcntl(vio->sd, F_SETFL, vio->fcntl_mode);
|
||||
}
|
||||
#endif /* !defined(NO_FCNTL_NONBLOCK) */
|
||||
#else /* !defined(__WIN__) && !defined(__EMX__) */
|
||||
#else /* !defined(_WIN32) && !defined(__EMX__) */
|
||||
#ifndef __EMX__
|
||||
if (vio->type != VIO_TYPE_NAMEDPIPE)
|
||||
#endif
|
||||
@ -268,7 +289,7 @@ int vio_blocking(Vio * vio, my_bool set_blocking_mode)
|
||||
if (old_fcntl != vio->fcntl_mode)
|
||||
r = ioctlsocket(vio->sd,FIONBIO,(void*) &arg, sizeof(arg));
|
||||
}
|
||||
#endif /* !defined(__WIN__) && !defined(__EMX__) */
|
||||
#endif /* !defined(_WIN32) && !defined(__EMX__) */
|
||||
DBUG_RETURN(r);
|
||||
}
|
||||
|
||||
@ -339,7 +360,7 @@ int vio_close(Vio * vio)
|
||||
{
|
||||
int r;
|
||||
DBUG_ENTER("vio_close");
|
||||
#ifdef __WIN__
|
||||
#ifdef _WIN32
|
||||
if (vio->type == VIO_TYPE_NAMEDPIPE)
|
||||
{
|
||||
#if defined(__NT__) && defined(MYSQL_SERVER)
|
||||
@ -349,7 +370,7 @@ int vio_close(Vio * vio)
|
||||
r=CloseHandle(vio->hPipe);
|
||||
}
|
||||
else if (vio->type != VIO_CLOSED)
|
||||
#endif /* __WIN__ */
|
||||
#endif /* _WIN32 */
|
||||
{
|
||||
r=0;
|
||||
if (shutdown(vio->sd,2))
|
||||
|
30
mysql_config/CMakeLists.txt
Normal file
30
mysql_config/CMakeLists.txt
Normal file
@ -0,0 +1,30 @@
|
||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
|
||||
|
||||
# Figure out additional libraries for use with -lmysql
|
||||
|
||||
FOREACH (dep ${libmysql_LIB_DEPENDS})
|
||||
STRING(REGEX MATCH "^-.*$" out "${dep}")
|
||||
IF(out)
|
||||
SET(extra_dynamic_LDFLAGS "${extra_dynamic_LDFLAGS} ${dep}")
|
||||
ENDIF(out)
|
||||
ENDFOREACH(dep)
|
||||
|
||||
IF(UNIX)
|
||||
IF(DL_LIBRARY)
|
||||
SET(extra_dynamic_LDFLAGS "${extra_dynamic_LDFLAGS} -ldl")
|
||||
ENDIF(DL_LIBRARY)
|
||||
IF(MATH_LIBRARY)
|
||||
SET(extra_dynamic_LDFLAGS "${extra_dynamic_LDFLAGS} -lm")
|
||||
ENDIF(MATH_LIBRARY)
|
||||
ENDIF(UNIX)
|
||||
|
||||
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/mysql_config.c.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/mysql_config.c @ONLY)
|
||||
|
||||
ADD_EXECUTABLE(mysql_config ${CMAKE_CURRENT_BINARY_DIR}/mysql_config.c)
|
||||
TARGET_LINK_LIBRARIES(mysql_config mysqlclient)
|
||||
|
||||
# Installation
|
||||
#
|
||||
INSTALL(TARGETS mysql_config
|
||||
DESTINATION "bin")
|
101
mysql_config/mysql_config.c.in
Normal file
101
mysql_config/mysql_config.c.in
Normal file
@ -0,0 +1,101 @@
|
||||
#include <my_global.h>
|
||||
#include <my_sys.h>
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define INCLUDE "-I@CMAKE_INSTALL_PREFIX@/include"
|
||||
#define LIBS "-L@CMAKE_INSTALL_PREFIX@/lib -lmysql" \
|
||||
"@extra_dynamic_LDFLAGS@"
|
||||
#define CFLAGS INCLUDE "@CMAKE_C_FLAGS@"
|
||||
#define VERSION "@MYSQL_CLIENT_VERSION@"
|
||||
#define SOCKET "@MYSQL_UNIX_ADDR@"
|
||||
#define PORT "@MYSQL_PORT@"
|
||||
|
||||
static struct option long_options[]=
|
||||
{
|
||||
{"cflags", no_argument, 0, 'a'},
|
||||
{"help", no_argument, 0, 'b'},
|
||||
{"include", no_argument, 0, 'c'},
|
||||
{"libs", no_argument, 0, 'd'},
|
||||
{"libs_r", no_argument, 0, 'e'},
|
||||
{"version", no_argument, 0, 'f'},
|
||||
{"socket", no_argument, 0, 'g'},
|
||||
{"port", no_argument, 0, 'h'},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
static char *values[]=
|
||||
{
|
||||
CFLAGS,
|
||||
NULL,
|
||||
INCLUDE,
|
||||
LIBS,
|
||||
LIBS,
|
||||
VERSION,
|
||||
SOCKET,
|
||||
PORT
|
||||
};
|
||||
|
||||
void usage(void)
|
||||
{
|
||||
int i=0;
|
||||
puts("Copyright 2011 Monty Program AB");
|
||||
puts("Get compiler flags for using the MariaDB client library.");
|
||||
printf("Usage: %s [OPTIONS]\n", my_progname);
|
||||
while (long_options[i].name)
|
||||
{
|
||||
if (values[i])
|
||||
printf(" --%-12s [%s]\n", long_options[i].name, values[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int error;
|
||||
int c;
|
||||
my_progname= argv[0];
|
||||
|
||||
if (argc <= 1)
|
||||
{
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
int option_index= 0;
|
||||
c= getopt_long(argc, argv, "abcdef", long_options, &option_index);
|
||||
|
||||
switch(c) {
|
||||
case 'a':
|
||||
puts(CFLAGS);
|
||||
break;
|
||||
case 'b':
|
||||
usage();
|
||||
break;
|
||||
case 'c':
|
||||
puts(INCLUDE);
|
||||
break;
|
||||
case 'd':
|
||||
case 'e':
|
||||
puts(LIBS);
|
||||
break;
|
||||
case 'f':
|
||||
puts(VERSION);
|
||||
break;
|
||||
case 'g':
|
||||
puts(SOCKET);
|
||||
break;
|
||||
case 'h':
|
||||
puts(PORT);
|
||||
break;
|
||||
default:
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/extlib/zlib)
|
||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/zlib)
|
||||
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG")
|
||||
|
||||
SET(SOURCE_FILES adler32.c compress.c crc32.c deflate.c example.c gzclose.c gzlib.c gzread.c gzwrite.c infback.c inffast.c inflate.c inftrees.c minigzip.c trees.c uncompr.c zutil.c)
|
||||
|
||||
ADD_LIBRARY(zlib ${SOURCE_FILES})
|
||||
SET_TARGET_PROPERTIES(zlib PROPERTIES COMPILE_FLAGS
|
||||
"${CMAKE_SHARED_LIBRARY_C_FLAGS}")
|
||||
|
@ -24,6 +24,9 @@
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
# include <limits.h>
|
||||
#ifndef _WIN32
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user