1
0
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:
Georg Richter 2012-11-14 18:43:45 +01:00
parent 18cb6a1407
commit dd3d0d6f52
99 changed files with 5673 additions and 8211 deletions

13
.bzrignore Normal file
View 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

View File

@ -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)

View File

@ -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

View File

@ -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
View File

@ -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
View 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})

View 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
View 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
View 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;
}

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -264,6 +264,8 @@
# define HAVE_SOCKLEN_T 1
#endif
#cmakedefine SOCKET_SIZE_TYPE @SOCKET_SIZE_TYPE@
#cmakedefine RETSIGTYPE @RETSIGTYPE@
#cmakedefine RETQSORTTYPE @RETQSORTTYPE@

View File

@ -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 */

View File

@ -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)

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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)

View 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
View 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

View 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

View File

@ -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 */

View File

@ -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

View File

@ -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@

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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
View 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 .)

View File

@ -17,7 +17,7 @@
/* Handling of arrays that can grow dynamicly. */
#ifdef __WIN__)
#ifdef _WIN32
#undef SAFEMALLOC /* Problems with threads */
#endif

View File

@ -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

View File

@ -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;
}

View File

@ -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
View 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);
}

View File

@ -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)

View File

@ -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;
}

View File

@ -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() */
}

View File

@ -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()
{

View File

@ -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

View File

@ -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

View File

@ -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*/

View File

@ -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)
{

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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)

File diff suppressed because it is too large Load Diff

View 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

View File

@ -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;
}

View File

@ -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);
}
}
*/

View File

@ -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 */

View File

@ -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");

View File

@ -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 */

View File

@ -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
View 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
View 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));
}
/* }}} */

View File

@ -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);

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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
View 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);
}
/* }}} */

View File

@ -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)

View File

@ -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)
{

View File

@ -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;

View File

@ -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);

View File

@ -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 */

View File

@ -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)

View File

@ -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");

View File

@ -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

View File

@ -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;

View File

@ -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
View 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

View File

@ -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))
{

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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
*/

View File

@ -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

View File

@ -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';

View File

@ -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))))

View File

@ -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
View 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;
}

View File

@ -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
View 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;
}

View File

@ -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

View File

@ -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");

View File

@ -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))

View 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")

View 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);
}

View File

@ -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}")

View File

@ -24,6 +24,9 @@
# include <string.h>
# include <stdlib.h>
# include <limits.h>
#ifndef _WIN32
# include <unistd.h>
#endif
#endif
#include <fcntl.h>