mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2025-06-15 22:57:12 +02:00
Integrate MySQL module.
This commit is contained in:
468
module/Vendor/MDBC/libmariadb/CMakeLists.txt
vendored
Normal file
468
module/Vendor/MDBC/libmariadb/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,468 @@
|
||||
INCLUDE_DIRECTORIES(${CC_SOURCE_DIR}/include
|
||||
${ZLIB_INC}
|
||||
${CC_SOURCE_DIR}/libmariadb)
|
||||
|
||||
ADD_DEFINITIONS(-D ENABLED_LOCAL_INFILE)
|
||||
ADD_DEFINITIONS(-D HAVE_COMPRESS)
|
||||
ADD_DEFINITIONS(-D LIBMARIADB)
|
||||
ADD_DEFINITIONS(-D THREAD)
|
||||
|
||||
SET(EXPORT_SYMBOLS
|
||||
load_defaults
|
||||
mariadb_connection
|
||||
mariadb_convert_string
|
||||
mariadb_dyncol_check
|
||||
mariadb_dyncol_column_cmp_named
|
||||
mariadb_dyncol_column_count
|
||||
mariadb_dyncol_create_many_named
|
||||
mariadb_dyncol_create_many_num
|
||||
mariadb_dyncol_exists_named
|
||||
mariadb_dyncol_exists_num
|
||||
mariadb_dyncol_free
|
||||
mariadb_dyncol_get_named
|
||||
mariadb_dyncol_get_num
|
||||
mariadb_dyncol_has_names
|
||||
mariadb_dyncol_json
|
||||
mariadb_dyncol_list_named
|
||||
mariadb_dyncol_list_num
|
||||
mariadb_dyncol_unpack
|
||||
mariadb_dyncol_update_many_named
|
||||
mariadb_dyncol_update_many_num
|
||||
mariadb_dyncol_val_double
|
||||
mariadb_dyncol_val_long
|
||||
mariadb_dyncol_val_str
|
||||
myodbc_remove_escape
|
||||
mysql_affected_rows
|
||||
mysql_autocommit
|
||||
mysql_autocommit_cont
|
||||
mysql_autocommit_start
|
||||
mysql_change_user
|
||||
mysql_change_user_cont
|
||||
mysql_change_user_start
|
||||
mysql_character_set_name
|
||||
mysql_client_find_plugin
|
||||
mysql_client_register_plugin
|
||||
mysql_close
|
||||
mysql_close_cont
|
||||
mysql_close_start
|
||||
mysql_commit
|
||||
mysql_commit_cont
|
||||
mysql_commit_start
|
||||
mysql_data_seek
|
||||
mysql_debug
|
||||
mysql_dump_debug_info
|
||||
mysql_dump_debug_info_cont
|
||||
mysql_dump_debug_info_start
|
||||
mysql_eof
|
||||
mysql_errno
|
||||
mysql_error
|
||||
mysql_escape_string
|
||||
mysql_fetch_field
|
||||
mysql_fetch_field_direct
|
||||
mysql_fetch_fields
|
||||
mysql_fetch_lengths
|
||||
mysql_fetch_row
|
||||
mysql_fetch_row_cont
|
||||
mysql_fetch_row_start
|
||||
mysql_field_count
|
||||
mysql_field_seek
|
||||
mysql_field_tell
|
||||
mysql_free_result
|
||||
mysql_free_result_cont
|
||||
mysql_free_result_start
|
||||
mysql_get_character_set_info
|
||||
mysql_get_charset_by_name
|
||||
mysql_get_charset_by_nr
|
||||
mysql_get_client_info
|
||||
mysql_get_client_version
|
||||
mysql_get_host_info
|
||||
mysql_get_parameters
|
||||
mysql_get_proto_info
|
||||
mysql_get_server_info
|
||||
mysql_get_server_name
|
||||
mysql_get_server_version
|
||||
mysql_get_socket
|
||||
mysql_get_ssl_cipher
|
||||
mysql_get_timeout_value
|
||||
mysql_get_timeout_value_ms
|
||||
mysql_hex_string
|
||||
mysql_info
|
||||
mysql_init
|
||||
mysql_insert_id
|
||||
mysql_kill
|
||||
mysql_kill_cont
|
||||
mysql_kill_start
|
||||
mysql_list_dbs
|
||||
mysql_list_dbs_cont
|
||||
mysql_list_dbs_start
|
||||
mysql_list_fields
|
||||
mysql_list_fields_cont
|
||||
mysql_list_fields_start
|
||||
mysql_list_processes
|
||||
mysql_list_processes_cont
|
||||
mysql_list_processes_start
|
||||
mysql_list_tables
|
||||
mysql_list_tables_cont
|
||||
mysql_list_tables_start
|
||||
mysql_load_plugin;
|
||||
mysql_load_plugin_v
|
||||
mysql_more_results
|
||||
mysql_next_result
|
||||
mysql_next_result_cont
|
||||
mysql_next_result_start
|
||||
mysql_num_fields
|
||||
mysql_num_rows
|
||||
mysql_options
|
||||
mysql_optionsv
|
||||
mysql_ping
|
||||
mysql_ping_cont
|
||||
mysql_ping_start
|
||||
mysql_ps_fetch_functions
|
||||
mysql_query
|
||||
mysql_query_cont
|
||||
mysql_query_start
|
||||
mysql_read_query_result
|
||||
mysql_read_query_result_cont
|
||||
mysql_read_query_result_start
|
||||
mysql_real_connect
|
||||
mysql_real_connect_cont
|
||||
mysql_real_connect_start
|
||||
mysql_real_escape_string
|
||||
mysql_real_query
|
||||
mysql_real_query_cont
|
||||
mysql_real_query_start
|
||||
mysql_refresh
|
||||
mysql_refresh_cont
|
||||
mysql_refresh_start
|
||||
mysql_rollback
|
||||
mysql_rollback_cont
|
||||
mysql_rollback_start
|
||||
mysql_row_seek
|
||||
mysql_row_tell
|
||||
mysql_select_db
|
||||
mysql_select_db_cont
|
||||
mysql_select_db_start
|
||||
mysql_send_query
|
||||
mysql_send_query_cont
|
||||
mysql_send_query_start
|
||||
mysql_server_end
|
||||
mysql_server_init
|
||||
mysql_set_character_set
|
||||
mysql_set_character_set_cont
|
||||
mysql_set_character_set_start
|
||||
mysql_set_local_infile_default
|
||||
mysql_set_local_infile_handler
|
||||
mysql_set_server_option
|
||||
mysql_set_server_option_cont
|
||||
mysql_set_server_option_start
|
||||
mysql_shutdown
|
||||
mysql_shutdown_cont
|
||||
mysql_shutdown_start
|
||||
mysql_sqlstate
|
||||
mysql_ssl_set
|
||||
mysql_stat
|
||||
mysql_stat_cont
|
||||
mysql_stat_start
|
||||
mysql_stmt_affected_rows
|
||||
mysql_stmt_attr_get
|
||||
mysql_stmt_attr_set
|
||||
mysql_stmt_bind_param
|
||||
mysql_stmt_bind_result
|
||||
mysql_stmt_close
|
||||
mysql_stmt_close_cont
|
||||
mysql_stmt_close_start
|
||||
mysql_stmt_data_seek
|
||||
mysql_stmt_errno
|
||||
mysql_stmt_error
|
||||
mysql_stmt_execute
|
||||
mysql_stmt_execute_cont
|
||||
mysql_stmt_execute_start
|
||||
mysql_stmt_fetch
|
||||
mysql_stmt_fetch_column
|
||||
mysql_stmt_fetch_cont
|
||||
mysql_stmt_fetch_start
|
||||
mysql_stmt_field_count
|
||||
mysql_stmt_free_result
|
||||
mysql_stmt_free_result_cont
|
||||
mysql_stmt_free_result_start
|
||||
mysql_stmt_init
|
||||
mysql_stmt_insert_id
|
||||
mysql_stmt_more_results
|
||||
mysql_stmt_next_result
|
||||
mysql_stmt_next_result_cont
|
||||
mysql_stmt_next_result_start
|
||||
mysql_stmt_num_rows
|
||||
mysql_stmt_param_count
|
||||
mysql_stmt_param_metadata
|
||||
mysql_stmt_prepare
|
||||
mysql_stmt_prepare_cont
|
||||
mysql_stmt_prepare_start
|
||||
mysql_stmt_reset
|
||||
mysql_stmt_reset_cont
|
||||
mysql_stmt_reset_start
|
||||
mysql_stmt_result_metadata
|
||||
mysql_stmt_row_seek
|
||||
mysql_stmt_row_tell
|
||||
mysql_stmt_send_long_data
|
||||
mysql_stmt_send_long_data_cont
|
||||
mysql_stmt_send_long_data_start
|
||||
mysql_stmt_sqlstate
|
||||
mysql_stmt_store_result
|
||||
mysql_stmt_store_result_cont
|
||||
mysql_stmt_store_result_start
|
||||
mysql_store_result
|
||||
mysql_store_result_cont
|
||||
mysql_store_result_start
|
||||
mysql_thread_end
|
||||
mysql_thread_id
|
||||
mysql_thread_init
|
||||
mysql_thread_safe
|
||||
mysql_use_result
|
||||
mysql_warning_count)
|
||||
|
||||
IF(WITH_OPENSSL)
|
||||
SET(EXPORT_SYMBOLS ${EXPORT_SYMBOLS} mariadb_deinitialize_ssl)
|
||||
ENDIF()
|
||||
|
||||
IF(WIN32)
|
||||
SET(EXPORT_CONTENT "EXPORTS\n")
|
||||
FOREACH(SYMBOL ${EXPORT_SYMBOLS})
|
||||
SET(EXPORT_CONTENT "${EXPORT_CONTENT} ${SYMBOL}\n")
|
||||
ENDFOREACH()
|
||||
SET(EXPORT_FILE "${CC_BINARY_DIR}/libmariadb/exports.def")
|
||||
SET(EXPORT_LINK ${EXPORT_FILE})
|
||||
ELSE()
|
||||
SET(EXPORT_CONTENT "{\nglobal:\n")
|
||||
FOREACH(SYMBOL ${EXPORT_SYMBOLS})
|
||||
SET(EXPORT_CONTENT "${EXPORT_CONTENT} ${SYMBOL}\\;\n")
|
||||
ENDFOREACH()
|
||||
SET(EXPORT_FILE "${CC_BINARY_DIR}/libmariadb/exports.txt")
|
||||
SET(EXPORT_CONTENT "${EXPORT_CONTENT}local:\n *\\;\n}\\;")
|
||||
ENDIF()
|
||||
|
||||
FILE(WRITE ${EXPORT_FILE} ${EXPORT_CONTENT})
|
||||
|
||||
SET(LIBMARIADB_SOURCES
|
||||
array.c
|
||||
ma_dyncol.c
|
||||
bchange.c
|
||||
bmove.c
|
||||
bmove_upp.c
|
||||
my_charset.c
|
||||
hash.c
|
||||
violite.c
|
||||
net.c
|
||||
charset.c
|
||||
ma_time.c
|
||||
dbug.c
|
||||
default.c
|
||||
errmsg.c
|
||||
my_vsnprintf.c
|
||||
errors.c
|
||||
getopt1.c
|
||||
getopt.c
|
||||
int2str.c
|
||||
is_prefix.c
|
||||
libmariadb.c
|
||||
list.c
|
||||
llstr.c
|
||||
longlong2str.c
|
||||
ma_dtoa.c
|
||||
mf_dirname.c
|
||||
mf_fn_ext.c
|
||||
mf_format.c
|
||||
mf_loadpath.c
|
||||
mf_pack.c
|
||||
mf_path.c
|
||||
mf_unixpath.c
|
||||
mf_wcomp.c
|
||||
mulalloc.c
|
||||
my_alloc.c
|
||||
my_compress.c
|
||||
my_context.c
|
||||
my_div.c
|
||||
my_error.c
|
||||
my_fopen.c
|
||||
my_fstream.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
|
||||
mysql_async.c
|
||||
password.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
|
||||
)
|
||||
|
||||
# some gcc versions fail to compile asm parts of my_context.c,
|
||||
# if build type is "Release" (see CONC-133), so we need to add -g flag
|
||||
IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_BUILD_TYPE MATCHES "Release")
|
||||
SET_SOURCE_FILES_PROPERTIES(my_context.c PROPERTIES COMPILE_FLAGS -g)
|
||||
ENDIF()
|
||||
|
||||
|
||||
IF(WITH_OPENSSL)
|
||||
SET(LIBMARIADB_SOURCES ${LIBMARIADB_SOURCES} ma_secure.c)
|
||||
ENDIF()
|
||||
|
||||
IF(WIN32)
|
||||
INCLUDE_DIRECTORIES(${CC_SOURCE_DIR}/win-iconv)
|
||||
SET(LIBMARIADB_SOURCES ${LIBMARIADB_SOURCES}
|
||||
${CC_SOURCE_DIR}/win-iconv/win_iconv.c)
|
||||
ENDIF()
|
||||
|
||||
IF(ZLIB_FOUND)
|
||||
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
|
||||
LINK_LIBRARIES(${ZLIB_LIBRARY})
|
||||
ELSE()
|
||||
#[[ SET(ZLIB_SOURCES
|
||||
../zlib/adler32.c
|
||||
../zlib/compress.c
|
||||
../zlib/crc32.c
|
||||
../zlib/deflate.c
|
||||
../zlib/gzclose.c
|
||||
../zlib/gzlib.c
|
||||
../zlib/gzread.c
|
||||
../zlib/gzwrite.c
|
||||
../zlib/infback.c
|
||||
../zlib/inffast.c
|
||||
../zlib/inflate.c
|
||||
../zlib/inftrees.c
|
||||
../zlib/trees.c
|
||||
../zlib/uncompr.c
|
||||
../zlib/zutil.c
|
||||
)]]
|
||||
#SET(LIBMARIADB_SOURCES ${LIBMARIADB_SOURCES} ${ZLIB_SOURCES})
|
||||
#INCLUDE_DIRECTORIES(${CC_SOURCE_DIR}/zlib)
|
||||
ENDIF()
|
||||
|
||||
IF(WIN32)
|
||||
SET_VERSION_INFO("TARGET:libmariadb"
|
||||
"FILE_TYPE:VFT_DLL"
|
||||
"SOURCE_FILE:libmariadb/libmariadb.c"
|
||||
"ORIGINAL_FILE_NAME:libmariadb.dll"
|
||||
"FILE_DESCRIPTION:Dynamic lib for client/server communication")
|
||||
SET_VERSION_INFO("TARGET:mariadbclient"
|
||||
"FILE_TYPE:VFT_STATIC_LIB"
|
||||
"SOURCE_FILE:libmariadb/libmariadb.c"
|
||||
"ORIGINAL_FILE_NAME:mariadbclient.lib"
|
||||
"FILE_DESCRIPTION:Static lib for client/server communication")
|
||||
ENDIF()
|
||||
|
||||
# CREATE OBJECT LIBRARY
|
||||
ADD_LIBRARY(mariadb_obj OBJECT ${LIBMARIADB_SOURCES})
|
||||
IF(UNIX)
|
||||
SET_TARGET_PROPERTIES(mariadb_obj PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS}")
|
||||
ENDIF()
|
||||
|
||||
# Xcode doesn't support targets that have only object files,
|
||||
# so let's add an empty file to keep Xcode happy
|
||||
IF(CMAKE_GENERATOR MATCHES Xcode)
|
||||
FILE(WRITE ${CC_SOURCE_DIR}/libmariadb/empty.c "")
|
||||
SET(EMPTY_FILE ${CC_SOURCE_DIR}/libmariadb/empty.c)
|
||||
ENDIF()
|
||||
|
||||
ADD_LIBRARY(mariadbclient STATIC ${mariadbclient_RC} $<TARGET_OBJECTS:mariadb_obj> ${EMPTY_FILE} ${EXPORT_LINK})
|
||||
TARGET_LINK_LIBRARIES(mariadbclient ${SYSTEM_LIBS})
|
||||
target_include_directories(mariadbclient PUBLIC ${CC_SOURCE_DIR}/include)
|
||||
|
||||
ADD_LIBRARY(libmariadb SHARED ${libmariadb_RC} $<TARGET_OBJECTS:mariadb_obj> ${EMPTY_FILE} ${EXPORT_LINK})
|
||||
TARGET_LINK_LIBRARIES(libmariadb ${SYSTEM_LIBS})
|
||||
target_include_directories(libmariadb PUBLIC ${CC_SOURCE_DIR}/include)
|
||||
|
||||
IF(NOT ZLIB_FOUND)
|
||||
TARGET_LINK_LIBRARIES(mariadbclient zlibstatic)
|
||||
TARGET_LINK_LIBRARIES(libmariadb zlibstatic)
|
||||
ENDIF()
|
||||
|
||||
IF(UNIX)
|
||||
SET_TARGET_PROPERTIES(libmariadb PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS}")
|
||||
ENDIF()
|
||||
SIGN_TARGET(libmariadb)
|
||||
|
||||
IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
TARGET_LINK_LIBRARIES (libmariadb "-Wl,--no-undefined")
|
||||
SET_TARGET_PROPERTIES(libmariadb PROPERTIES LINK_FLAGS "-Wl,--version-script=${EXPORT_FILE}")
|
||||
TARGET_LINK_LIBRARIES (mariadbclient "-Wl,--no-undefined")
|
||||
SET_TARGET_PROPERTIES(mariadbclient PROPERTIES LINK_FLAGS "-Wl,--version-script=${EXPORT_FILE}")
|
||||
ENDIF()
|
||||
|
||||
SET_TARGET_PROPERTIES(libmariadb PROPERTIES PREFIX "")
|
||||
|
||||
SET_TARGET_PROPERTIES(libmariadb PROPERTIES VERSION
|
||||
${CPACK_PACKAGE_VERSION_MAJOR}
|
||||
SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR})
|
||||
|
||||
IF(NOT WIN32)
|
||||
SET_TARGET_PROPERTIES(mariadbclient PROPERTIES OUTPUT_NAME "${LIBMARIADB_STATIC_NAME}")
|
||||
ENDIF()
|
||||
|
||||
|
||||
#
|
||||
# Installation
|
||||
#
|
||||
INCLUDE(${CC_SOURCE_DIR}/cmake/symlink.cmake)
|
||||
|
||||
|
||||
# There are still several projects which don't make use
|
||||
# of the config program. To make sure these programs can
|
||||
# use mariadb client library we provide libmysql symlinks
|
||||
IF(NOT WIN32 AND WITH_MYSQLCOMPAT)
|
||||
SET(INSTALL_PATH ${LIB_INSTALL_DIR}/${LIBSUFFIX_INSTALL_DIR})
|
||||
create_symlink(libmysqlclient${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_PATH})
|
||||
create_symlink(libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_PATH})
|
||||
create_symlink(libmysqlclient${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_PATH})
|
||||
create_symlink(libmysqlclient_r${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_PATH})
|
||||
ENDIF()
|
||||
|
||||
|
||||
INSTALL(TARGETS
|
||||
libmariadb mariadbclient
|
||||
RUNTIME DESTINATION "${LIB_INSTALL_DIR}/${LIBSUFFIX_INSTALL_DIR}"
|
||||
LIBRARY DESTINATION "${LIB_INSTALL_DIR}/${LIBSUFFIX_INSTALL_DIR}"
|
||||
ARCHIVE DESTINATION "${LIB_INSTALL_DIR}/${LIBSUFFIX_INSTALL_DIR}")
|
||||
|
||||
INSTALL(DIRECTORY ${CC_SOURCE_DIR}/include/
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/${SUFFIX_INSTALL_DIR}
|
||||
PATTERN "*.h.in" EXCLUDE
|
||||
PATTERN "CMakeLists.txt" EXCLUDE
|
||||
PATTERN "Makefile.am" EXCLUDE)
|
||||
INSTALL(FILES
|
||||
${CC_BINARY_DIR}/include/my_config.h
|
||||
${CC_BINARY_DIR}/include/mysql_version.h
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/${SUFFIX_INSTALL_DIR})
|
||||
|
||||
|
91
module/Vendor/MDBC/libmariadb/acinclude.m4
vendored
Normal file
91
module/Vendor/MDBC/libmariadb/acinclude.m4
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
# Local macros for automake & autoconf
|
||||
|
||||
AC_DEFUN(MYSQL_TYPE_ACCEPT,
|
||||
[ac_save_CXXFLAGS="$CXXFLAGS"
|
||||
AC_CACHE_CHECK([base type of last arg to accept], mysql_cv_btype_last_arg_accept,
|
||||
AC_LANG_SAVE
|
||||
AC_LANG_CPLUSPLUS
|
||||
if test "$ac_cv_prog_gxx" = "yes"
|
||||
then
|
||||
CXXFLAGS="$CXXFLAGS -Werror"
|
||||
fi
|
||||
mysql_cv_btype_last_arg_accept=none
|
||||
[AC_TRY_COMPILE([#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
],
|
||||
[int a = accept(1, (struct sockaddr *) 0, (socklen_t *) 0);],
|
||||
mysql_cv_btype_last_arg_accept=socklen_t)]
|
||||
if test $mysql_cv_btype_last_arg_accept = none; then
|
||||
[AC_TRY_COMPILE([#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
],
|
||||
[int a = accept(1, (struct sockaddr *) 0, (size_t *) 0);],
|
||||
mysql_cv_btype_last_arg_accept=size_t)]
|
||||
fi
|
||||
if test $mysql_cv_btype_last_arg_accept = none; then
|
||||
mysql_cv_btype_last_arg_accept=int
|
||||
fi)
|
||||
AC_LANG_RESTORE
|
||||
AC_DEFINE_UNQUOTED(SOCKET_SIZE_TYPE, $mysql_cv_btype_last_arg_accept)
|
||||
CXXFLAGS="$ac_save_CXXFLAGS"
|
||||
])
|
||||
|
||||
|
||||
#---START: Used in for client configure
|
||||
AC_DEFUN(MYSQL_CHECK_ULONG,
|
||||
[AC_MSG_CHECKING(for type ulong)
|
||||
AC_CACHE_VAL(ac_cv_ulong,
|
||||
[AC_TRY_RUN([#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
main()
|
||||
{
|
||||
ulong foo;
|
||||
foo++;
|
||||
exit(0);
|
||||
}], ac_cv_ulong=yes, ac_cv_ulong=no, ac_cv_ulong=no)])
|
||||
AC_MSG_RESULT($ac_cv_ulong)
|
||||
if test "$ac_cv_ulong" = "yes"
|
||||
then
|
||||
AC_DEFINE(HAVE_ULONG)
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN(MYSQL_CHECK_UCHAR,
|
||||
[AC_MSG_CHECKING(for type uchar)
|
||||
AC_CACHE_VAL(ac_cv_uchar,
|
||||
[AC_TRY_RUN([#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
main()
|
||||
{
|
||||
uchar foo;
|
||||
foo++;
|
||||
exit(0);
|
||||
}], ac_cv_uchar=yes, ac_cv_uchar=no, ac_cv_uchar=no)])
|
||||
AC_MSG_RESULT($ac_cv_uchar)
|
||||
if test "$ac_cv_uchar" = "yes"
|
||||
then
|
||||
AC_DEFINE(HAVE_UCHAR)
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN(MYSQL_CHECK_UINT,
|
||||
[AC_MSG_CHECKING(for type uint)
|
||||
AC_CACHE_VAL(ac_cv_uint,
|
||||
[AC_TRY_RUN([#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
main()
|
||||
{
|
||||
uint foo;
|
||||
foo++;
|
||||
exit(0);
|
||||
}], ac_cv_uint=yes, ac_cv_uint=no, ac_cv_uint=no)])
|
||||
AC_MSG_RESULT($ac_cv_uint)
|
||||
if test "$ac_cv_uint" = "yes"
|
||||
then
|
||||
AC_DEFINE(HAVE_UINT)
|
||||
fi
|
||||
])
|
||||
|
||||
#---END:
|
175
module/Vendor/MDBC/libmariadb/array.c
vendored
Normal file
175
module/Vendor/MDBC/libmariadb/array.c
vendored
Normal file
@ -0,0 +1,175 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* Handling of arrays that can grow dynamicly. */
|
||||
|
||||
#undef SAFEMALLOC /* Problems with threads */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include "m_string.h"
|
||||
|
||||
/*
|
||||
Initiate array and alloc space for init_alloc elements. Array is usable
|
||||
even if space allocation failed
|
||||
*/
|
||||
|
||||
my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size,
|
||||
uint init_alloc, uint alloc_increment CALLER_INFO_PROTO)
|
||||
{
|
||||
DBUG_ENTER("init_dynamic_array");
|
||||
if (!alloc_increment)
|
||||
{
|
||||
alloc_increment=max((8192-MALLOC_OVERHEAD)/element_size,16);
|
||||
if (init_alloc > 8 && alloc_increment > init_alloc * 2)
|
||||
alloc_increment=init_alloc*2;
|
||||
}
|
||||
|
||||
if (!init_alloc)
|
||||
init_alloc=alloc_increment;
|
||||
array->elements=0;
|
||||
array->max_element=init_alloc;
|
||||
array->alloc_increment=alloc_increment;
|
||||
array->size_of_element=element_size;
|
||||
if (!(array->buffer=(char*) my_malloc_ci(element_size*init_alloc,MYF(MY_WME))))
|
||||
{
|
||||
array->max_element=0;
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
||||
my_bool insert_dynamic(DYNAMIC_ARRAY *array, gptr element)
|
||||
{
|
||||
gptr buffer;
|
||||
if (array->elements == array->max_element)
|
||||
{ /* Call only when nessesary */
|
||||
if (!(buffer=alloc_dynamic(array)))
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer=array->buffer+(array->elements * array->size_of_element);
|
||||
array->elements++;
|
||||
}
|
||||
memcpy(buffer,element,(size_t) array->size_of_element);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* Alloc room for one element */
|
||||
|
||||
unsigned char *alloc_dynamic(DYNAMIC_ARRAY *array)
|
||||
{
|
||||
if (array->elements == array->max_element)
|
||||
{
|
||||
char *new_ptr;
|
||||
if (!(new_ptr=(char*) my_realloc(array->buffer,(array->max_element+
|
||||
array->alloc_increment)*
|
||||
array->size_of_element,
|
||||
MYF(MY_WME | MY_ALLOW_ZERO_PTR))))
|
||||
return 0;
|
||||
array->buffer=new_ptr;
|
||||
array->max_element+=array->alloc_increment;
|
||||
}
|
||||
return array->buffer+(array->elements++ * array->size_of_element);
|
||||
}
|
||||
|
||||
|
||||
/* remove last element from array and return it */
|
||||
|
||||
unsigned char *pop_dynamic(DYNAMIC_ARRAY *array)
|
||||
{
|
||||
if (array->elements)
|
||||
return array->buffer+(--array->elements * array->size_of_element);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
my_bool set_dynamic(DYNAMIC_ARRAY *array, gptr element, uint idx)
|
||||
{
|
||||
if (idx >= array->elements)
|
||||
{
|
||||
if (idx >= array->max_element)
|
||||
{
|
||||
uint size;
|
||||
char *new_ptr;
|
||||
size=(idx+array->alloc_increment)/array->alloc_increment;
|
||||
size*= array->alloc_increment;
|
||||
if (!(new_ptr=(char*) my_realloc(array->buffer,size*
|
||||
array->size_of_element,
|
||||
MYF(MY_WME | MY_ALLOW_ZERO_PTR))))
|
||||
return TRUE;
|
||||
array->buffer=new_ptr;
|
||||
array->max_element=size;
|
||||
}
|
||||
bzero((gptr) (array->buffer+array->elements*array->size_of_element),
|
||||
(idx - array->elements)*array->size_of_element);
|
||||
array->elements=idx+1;
|
||||
}
|
||||
memcpy(array->buffer+(idx * array->size_of_element),element,
|
||||
(size_t) array->size_of_element);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
void get_dynamic(DYNAMIC_ARRAY *array, gptr element, uint idx)
|
||||
{
|
||||
if (idx >= array->elements)
|
||||
{
|
||||
DBUG_PRINT("warning",("To big array idx: %d, array size is %d",
|
||||
idx,array->elements));
|
||||
bzero(element,array->size_of_element);
|
||||
return;
|
||||
}
|
||||
memcpy(element,array->buffer+idx*array->size_of_element,
|
||||
(size_t) array->size_of_element);
|
||||
}
|
||||
|
||||
|
||||
void delete_dynamic(DYNAMIC_ARRAY *array)
|
||||
{
|
||||
if (array->buffer)
|
||||
{
|
||||
my_free(array->buffer);
|
||||
array->buffer=0;
|
||||
array->elements=array->max_element=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void delete_dynamic_element(DYNAMIC_ARRAY *array, uint idx)
|
||||
{
|
||||
char *ptr=array->buffer+array->size_of_element*idx;
|
||||
array->elements--;
|
||||
memmove(ptr,ptr+array->size_of_element,
|
||||
(array->elements-idx)*array->size_of_element);
|
||||
}
|
||||
|
||||
|
||||
void freeze_size(DYNAMIC_ARRAY *array)
|
||||
{
|
||||
uint elements=max(array->elements,1);
|
||||
|
||||
if (array->buffer && array->max_element != elements)
|
||||
{
|
||||
array->buffer=(char*) my_realloc(array->buffer,
|
||||
elements*array->size_of_element,
|
||||
MYF(MY_WME));
|
||||
array->max_element=elements;
|
||||
}
|
||||
}
|
39
module/Vendor/MDBC/libmariadb/bchange.c
vendored
Normal file
39
module/Vendor/MDBC/libmariadb/bchange.c
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* File : bchange.c
|
||||
Author : Michael widenius
|
||||
Updated: 1987-03-20
|
||||
Defines: bchange()
|
||||
|
||||
bchange(dst, old_length, src, new_length, tot_length)
|
||||
replaces old_length characters at dst to new_length characters from
|
||||
src in a buffer with tot_length bytes.
|
||||
*/
|
||||
|
||||
#include <my_global.h>
|
||||
#include "m_string.h"
|
||||
|
||||
void bchange(register char *dst, size_t old_length, register const char *src, size_t new_length, size_t tot_length)
|
||||
{
|
||||
size_t rest=tot_length-old_length;
|
||||
if (old_length < new_length)
|
||||
bmove_upp(dst+rest+new_length,dst+tot_length,rest);
|
||||
else
|
||||
bmove(dst+new_length,dst+old_length,rest);
|
||||
memcpy(dst,src,new_length);
|
||||
}
|
80
module/Vendor/MDBC/libmariadb/bmove.c
vendored
Normal file
80
module/Vendor/MDBC/libmariadb/bmove.c
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
/* Copyright (C) 2002 MySQL 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* File : bmove.c
|
||||
Author : Richard A. O'Keefe.
|
||||
Michael Widenius; ifdef MC68000
|
||||
Updated: 23 April 1984
|
||||
Defines: bmove()
|
||||
|
||||
bmove(dst, src, len) moves exactly "len" bytes from the source "src"
|
||||
to the destination "dst". It does not check for NUL characters as
|
||||
strncpy() and strnmov() do. Thus if your C compiler doesn't support
|
||||
structure assignment, you can simulate it with
|
||||
bmove(&to, &from, sizeof from);
|
||||
The standard 4.2bsd routine for this purpose is bcopy. But as bcopy
|
||||
has its first two arguments the other way around you may find this a
|
||||
bit easier to get right.
|
||||
No value is returned.
|
||||
|
||||
Note: the "b" routines are there to exploit certain VAX order codes,
|
||||
but the MOVC3 instruction will only move 65535 characters. The asm
|
||||
code is presented for your interest and amusement.
|
||||
*/
|
||||
|
||||
#include <my_global.h>
|
||||
#include "m_string.h"
|
||||
|
||||
#if !defined(HAVE_BMOVE) && !defined(bmove)
|
||||
|
||||
#if VaxAsm
|
||||
|
||||
void bmove(dst, src, len)
|
||||
char *dst, *src;
|
||||
uint len;
|
||||
{
|
||||
asm("movc3 12(ap),*8(ap),*4(ap)");
|
||||
}
|
||||
|
||||
#else
|
||||
#if defined(MC68000) && defined(DS90)
|
||||
|
||||
void bmove(dst, src, len)
|
||||
char *dst,*src;
|
||||
uint len; /* 0 <= len <= 65535 */
|
||||
{
|
||||
asm(" movl 12(a7),d0 ");
|
||||
asm(" subql #1,d0 ");
|
||||
asm(" blt .L5 ");
|
||||
asm(" movl 4(a7),a1 ");
|
||||
asm(" movl 8(a7),a0 ");
|
||||
asm(".L4: movb (a0)+,(a1)+ ");
|
||||
asm(" dbf d0,.L4 ");
|
||||
asm(".L5: ");
|
||||
}
|
||||
#else
|
||||
|
||||
void bmove(dst, src, len)
|
||||
register char *dst;
|
||||
register const char *src;
|
||||
register uint len;
|
||||
{
|
||||
while (len-- != 0) *dst++ = *src++;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
51
module/Vendor/MDBC/libmariadb/bmove_upp.c
vendored
Normal file
51
module/Vendor/MDBC/libmariadb/bmove_upp.c
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* File : bmove.c
|
||||
Author : Michael widenius
|
||||
Updated: 1987-03-20
|
||||
Defines: bmove_upp()
|
||||
|
||||
bmove_upp(dst, src, len) moves exactly "len" bytes from the source
|
||||
"src-len" to the destination "dst-len" counting downwards.
|
||||
*/
|
||||
|
||||
#include <my_global.h>
|
||||
#include "m_string.h"
|
||||
|
||||
#if defined(MC68000) && defined(DS90)
|
||||
|
||||
/* 0 <= len <= 65535 */
|
||||
void bmove_upp(byte *dst, const byte *src, size_t len)
|
||||
{
|
||||
asm(" movl 12(a7),d0 ");
|
||||
asm(" subql #1,d0 ");
|
||||
asm(" blt .L5 ");
|
||||
asm(" movl 4(a7),a1 ");
|
||||
asm(" movl 8(a7),a0 ");
|
||||
asm(".L4: movb -(a0),-(a1) ");
|
||||
asm(" dbf d0,.L4 ");
|
||||
asm(".L5: ");
|
||||
}
|
||||
#else
|
||||
|
||||
void bmove_upp(register char *dst, register const char *src, register size_t len)
|
||||
{
|
||||
while (len-- != 0) *--dst = *--src;
|
||||
}
|
||||
|
||||
#endif
|
78
module/Vendor/MDBC/libmariadb/charset.c
vendored
Normal file
78
module/Vendor/MDBC/libmariadb/charset.c
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include "mysys_err.h"
|
||||
#include <m_ctype.h>
|
||||
#include <m_string.h>
|
||||
#include <my_dir.h>
|
||||
|
||||
CHARSET_INFO *default_charset_info = (CHARSET_INFO *)&compiled_charsets[5];
|
||||
CHARSET_INFO *my_charset_bin= (CHARSET_INFO *)&compiled_charsets[32];
|
||||
CHARSET_INFO *my_charset_latin1= (CHARSET_INFO *)&compiled_charsets[5];
|
||||
CHARSET_INFO *my_charset_utf8_general_ci= (CHARSET_INFO *)&compiled_charsets[21];
|
||||
|
||||
CHARSET_INFO * STDCALL mysql_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) ? (CHARSET_INFO *)&compiled_charsets[i] : NULL;
|
||||
}
|
||||
|
||||
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 = mysql_get_charset_by_nr(cs);
|
||||
if (!new_charset)
|
||||
{
|
||||
DBUG_PRINT("error",("Couldn't set default character set"));
|
||||
DBUG_RETURN(TRUE); /* error */
|
||||
}
|
||||
default_charset_info = new_charset;
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
CHARSET_INFO * STDCALL mysql_get_charset_by_name(const char *cs_name)
|
||||
{
|
||||
int i= 0;
|
||||
|
||||
while (compiled_charsets[i].nr && strcmp(cs_name, compiled_charsets[i].csname) != 0)
|
||||
i++;
|
||||
|
||||
return (compiled_charsets[i].nr) ? (CHARSET_INFO *)&compiled_charsets[i] : NULL;
|
||||
}
|
||||
|
||||
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 = mysql_get_charset_by_name(cs_name);
|
||||
if (!new_charset)
|
||||
{
|
||||
DBUG_PRINT("error",("Couldn't set default character set"));
|
||||
DBUG_RETURN(TRUE); /* error */
|
||||
}
|
||||
|
||||
default_charset_info = new_charset;
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
466
module/Vendor/MDBC/libmariadb/client_plugin.c
vendored
Normal file
466
module/Vendor/MDBC/libmariadb/client_plugin.c
vendored
Normal file
@ -0,0 +1,466 @@
|
||||
/* Copyright (C) 2010 - 2012 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 (libmariadb) 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 <my_sys.h>
|
||||
#include <ma_common.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>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
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]=
|
||||
{
|
||||
MYSQL_CLIENT_DB_PLUGIN_INTERFACE_VERSION, /* 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;
|
||||
}
|
||||
|
||||
#ifdef THREAD
|
||||
safe_mutex_assert_owner(&LOCK_load_client_plugin);
|
||||
#endif
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/********** extern functions to be used by libmariadb *********************/
|
||||
|
||||
/**
|
||||
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 * STDCALL
|
||||
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 * STDCALL
|
||||
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;
|
||||
char *env_plugin_dir= getenv("MARIADB_PLUGIN_DIR");
|
||||
|
||||
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 : (env_plugin_dir) ? env_plugin_dir :
|
||||
PLUGINDIR, "/",
|
||||
name, SO_EXT, NullS);
|
||||
|
||||
/* Open new dll handle */
|
||||
if (!(dlhandle= dlopen((const char *)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 * STDCALL
|
||||
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 * STDCALL
|
||||
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);
|
||||
}
|
||||
|
||||
|
2457
module/Vendor/MDBC/libmariadb/dbug.c
vendored
Normal file
2457
module/Vendor/MDBC/libmariadb/dbug.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
433
module/Vendor/MDBC/libmariadb/default.c
vendored
Normal file
433
module/Vendor/MDBC/libmariadb/default.c
vendored
Normal file
@ -0,0 +1,433 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/****************************************************************************
|
||||
** Add all options from files named "group".cnf from the default_directories
|
||||
** before the command line arguments.
|
||||
** On Windows defaults will also search in the Windows directory for a file
|
||||
** called 'group'.ini
|
||||
** As long as the program uses the last argument for conflicting
|
||||
** options one only have to add a call to "load_defaults" to enable
|
||||
** use of default values.
|
||||
** pre- and end 'blank space' are removed from options and values. The
|
||||
** following escape sequences are recognized in values: \b \t \n \r \\
|
||||
**
|
||||
** The following arguments are handled automaticly; If used, they must be
|
||||
** first argument on the command line!
|
||||
** --no-defaults ; no options are read.
|
||||
** --defaults-file=full-path-to-default-file ; Only this file will be read.
|
||||
** --defaults-extra-file=full-path-to-default-file ; Read this file before ~/
|
||||
** --print-defaults ; Print the modified command line and exit
|
||||
****************************************************************************/
|
||||
|
||||
#undef SAFEMALLOC /* safe_malloc is not yet initailized */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include "m_string.h"
|
||||
#include <ctype.h>
|
||||
#include "m_ctype.h"
|
||||
#include <my_dir.h>
|
||||
|
||||
char *defaults_extra_file=0;
|
||||
|
||||
/* Which directories are searched for options (and in which order) */
|
||||
|
||||
const char *default_directories[]= {
|
||||
#ifdef _WIN32
|
||||
"C:/",
|
||||
#else
|
||||
"/etc/",
|
||||
#endif
|
||||
#ifdef DATADIR
|
||||
DATADIR,
|
||||
#endif
|
||||
"", /* Place for defaults_extra_dir */
|
||||
#ifndef _WIN32
|
||||
"~/",
|
||||
#endif
|
||||
NullS,
|
||||
};
|
||||
|
||||
#define default_ext ".cnf" /* extension for config file */
|
||||
#ifdef _WIN32
|
||||
#include <winbase.h>
|
||||
#define windows_ext ".ini"
|
||||
#endif
|
||||
|
||||
static my_bool search_default_file(DYNAMIC_ARRAY *args,MEM_ROOT *alloc,
|
||||
const char *dir, const char *config_file,
|
||||
const char *ext, TYPELIB *group);
|
||||
|
||||
|
||||
void load_defaults(const char *conf_file, const char **groups,
|
||||
int *argc, char ***argv)
|
||||
{
|
||||
DYNAMIC_ARRAY args;
|
||||
const char **dirs, *forced_default_file;
|
||||
TYPELIB group;
|
||||
my_bool found_print_defaults=0;
|
||||
uint args_used=0;
|
||||
MEM_ROOT alloc;
|
||||
char *ptr,**res;
|
||||
DBUG_ENTER("load_defaults");
|
||||
|
||||
init_alloc_root(&alloc,128,0);
|
||||
if (*argc >= 2 && !strcmp(argv[0][1],"--no-defaults"))
|
||||
{
|
||||
/* remove the --no-defaults argument and return only the other arguments */
|
||||
uint i;
|
||||
if (!(ptr=(char*) alloc_root(&alloc,sizeof(alloc)+
|
||||
(*argc + 1)*sizeof(char*))))
|
||||
goto err;
|
||||
res= (char**) (ptr+sizeof(alloc));
|
||||
res[0]= **argv; /* Copy program name */
|
||||
for (i=2 ; i < (uint) *argc ; i++)
|
||||
res[i-1]=argv[0][i];
|
||||
(*argc)--;
|
||||
*argv=res;
|
||||
*(MEM_ROOT*) ptr= alloc; /* Save alloc root for free */
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/* Check if we want to force the use a specific default file */
|
||||
forced_default_file=0;
|
||||
if (*argc >= 2)
|
||||
{
|
||||
if (is_prefix(argv[0][1],"--defaults-file="))
|
||||
{
|
||||
forced_default_file=strchr(argv[0][1],'=')+1;
|
||||
args_used++;
|
||||
}
|
||||
else if (is_prefix(argv[0][1],"--defaults-extra-file="))
|
||||
{
|
||||
defaults_extra_file=strchr(argv[0][1],'=')+1;
|
||||
args_used++;
|
||||
}
|
||||
}
|
||||
|
||||
group.count=0;
|
||||
group.name= "defaults";
|
||||
group.type_names= groups;
|
||||
for (; *groups ; groups++)
|
||||
group.count++;
|
||||
|
||||
if (my_init_dynamic_array(&args, sizeof(char*),*argc, 32))
|
||||
goto err;
|
||||
if (forced_default_file)
|
||||
{
|
||||
if (search_default_file(&args, &alloc, "", forced_default_file, "",
|
||||
&group))
|
||||
goto err;
|
||||
}
|
||||
else if (dirname_length(conf_file))
|
||||
{
|
||||
if (search_default_file(&args, &alloc, NullS, conf_file, default_ext,
|
||||
&group))
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
#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,
|
||||
&group))
|
||||
goto err;
|
||||
#endif
|
||||
#if defined(__EMX__) || defined(OS2)
|
||||
if (getenv("ETC") &&
|
||||
search_default_file(&args, &alloc, getenv("ETC"), conf_file,
|
||||
default_ext, &group))
|
||||
goto err;
|
||||
#endif
|
||||
for (dirs=default_directories ; *dirs; dirs++)
|
||||
{
|
||||
int error=0;
|
||||
if (**dirs)
|
||||
error=search_default_file(&args, &alloc, *dirs, conf_file,
|
||||
default_ext, &group);
|
||||
else if (defaults_extra_file)
|
||||
error=search_default_file(&args, &alloc, NullS, defaults_extra_file,
|
||||
default_ext, &group);
|
||||
if (error)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if (!(ptr=(char*) alloc_root(&alloc,sizeof(alloc)+
|
||||
(args.elements + *argc +1) *sizeof(char*))))
|
||||
goto err;
|
||||
res= (char**) (ptr+sizeof(alloc));
|
||||
|
||||
/* copy name + found arguments + command line arguments to new array */
|
||||
res[0]=argv[0][0];
|
||||
memcpy((gptr) (res+1), args.buffer, args.elements*sizeof(char*));
|
||||
/* Skipp --defaults-file and --defaults-extra-file */
|
||||
(*argc)-= args_used;
|
||||
(*argv)+= args_used;
|
||||
|
||||
/* Check if we wan't to see the new argument list */
|
||||
if (*argc >= 2 && !strcmp(argv[0][1],"--print-defaults"))
|
||||
{
|
||||
found_print_defaults=1;
|
||||
--*argc; ++*argv; /* skipp argument */
|
||||
}
|
||||
|
||||
memcpy((gptr) (res+1+args.elements), (char*) ((*argv)+1),
|
||||
(*argc-1)*sizeof(char*));
|
||||
res[args.elements+ *argc]=0; /* last null */
|
||||
|
||||
(*argc)+=args.elements;
|
||||
*argv= (char**) res;
|
||||
*(MEM_ROOT*) ptr= alloc; /* Save alloc root for free */
|
||||
delete_dynamic(&args);
|
||||
if (found_print_defaults)
|
||||
{
|
||||
int i;
|
||||
printf("%s would have been started with the following arguments:\n",
|
||||
**argv);
|
||||
for (i=1 ; i < *argc ; i++)
|
||||
printf("%s ", (*argv)[i]);
|
||||
puts("");
|
||||
exit(1);
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
err:
|
||||
fprintf(stderr,"Program aborted\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
void free_defaults(char **argv)
|
||||
{
|
||||
MEM_ROOT ptr;
|
||||
memcpy_fixed((char*) &ptr,(char *) argv - sizeof(ptr), sizeof(ptr));
|
||||
free_root(&ptr,MYF(0));
|
||||
}
|
||||
|
||||
|
||||
static my_bool search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
|
||||
const char *dir, const char *config_file,
|
||||
const char *ext, TYPELIB *group)
|
||||
{
|
||||
char name[FN_REFLEN+10],buff[4096],*ptr,*end,*value,*tmp;
|
||||
FILE *fp;
|
||||
uint line=0;
|
||||
my_bool read_values= 0, found_group= 0, is_escaped= 0, is_quoted= 0;
|
||||
|
||||
if ((dir ? strlen(dir) : 0 )+strlen(config_file) >= FN_REFLEN-3)
|
||||
return 0; /* Ignore wrong paths */
|
||||
if (dir)
|
||||
{
|
||||
strmov(name,dir);
|
||||
convert_dirname(name);
|
||||
if (dir[0] == FN_HOMELIB) /* Add . to filenames in home */
|
||||
strcat(name,".");
|
||||
strxmov(strend(name),config_file,ext,NullS);
|
||||
}
|
||||
else
|
||||
{
|
||||
strmov(name,config_file);
|
||||
}
|
||||
fn_format(name,name,"","",4);
|
||||
#if !defined(_WIN32) && !defined(OS2)
|
||||
{
|
||||
MY_STAT stat_info;
|
||||
if (!my_stat(name,&stat_info,MYF(0)))
|
||||
return 0;
|
||||
if (stat_info.st_mode & S_IWOTH) /* ignore world-writeable files */
|
||||
{
|
||||
fprintf(stderr, "warning: World-writeable config file %s is ignored\n",
|
||||
name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!(fp = my_fopen(fn_format(name,name,"","",4),O_RDONLY,MYF(0))))
|
||||
return 0; /* Ignore wrong files */
|
||||
|
||||
while (fgets(buff,sizeof(buff)-1,fp))
|
||||
{
|
||||
line++;
|
||||
/* Ignore comment and empty lines */
|
||||
for (ptr=buff ; isspace(*ptr) ; ptr++ );
|
||||
if (!is_escaped && (*ptr == '\"' || *ptr== '\''))
|
||||
{
|
||||
is_quoted= !is_quoted;
|
||||
continue;
|
||||
}
|
||||
if (*ptr == '#' || *ptr == ';' || !*ptr)
|
||||
continue;
|
||||
is_escaped= (*ptr == '\\');
|
||||
if (*ptr == '[') /* Group name */
|
||||
{
|
||||
found_group=1;
|
||||
if (!(end=(char *) strchr(++ptr,']')))
|
||||
{
|
||||
fprintf(stderr,
|
||||
"error: Wrong group definition in config file: %s at line %d\n",
|
||||
name,line);
|
||||
goto err;
|
||||
}
|
||||
for ( ; isspace(end[-1]) ; end--) ; /* Remove end space */
|
||||
end[0]=0;
|
||||
read_values=find_type(ptr,group,3) > 0;
|
||||
continue;
|
||||
}
|
||||
if (!found_group)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"error: Found option without preceding group in config file: %s at line: %d\n",
|
||||
name,line);
|
||||
goto err;
|
||||
}
|
||||
if (!read_values)
|
||||
continue;
|
||||
if (!(end=value=strchr(ptr,'=')))
|
||||
end=strend(ptr); /* Option without argument */
|
||||
for ( ; isspace(end[-1]) ; end--) ;
|
||||
if (!value)
|
||||
{
|
||||
if (!(tmp=alloc_root(alloc,(uint) (end-ptr)+3)))
|
||||
goto err;
|
||||
strmake(strmov(tmp,"--"),ptr,(uint) (end-ptr));
|
||||
if (insert_dynamic(args,(gptr) &tmp))
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Remove pre- and end space */
|
||||
char *value_end;
|
||||
for (value++ ; isspace(*value); value++) ;
|
||||
value_end=strend(value);
|
||||
for ( ; isspace(value_end[-1]) ; value_end--) ;
|
||||
/* remove possible quotes */
|
||||
if (*value == '\'' || *value == '\"')
|
||||
{
|
||||
value++;
|
||||
if (value_end[-1] == '\'' || value_end[-1] == '\"')
|
||||
value_end--;
|
||||
}
|
||||
if (value_end < value) /* Empty string */
|
||||
value_end=value;
|
||||
if (!(tmp=alloc_root(alloc,(uint) (end-ptr)+3 +
|
||||
(uint) (value_end-value)+1)))
|
||||
goto err;
|
||||
if (insert_dynamic(args,(gptr) &tmp))
|
||||
goto err;
|
||||
ptr=strnmov(strmov(tmp,"--"),ptr,(uint) (end-ptr));
|
||||
*ptr++= '=';
|
||||
for ( ; value != value_end; value++)
|
||||
{
|
||||
if (*value == '\\' && value != value_end-1)
|
||||
{
|
||||
switch(*++value) {
|
||||
case 'n':
|
||||
*ptr++='\n';
|
||||
break;
|
||||
case 't':
|
||||
*ptr++= '\t';
|
||||
break;
|
||||
case 'r':
|
||||
*ptr++ = '\r';
|
||||
break;
|
||||
case 'b':
|
||||
*ptr++ = '\b';
|
||||
break;
|
||||
case 's':
|
||||
*ptr++= ' '; /* space */
|
||||
break;
|
||||
case '\"':
|
||||
*ptr++= '\"';
|
||||
break;
|
||||
case '\'':
|
||||
*ptr++= '\'';
|
||||
break;
|
||||
case '\\':
|
||||
*ptr++= '\\';
|
||||
break;
|
||||
default: /* Unknown; Keep '\' */
|
||||
*ptr++= '\\';
|
||||
*ptr++= *value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
*ptr++= *value;
|
||||
}
|
||||
*ptr=0;
|
||||
}
|
||||
}
|
||||
my_fclose(fp,MYF(0));
|
||||
return(0);
|
||||
|
||||
err:
|
||||
my_fclose(fp,MYF(0));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void print_defaults(const char *conf_file, const char **groups)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
bool have_ext=fn_ext(conf_file)[0] != 0;
|
||||
#endif
|
||||
char name[FN_REFLEN];
|
||||
const char **dirs;
|
||||
puts("\nDefault options are read from the following files in the given order:");
|
||||
|
||||
if (dirname_length(conf_file))
|
||||
fputs(conf_file,stdout);
|
||||
else
|
||||
{
|
||||
#ifdef _WIN32
|
||||
GetWindowsDirectory(name,sizeof(name));
|
||||
printf("%s\\%s%s ",name,conf_file,have_ext ? "" : windows_ext);
|
||||
#endif
|
||||
#if defined(__EMX__) || defined(OS2)
|
||||
if (getenv("ETC"))
|
||||
printf("%s\\%s%s ", getenv("ETC"), conf_file, default_ext);
|
||||
#endif
|
||||
for (dirs=default_directories ; *dirs; dirs++)
|
||||
{
|
||||
if (**dirs)
|
||||
strmov(name,*dirs);
|
||||
else if (defaults_extra_file)
|
||||
strmov(name,defaults_extra_file);
|
||||
else
|
||||
continue;
|
||||
convert_dirname(name);
|
||||
if (name[0] == FN_HOMELIB) /* Add . to filenames in home */
|
||||
strcat(name,".");
|
||||
strxmov(strend(name),conf_file,default_ext," ",NullS);
|
||||
fputs(name,stdout);
|
||||
}
|
||||
puts("");
|
||||
}
|
||||
fputs("The following groups are read:",stdout);
|
||||
for ( ; *groups ; groups++)
|
||||
{
|
||||
fputc(' ',stdout);
|
||||
fputs(*groups,stdout);
|
||||
}
|
||||
puts("\nThe following options may be given as the first argument:\n\
|
||||
--print-defaults Print the program argument list and exit\n\
|
||||
--no-defaults Don't read default options from any options file\n\
|
||||
--defaults-file=# Only read default options from the given file #\n\
|
||||
--defaults-extra-file=# Read this file after the global files are read");
|
||||
}
|
||||
|
152
module/Vendor/MDBC/libmariadb/errmsg.c
vendored
Normal file
152
module/Vendor/MDBC/libmariadb/errmsg.c
vendored
Normal file
@ -0,0 +1,152 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* Error messages for MySQL clients */
|
||||
/* error messages for the demon is in share/language/errmsg.sys */
|
||||
|
||||
#include <my_global.h>
|
||||
#include <my_sys.h>
|
||||
#include "errmsg.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef GERMAN
|
||||
const char *client_errors[]=
|
||||
{
|
||||
"Unbekannter MySQL Fehler",
|
||||
"Kann UNIX-Socket nicht anlegen (%d)",
|
||||
"Keine Verbindung zu lokalem MySQL Server, socket: '%-.64s' (%d)",
|
||||
"Keine Verbindung zu MySQL Server auf %-.64s (%d)",
|
||||
"Kann TCP/IP-Socket nicht anlegen (%d)",
|
||||
"Unbekannter MySQL Server Host (%-.64s) (%d)",
|
||||
"MySQL Server nicht vorhanden",
|
||||
"Protokolle ungleich. Server Version = % d Client Version = %d",
|
||||
"MySQL client got out of memory",
|
||||
"Wrong host info",
|
||||
"Localhost via UNIX socket",
|
||||
"%-.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",
|
||||
"Verbindung ueber Named Pipe; Host: %-.64s",
|
||||
"Kann nicht auf Named Pipe warten. Host: %-.64s pipe: %-.32s (%lu)",
|
||||
"Kann Named Pipe nicht oeffnen. Host: %-.64s pipe: %-.32s (%lu)",
|
||||
"Kann den Status der Named Pipe nicht setzen. Host: %-.64s pipe: %-.32s (%lu)",
|
||||
"Can't initialize character set %-.64s (path: %-.64s)",
|
||||
"Got packet bigger than 'max_allowed_packet'"
|
||||
};
|
||||
|
||||
/* Start of code added by Roberto M. Serqueira - martinsc@uol.com.br - 05.24.2001 */
|
||||
|
||||
#elif defined PORTUGUESE
|
||||
const char *client_errors[]=
|
||||
{
|
||||
"Erro desconhecido do MySQL",
|
||||
"N<EFBFBD>o pode criar 'UNIX socket' (%d)",
|
||||
"N<EFBFBD>o pode se conectar ao servidor MySQL local atrav<61>s do 'socket' '%-.64s' (%d)",
|
||||
"N<EFBFBD>o pode se conectar ao servidor MySQL em '%-.64s' (%d)",
|
||||
"N<EFBFBD>o pode criar 'socket TCP/IP' (%d)",
|
||||
"'Host' servidor MySQL '%-.64s' (%d) desconhecido",
|
||||
"Servidor MySQL desapareceu",
|
||||
"Incompatibilidade de protocolos. Vers<72>o do Servidor: %d - Vers<72>o do Cliente: %d",
|
||||
"Cliente do MySQL com falta de mem<65>ria",
|
||||
"Informa<EFBFBD><EFBFBD>o inv<6E>lida de 'host'",
|
||||
"Localhost via 'UNIX socket'",
|
||||
"%-.64s via 'TCP/IP'",
|
||||
"Erro na negocia<69><61>o de acesso ao servidor",
|
||||
"Conex<EFBFBD>o perdida com servidor MySQL durante 'query'",
|
||||
"Comandos fora de sincronismo. Voc<6F> n<>o pode executar este comando agora",
|
||||
"%-.64s via 'named pipe'",
|
||||
"N<EFBFBD>o pode esperar pelo 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
|
||||
"N<EFBFBD>o pode abrir 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
|
||||
"N<EFBFBD>o pode estabelecer o estado do 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
|
||||
"N<EFBFBD>o pode inicializar conjunto de caracteres %-.64s (caminho %-.64s)",
|
||||
"Obteve pacote maior do que 'max_allowed_packet'"
|
||||
};
|
||||
|
||||
#else /* ENGLISH */
|
||||
const char *client_errors[]=
|
||||
{
|
||||
/* 2000 */ "Unknown MySQL error",
|
||||
/* 2001 */ "Can't create UNIX socket (%d)",
|
||||
/* 2002 */ "Can't connect to local MySQL server through socket '%-.64s' (%d)",
|
||||
/* 2003 */ "Can't connect to MySQL server on '%-.64s' (%d)",
|
||||
/* 2004 */ "Can't create TCP/IP socket (%d)",
|
||||
/* 2005 */ "Unknown MySQL Server Host '%-.64s' (%d)",
|
||||
/* 2006 */ "MySQL server has gone away",
|
||||
/* 2007 */ "Protocol mismatch. Server Version = %d Client Version = %d",
|
||||
/* 2008 */ "MySQL client run out of memory",
|
||||
/* 2009 */ "Wrong host info",
|
||||
/* 2010 */ "Localhost via UNIX socket",
|
||||
/* 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",
|
||||
/* 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)",
|
||||
/* 2018 */ "Can't set state of named pipe to host: %-.64s pipe: %-.32s (%lu)",
|
||||
/* 2019 */ "Can't initialize character set %-.64s (path: %-.64s)",
|
||||
/* 2020 */ "Got packet bigger than 'max_allowed_packet'",
|
||||
/* 2021 */ "",
|
||||
/* 2022 */ "",
|
||||
/* 2023 */ "",
|
||||
/* 2024 */ "",
|
||||
/* 2025 */ "",
|
||||
/* 2026 */ "SSL connection error: %100s",
|
||||
/* 2027 */ "received malformed packet",
|
||||
/* 2028 */ "",
|
||||
/* 2029 */ "",
|
||||
/* 2030 */ "Statement is not prepared",
|
||||
/* 2031 */ "No data supplied for parameters in prepared statement",
|
||||
/* 2032 */ "",
|
||||
/* 2033 */ "",
|
||||
/* 2034 */ "",
|
||||
/* 2035 */ "",
|
||||
/* 2036 */ "Buffer type is not supported",
|
||||
/* 2037 */ "",
|
||||
/* 2038 */ "",
|
||||
/* 2039 */ "",
|
||||
/* 2040 */ "",
|
||||
/* 2041 */ "",
|
||||
/* 2042 */ "",
|
||||
/* 2043 */ "",
|
||||
/* 2044 */ "",
|
||||
/* 2045 */ "",
|
||||
/* 2046 */ "",
|
||||
/* 2047 */ "",
|
||||
/* 2048 */ "",
|
||||
/* 2049 */ "Connection with old authentication protocol refused.",
|
||||
/* 2050 */ "",
|
||||
/* 2051 */ "",
|
||||
/* 2052 */ "Prepared statement contains no metadata",
|
||||
/* 2053 */ "",
|
||||
/* 2054 */ "This feature is not implemented or disabled",
|
||||
/* 2055 */ "Lost connection to MySQL server at '%s', system error: %d",
|
||||
/* 2056 */ "",
|
||||
/* 2057 */ "The number of parameters in bound buffers differs from number of columns in resultset",
|
||||
/* 2058 */ "Plugin %s could not be loaded: %s",
|
||||
/* 2059 */ "Can't connect twice. Already connected",
|
||||
/* 2060 */ "Plugin doesn't support this function",
|
||||
""
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
void init_client_errs(void)
|
||||
{
|
||||
my_errmsg[CLIENT_ERRMAP] = &client_errors[0];
|
||||
}
|
96
module/Vendor/MDBC/libmariadb/errors.c
vendored
Normal file
96
module/Vendor/MDBC/libmariadb/errors.c
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include "mysys_err.h"
|
||||
|
||||
#ifndef SHARED_LIBRARY
|
||||
|
||||
const char * NEAR globerrs[GLOBERRS]=
|
||||
{
|
||||
"Can't create/write to file '%s' (Errcode: %d)",
|
||||
"Error reading file '%s' (Errcode: %d)",
|
||||
"Error writing file '%s' (Errcode: %d)",
|
||||
"Error on close of '%s' (Errcode: %d)",
|
||||
"Out of memory (Needed %u bytes)",
|
||||
"Error on delete of '%s' (Errcode: %d)",
|
||||
"Error on rename of '%s' to '%s' (Errcode: %d)",
|
||||
"",
|
||||
"Unexpected eof found when reading file '%s' (Errcode: %d)",
|
||||
"Can't lock file (Errcode: %d)",
|
||||
"Can't unlock file (Errcode: %d)",
|
||||
"Can't read dir of '%s' (Errcode: %d)",
|
||||
"Can't get stat of '%s' (Errcode: %d)",
|
||||
"Can't change size of file (Errcode: %d)",
|
||||
"Can't open stream from handle (Errcode: %d)",
|
||||
"Can't get working dirctory (Errcode: %d)",
|
||||
"Can't change dir to '%s' (Errcode: %d)",
|
||||
"Warning: '%s' had %d links",
|
||||
"Warning: %d files and %d streams is left open\n",
|
||||
"Disk is full writing '%s' (Errcode: %d). Waiting for someone to free space... (Expect up to %d secs delay for server to continue after freeing disk space)",
|
||||
"Can't create directory '%s' (Errcode: %d)",
|
||||
"Character set '%s' is not a compiled character set and is not specified in the '%s' file",
|
||||
"Out of resources when opening file '%s' (Errcode: %d)",
|
||||
"Can't read value for symlink '%s' (Error %d)",
|
||||
"Can't create symlink '%s' pointing at '%s' (Error %d)",
|
||||
"Error on realpath() on '%s' (Error %d)",
|
||||
"Can't sync file '%s' to disk (Errcode: %d)",
|
||||
"Collation '%s' is not a compiled collation and is not specified in the '%s' file",
|
||||
"File '%s' not found (Errcode: %d)",
|
||||
"File '%s' (fileno: %d) was not closed",
|
||||
"Can't change mode for file '%s' to 0x%lx (Error: %d)"
|
||||
};
|
||||
|
||||
void init_glob_errs(void)
|
||||
{
|
||||
my_errmsg[GLOB] = & globerrs[0];
|
||||
} /* init_glob_errs */
|
||||
|
||||
#else
|
||||
|
||||
void init_glob_errs()
|
||||
{
|
||||
my_errmsg[GLOB] = & globerrs[0];
|
||||
|
||||
EE(EE_FILENOTFOUND) = "File '%s' not found (Errcode: %d)";
|
||||
EE(EE_CANTCREATEFILE) = "Can't create/write to file '%s' (Errcode: %d)";
|
||||
EE(EE_READ) = "Error reading file '%s' (Errcode: %d)";
|
||||
EE(EE_WRITE) = "Error writing file '%s' (Errcode: %d)";
|
||||
EE(EE_BADCLOSE) = "Error on close of '%'s (Errcode: %d)";
|
||||
EE(EE_OUTOFMEMORY) = "Out of memory (Needed %u bytes)";
|
||||
EE(EE_DELETE) = "Error on delete of '%s' (Errcode: %d)";
|
||||
EE(EE_LINK) = "Error on rename of '%s' to '%s' (Errcode: %d)";
|
||||
EE(EE_EOFERR) = "Unexpected eof found when reading file '%s' (Errcode: %d)";
|
||||
EE(EE_CANTLOCK) = "Can't lock file (Errcode: %d)";
|
||||
EE(EE_CANTUNLOCK) = "Can't unlock file (Errcode: %d)";
|
||||
EE(EE_DIR) = "Can't read dir of '%s' (Errcode: %d)";
|
||||
EE(EE_STAT) = "Can't get stat of '%s' (Errcode: %d)";
|
||||
EE(EE_CANT_CHSIZE) = "Can't change size of file (Errcode: %d)";
|
||||
EE(EE_CANT_OPEN_STREAM)= "Can't open stream from handle (Errcode: %d)";
|
||||
EE(EE_GETWD) = "Can't get working dirctory (Errcode: %d)";
|
||||
EE(EE_SETWD) = "Can't change dir to '%s' (Errcode: %d)";
|
||||
EE(EE_LINK_WARNING) = "Warning: '%s' had %d links";
|
||||
EE(EE_OPEN_WARNING) = "%d files and %d streams is left open\n";
|
||||
EE(EE_DISK_FULL) = "Disk is full writing '%s'. Waiting for someone to free space...";
|
||||
EE(EE_CANT_MKDIR) ="Can't create directory '%s' (Errcode: %d)";
|
||||
EE(EE_UNKNOWN_CHARSET)= "Character set is not a compiled character set and is not specified in the %s file";
|
||||
EE(EE_OUT_OF_FILERESOURCES)="Out of resources when opening file '%s' (Errcode: %d)";
|
||||
EE(EE_CANT_READLINK)="Can't read value for symlink '%s' (Error %d)";
|
||||
EE(EE_CANT_SYMLINK)="Can't create symlink '%s' pointing at '%s' (Error %d)";
|
||||
EE(EE_REALPATH)="Error on realpath() on '%s' (Error %d)";
|
||||
}
|
||||
#endif
|
175
module/Vendor/MDBC/libmariadb/get_password.c
vendored
Normal file
175
module/Vendor/MDBC/libmariadb/get_password.c
vendored
Normal file
@ -0,0 +1,175 @@
|
||||
/************************************************************************************
|
||||
Copyright (C) 2014 MariaDB Corporation 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
|
||||
*************************************************************************************/
|
||||
#include <my_global.h>
|
||||
#include <my_sys.h>
|
||||
#include "mysql.h"
|
||||
#include <m_string.h>
|
||||
#include <m_ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <termios.h>
|
||||
#else
|
||||
#include <conio.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/* {{{ static char *get_password() */
|
||||
/*
|
||||
read password from device
|
||||
|
||||
SYNOPSIS
|
||||
get_password
|
||||
Hdl/file file handle
|
||||
buffer input buffer
|
||||
length buffer length
|
||||
|
||||
RETURN
|
||||
buffer zero terminated input buffer
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
static char *get_password(HANDLE Hdl, char *buffer, DWORD length)
|
||||
#else
|
||||
static char *get_password(FILE *file, char *buffer, int length)
|
||||
#endif
|
||||
{
|
||||
char inChar;
|
||||
int CharsProcessed= 1;
|
||||
#ifdef _WIN32
|
||||
DWORD Offset= 0;
|
||||
#else
|
||||
int Offset= 0;
|
||||
#endif
|
||||
|
||||
memset(buffer, 0, length);
|
||||
|
||||
do
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (!ReadConsole(Hdl, &inChar, 1, &CharsProcessed, NULL) ||
|
||||
!CharsProcessed)
|
||||
break;
|
||||
#else
|
||||
inChar= fgetc(file);
|
||||
#endif
|
||||
|
||||
switch(inChar) {
|
||||
case '\b': /* backslash */
|
||||
if (Offset)
|
||||
{
|
||||
/* cursor is always at the end */
|
||||
Offset--;
|
||||
buffer[Offset]= 0;
|
||||
#ifdef _WIN32
|
||||
_cputs("\b \b");
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case '\n':
|
||||
case '\r':
|
||||
break;
|
||||
default:
|
||||
buffer[Offset]= inChar;
|
||||
if (Offset < length - 2)
|
||||
Offset++;
|
||||
#ifdef _WIN32
|
||||
_cputs("*");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
} while (CharsProcessed && inChar != '\n' && inChar != '\r');
|
||||
return buffer;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ static char* get_tty_password */
|
||||
/*
|
||||
reads password from tty/console
|
||||
|
||||
SYNOPSIS
|
||||
get_tty_password()
|
||||
buffer input buffer
|
||||
length length of input buffer
|
||||
|
||||
DESCRIPTION
|
||||
reads a password from console (Windows) or tty without echoing
|
||||
it's characters. Input buffer must be allocated by calling function.
|
||||
|
||||
RETURNS
|
||||
buffer pointer to input buffer
|
||||
*/
|
||||
char* get_tty_password(char *prompt, char *buffer, int length)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
DWORD SaveState;
|
||||
HANDLE Hdl;
|
||||
int Offset= 0;
|
||||
DWORD CharsProcessed= 0;
|
||||
|
||||
if (prompt)
|
||||
fprintf(stderr, "%s", prompt);
|
||||
|
||||
if (!(Hdl= CreateFile("CONIN$",
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_EXISTING, 0, NULL)))
|
||||
{
|
||||
/* todo: provide a graphical dialog */
|
||||
return buffer;
|
||||
}
|
||||
/* Save ConsoleMode and set ENABLE_PROCESSED_INPUT:
|
||||
CTRL+C is processed by the system and is not placed in the input buffer */
|
||||
GetConsoleMode(Hdl, &SaveState);
|
||||
SetConsoleMode(Hdl, ENABLE_PROCESSED_INPUT);
|
||||
|
||||
buffer= get_password(Hdl, buffer, length);
|
||||
SetConsoleMode(Hdl, SaveState);
|
||||
CloseHandle(Hdl);
|
||||
return buffer;
|
||||
#else
|
||||
struct termios term_old,
|
||||
term_new;
|
||||
FILE *readfrom;
|
||||
|
||||
if (prompt && isatty(fileno(stderr)))
|
||||
fputs(prompt, stderr);
|
||||
|
||||
if (!(readfrom= fopen("/dev/tty", "r")))
|
||||
readfrom= stdin;
|
||||
|
||||
/* try to disable echo */
|
||||
tcgetattr(fileno(readfrom), &term_old);
|
||||
term_new= term_old;
|
||||
term_new.c_cc[VMIN] = 1;
|
||||
term_new.c_cc[VTIME]= 0;
|
||||
term_new.c_lflag&= ~(ECHO | ISIG | ICANON | ECHONL);
|
||||
tcsetattr(fileno(readfrom), TCSADRAIN, &term_new);
|
||||
|
||||
buffer= get_password(readfrom, buffer, length);
|
||||
|
||||
if (isatty(fileno(readfrom)))
|
||||
tcsetattr(fileno(readfrom), TCSADRAIN, &term_old);
|
||||
|
||||
fclose(readfrom);
|
||||
|
||||
return buffer;
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
746
module/Vendor/MDBC/libmariadb/getopt.c
vendored
Normal file
746
module/Vendor/MDBC/libmariadb/getopt.c
vendored
Normal file
@ -0,0 +1,746 @@
|
||||
/* Getopt for GNU.
|
||||
NOTE: getopt is now part of the C library, so if you don't know what
|
||||
"Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
|
||||
before changing it!
|
||||
|
||||
Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
Changes by monty:
|
||||
- Added include of string.h when nessessary.
|
||||
- Removed two warnings from gcc.
|
||||
|
||||
This file is part of the GNU C Library. Its master source is NOT part of
|
||||
the C library, however. The master source lives in /gd/gnu/lib.
|
||||
|
||||
The GNU C 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.
|
||||
|
||||
The GNU C 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 the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
|
||||
Ditto for AIX 3.2 and <stdlib.h>. */
|
||||
#ifndef _NO_PROTO
|
||||
#define _NO_PROTO
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#if (!defined (__STDC__) || !__STDC__) && !defined(MSDOS) && !defined(OS2)
|
||||
/* This is a separate conditional since some stdc systems
|
||||
reject `defined (const)'. */
|
||||
#ifndef const
|
||||
#define const
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <my_global.h> /* Changes for mysys */
|
||||
#include <m_string.h>
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
|
||||
|
||||
|
||||
/* This needs to come after some library #include
|
||||
to get __GNU_LIBRARY__ defined. */
|
||||
#ifdef __GNU_LIBRARY__
|
||||
/* Don't include stdlib.h for non-GNU C libraries because some of them
|
||||
contain conflicting prototypes for getopt. */
|
||||
#include <stdlib.h>
|
||||
#endif /* GNU C library. */
|
||||
|
||||
/* This version of `getopt' appears to the caller like standard Unix `getopt'
|
||||
but it behaves differently for the user, since it allows the user
|
||||
to intersperse the options with the other arguments.
|
||||
|
||||
As `getopt' works, it permutes the elements of ARGV so that,
|
||||
when it is done, all the options precede everything else. Thus
|
||||
all application programs are extended to handle flexible argument order.
|
||||
|
||||
Setting the environment variable POSIXLY_CORRECT disables permutation.
|
||||
Then the behavior is completely standard.
|
||||
|
||||
GNU application programs can use a third alternative mode in which
|
||||
they can distinguish the relative order of options and other arguments. */
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
char *optarg = NULL;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `getopt'.
|
||||
|
||||
On entry to `getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `getopt' returns EOF, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
/* XXX 1003.2 says this must be 1 before any call. */
|
||||
int optind = 1;
|
||||
|
||||
/* The next char to be scanned in the option-element
|
||||
in which the last option character we returned was found.
|
||||
This allows us to pick up the scan where we left off.
|
||||
|
||||
If this is zero, or a null string, it means resume the scan
|
||||
by advancing to the next ARGV-element. */
|
||||
|
||||
static char *nextchar;
|
||||
|
||||
/* Callers store zero here to inhibit the error message
|
||||
for unrecognized options. */
|
||||
|
||||
int opterr = 1;
|
||||
|
||||
/* Set to an option character which was unrecognized.
|
||||
This must be initialized on some systems to avoid linking in the
|
||||
system's own getopt implementation. */
|
||||
|
||||
int optopt = '?';
|
||||
|
||||
/* Describe how to deal with options that follow non-option ARGV-elements.
|
||||
|
||||
If the caller did not specify anything,
|
||||
the default is REQUIRE_ORDER if the environment variable
|
||||
POSIXLY_CORRECT is defined, PERMUTE otherwise.
|
||||
|
||||
REQUIRE_ORDER means don't recognize them as options;
|
||||
stop option processing when the first non-option is seen.
|
||||
This is what Unix does.
|
||||
This mode of operation is selected by either setting the environment
|
||||
variable POSIXLY_CORRECT, or using `+' as the first character
|
||||
of the list of option characters.
|
||||
|
||||
PERMUTE is the default. We permute the contents of ARGV as we scan,
|
||||
so that eventually all the non-options are at the end. This allows options
|
||||
to be given in any order, even with programs that were not written to
|
||||
expect this.
|
||||
|
||||
RETURN_IN_ORDER is an option available to programs that were written
|
||||
to expect options and other ARGV-elements in any order and that care about
|
||||
the ordering of the two. We describe each non-option ARGV-element
|
||||
as if it were the argument of an option with character code 1.
|
||||
Using `-' as the first character of the list of option characters
|
||||
selects this mode of operation.
|
||||
|
||||
The special argument `--' forces an end of option-scanning regardless
|
||||
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
|
||||
`--' can cause `getopt' to return EOF with `optind' != ARGC. */
|
||||
|
||||
static enum
|
||||
{
|
||||
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
|
||||
} ordering;
|
||||
|
||||
/* Value of POSIXLY_CORRECT environment variable. */
|
||||
static char *posixly_correct;
|
||||
|
||||
#ifdef __GNU_LIBRARY__
|
||||
/* We want to avoid inclusion of string.h with non-GNU libraries
|
||||
because there are many ways it can cause trouble.
|
||||
On some systems, it contains special magic macros that don't work
|
||||
in GCC. */
|
||||
#include <string.h>
|
||||
#define my_index strchr
|
||||
#else
|
||||
|
||||
/* Avoid depending on library functions or files
|
||||
whose names are inconsistent. */
|
||||
|
||||
static char *
|
||||
my_index (const char *str, int chr)
|
||||
{
|
||||
while (*str)
|
||||
{
|
||||
if (*str == chr)
|
||||
return (char *) str;
|
||||
str++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If using GCC, we can safely declare strlen this way.
|
||||
If not using GCC, it is ok not to declare it. */
|
||||
#ifdef __GNUC__
|
||||
/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
|
||||
That was relevant to code that was here before. */
|
||||
#if !defined (__STDC__) || !__STDC__
|
||||
/* gcc with -traditional declares the built-in strlen to return int,
|
||||
and has done so at least since version 2.4.5. -- rms. */
|
||||
extern int strlen (const char *);
|
||||
#endif /* not __STDC__ */
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#endif /* not __GNU_LIBRARY__ */
|
||||
|
||||
/* Handle permutation of arguments. */
|
||||
|
||||
/* Describe the part of ARGV that contains non-options that have
|
||||
been skipped. `first_nonopt' is the index in ARGV of the first of them;
|
||||
`last_nonopt' is the index after the last of them. */
|
||||
|
||||
static int first_nonopt;
|
||||
static int last_nonopt;
|
||||
|
||||
/* Exchange two adjacent subsequences of ARGV.
|
||||
One subsequence is elements [first_nonopt,last_nonopt)
|
||||
which contains all the non-options that have been skipped so far.
|
||||
The other is elements [last_nonopt,optind), which contains all
|
||||
the options processed since those non-options were skipped.
|
||||
|
||||
`first_nonopt' and `last_nonopt' are relocated so that they describe
|
||||
the new indices of the non-options in ARGV after they are moved. */
|
||||
|
||||
static void
|
||||
exchange (char **argv)
|
||||
{
|
||||
int bottom = first_nonopt;
|
||||
int middle = last_nonopt;
|
||||
int top = optind;
|
||||
char *tem;
|
||||
|
||||
/* Exchange the shorter segment with the far end of the longer segment.
|
||||
That puts the shorter segment into the right place.
|
||||
It leaves the longer segment in the right place overall,
|
||||
but it consists of two parts that need to be swapped next. */
|
||||
|
||||
while (top > middle && middle > bottom)
|
||||
{
|
||||
if (top - middle > middle - bottom)
|
||||
{
|
||||
/* Bottom segment is the short one. */
|
||||
int len = middle - bottom;
|
||||
register int i;
|
||||
|
||||
/* Swap it with the top part of the top segment. */
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
tem = argv[bottom + i];
|
||||
argv[bottom + i] = argv[top - (middle - bottom) + i];
|
||||
argv[top - (middle - bottom) + i] = tem;
|
||||
}
|
||||
/* Exclude the moved bottom segment from further swapping. */
|
||||
top -= len;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Top segment is the short one. */
|
||||
int len = top - middle;
|
||||
register int i;
|
||||
|
||||
/* Swap it with the bottom part of the bottom segment. */
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
tem = argv[bottom + i];
|
||||
argv[bottom + i] = argv[middle + i];
|
||||
argv[middle + i] = tem;
|
||||
}
|
||||
/* Exclude the moved top segment from further swapping. */
|
||||
bottom += len;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update records for the slots the non-options now occupy. */
|
||||
|
||||
first_nonopt += (optind - last_nonopt);
|
||||
last_nonopt = optind;
|
||||
}
|
||||
|
||||
/* Initialize the internal data when the first call is made. */
|
||||
|
||||
static const char *
|
||||
_getopt_initialize (const char *optstring)
|
||||
{
|
||||
/* Start processing options with ARGV-element 1 (since ARGV-element 0
|
||||
is the program name); the sequence of previously skipped
|
||||
non-option ARGV-elements is empty. */
|
||||
|
||||
first_nonopt = last_nonopt = optind = 1;
|
||||
|
||||
nextchar = NULL;
|
||||
|
||||
posixly_correct = getenv ("POSIXLY_CORRECT");
|
||||
|
||||
/* Determine how to handle the ordering of options and nonoptions. */
|
||||
|
||||
if (optstring[0] == '-')
|
||||
{
|
||||
ordering = RETURN_IN_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (optstring[0] == '+')
|
||||
{
|
||||
ordering = REQUIRE_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (posixly_correct != NULL)
|
||||
ordering = REQUIRE_ORDER;
|
||||
else
|
||||
ordering = PERMUTE;
|
||||
|
||||
return optstring;
|
||||
}
|
||||
|
||||
/* Scan elements of ARGV (whose length is ARGC) for option characters
|
||||
given in OPTSTRING.
|
||||
|
||||
If an element of ARGV starts with '-', and is not exactly "-" or "--",
|
||||
then it is an option element. The characters of this element
|
||||
(aside from the initial '-') are option characters. If `getopt'
|
||||
is called repeatedly, it returns successively each of the option characters
|
||||
from each of the option elements.
|
||||
|
||||
If `getopt' finds another option character, it returns that character,
|
||||
updating `optind' and `nextchar' so that the next call to `getopt' can
|
||||
resume the scan with the following option character or ARGV-element.
|
||||
|
||||
If there are no more option characters, `getopt' returns `EOF'.
|
||||
Then `optind' is the index in ARGV of the first ARGV-element
|
||||
that is not an option. (The ARGV-elements have been permuted
|
||||
so that those that are not options now come last.)
|
||||
|
||||
OPTSTRING is a string containing the legitimate option characters.
|
||||
If an option character is seen that is not listed in OPTSTRING,
|
||||
return '?' after printing an error message. If you set `opterr' to
|
||||
zero, the error message is suppressed but we still return '?'.
|
||||
|
||||
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
|
||||
so the following text in the same ARGV-element, or the text of the following
|
||||
ARGV-element, is returned in `optarg'. Two colons mean an option that
|
||||
wants an optional arg; if there is text in the current ARGV-element,
|
||||
it is returned in `optarg', otherwise `optarg' is set to zero.
|
||||
|
||||
If OPTSTRING starts with `-' or `+', it requests different methods of
|
||||
handling the non-option ARGV-elements.
|
||||
See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
|
||||
|
||||
Long-named options begin with `--' instead of `-'.
|
||||
Their names may be abbreviated as long as the abbreviation is unique
|
||||
or is an exact match for some defined option. If they have an
|
||||
argument, it follows the option name in the same ARGV-element, separated
|
||||
from the option name by a `=', or else the in next ARGV-element.
|
||||
When `getopt' finds a long-named option, it returns 0 if that option's
|
||||
`flag' field is nonzero, the value of the option's `val' field
|
||||
if the `flag' field is zero.
|
||||
|
||||
The elements of ARGV aren't really const, because we permute them.
|
||||
But we pretend they're const in the prototype to be compatible
|
||||
with other systems.
|
||||
|
||||
LONGOPTS is a vector of `struct option' terminated by an
|
||||
element containing a name which is zero.
|
||||
|
||||
LONGIND returns the index in LONGOPT of the long-named option found.
|
||||
It is only valid when a long-named option has been found by the most
|
||||
recent call.
|
||||
|
||||
If LONG_ONLY is nonzero, '-' as well as '--' can introduce
|
||||
long-named options. */
|
||||
|
||||
int
|
||||
_getopt_internal (int argc, char *const *argv, const char *optstring, const struct option *longopts, int *longind, int long_only)
|
||||
{
|
||||
optarg = NULL;
|
||||
|
||||
if (optind == 0)
|
||||
optstring = _getopt_initialize (optstring);
|
||||
|
||||
if (nextchar == NULL || *nextchar == '\0')
|
||||
{
|
||||
/* Advance to the next ARGV-element. */
|
||||
|
||||
if (ordering == PERMUTE)
|
||||
{
|
||||
/* If we have just processed some options following some non-options,
|
||||
exchange them so that the options come first. */
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||
exchange ((char **) argv);
|
||||
else if (last_nonopt != optind)
|
||||
first_nonopt = optind;
|
||||
|
||||
/* Skip any additional non-options
|
||||
and extend the range of non-options previously skipped. */
|
||||
|
||||
while (optind < argc
|
||||
&& (argv[optind][0] != '-' || argv[optind][1] == '\0'))
|
||||
optind++;
|
||||
last_nonopt = optind;
|
||||
}
|
||||
|
||||
/* The special ARGV-element `--' means premature end of options.
|
||||
Skip it like a null option,
|
||||
then exchange with previous non-options as if it were an option,
|
||||
then skip everything else like a non-option. */
|
||||
|
||||
if (optind != argc && !strcmp (argv[optind], "--"))
|
||||
{
|
||||
optind++;
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||
exchange ((char **) argv);
|
||||
else if (first_nonopt == last_nonopt)
|
||||
first_nonopt = optind;
|
||||
last_nonopt = argc;
|
||||
|
||||
optind = argc;
|
||||
}
|
||||
|
||||
/* If we have done all the ARGV-elements, stop the scan
|
||||
and back over any non-options that we skipped and permuted. */
|
||||
|
||||
if (optind == argc)
|
||||
{
|
||||
/* Set the next-arg-index to point at the non-options
|
||||
that we previously skipped, so the caller will digest them. */
|
||||
if (first_nonopt != last_nonopt)
|
||||
optind = first_nonopt;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* If we have come to a non-option and did not permute it,
|
||||
either stop the scan or describe it to the caller and pass it by. */
|
||||
|
||||
if ((argv[optind][0] != '-' || argv[optind][1] == '\0'))
|
||||
{
|
||||
if (ordering == REQUIRE_ORDER)
|
||||
return EOF;
|
||||
optarg = argv[optind++];
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* We have found another option-ARGV-element.
|
||||
Skip the initial punctuation. */
|
||||
|
||||
nextchar = (argv[optind] + 1
|
||||
+ (longopts != NULL && argv[optind][1] == '-'));
|
||||
}
|
||||
|
||||
/* Decode the current option-ARGV-element. */
|
||||
|
||||
/* Check whether the ARGV-element is a long option.
|
||||
|
||||
If long_only and the ARGV-element has the form "-f", where f is
|
||||
a valid short option, don't consider it an abbreviated form of
|
||||
a long option that starts with f. Otherwise there would be no
|
||||
way to give the -f short option.
|
||||
|
||||
On the other hand, if there's a long option "fubar" and
|
||||
the ARGV-element is "-fu", do consider that an abbreviation of
|
||||
the long option, just like "--fu", and not "-f" with arg "u".
|
||||
|
||||
This distinction seems to be the most useful approach. */
|
||||
|
||||
if (longopts != NULL
|
||||
&& (argv[optind][1] == '-'
|
||||
|| (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
|
||||
{
|
||||
char *nameend;
|
||||
const struct option *p;
|
||||
const struct option *pfound = NULL;
|
||||
int exact = 0;
|
||||
int ambig = 0;
|
||||
int indfound=0; /* Keep gcc happy */
|
||||
int option_index;
|
||||
|
||||
for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
|
||||
/* Do nothing. */ ;
|
||||
|
||||
/* Test all long options for either exact match
|
||||
or abbreviated matches. */
|
||||
for (p = longopts, option_index = 0; p->name; p++, option_index++)
|
||||
if (!strncmp (p->name, nextchar, nameend - nextchar))
|
||||
{
|
||||
if ((size_t) (nameend - nextchar) == (size_t) strlen (p->name))
|
||||
{
|
||||
/* Exact match found. */
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
exact = 1;
|
||||
break;
|
||||
}
|
||||
else if (pfound == NULL)
|
||||
{
|
||||
/* First nonexact match found. */
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
}
|
||||
else
|
||||
/* Second or later nonexact match found. */
|
||||
ambig = 1;
|
||||
}
|
||||
|
||||
if (ambig && !exact)
|
||||
{
|
||||
if (opterr)
|
||||
fprintf (stderr, "%s: option `%s' is ambiguous\n",
|
||||
argv[0], argv[optind]);
|
||||
nextchar += strlen (nextchar);
|
||||
optind++;
|
||||
return '?';
|
||||
}
|
||||
|
||||
if (pfound != NULL)
|
||||
{
|
||||
option_index = indfound;
|
||||
optind++;
|
||||
if (*nameend)
|
||||
{
|
||||
/* Don't test has_arg with >, because some C compilers don't
|
||||
allow it to be used on enums. */
|
||||
if (pfound->has_arg)
|
||||
optarg = nameend + 1;
|
||||
else
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
if (argv[optind - 1][1] == '-')
|
||||
/* --option */
|
||||
fprintf (stderr,
|
||||
"%s: option `--%s' doesn't allow an argument\n",
|
||||
argv[0], pfound->name);
|
||||
else
|
||||
/* +option or -option */
|
||||
fprintf (stderr,
|
||||
"%s: option `%c%s' doesn't allow an argument\n",
|
||||
argv[0], argv[optind - 1][0], pfound->name);
|
||||
}
|
||||
nextchar += strlen (nextchar);
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
else if (pfound->has_arg == 1)
|
||||
{
|
||||
if (optind < argc)
|
||||
optarg = argv[optind++];
|
||||
else
|
||||
{
|
||||
if (opterr)
|
||||
fprintf (stderr, "%s: option `%s' requires an argument\n",
|
||||
argv[0], argv[optind - 1]);
|
||||
nextchar += strlen (nextchar);
|
||||
return optstring[0] == ':' ? ':' : '?';
|
||||
}
|
||||
}
|
||||
nextchar += strlen (nextchar);
|
||||
if (longind != NULL)
|
||||
*longind = option_index;
|
||||
if (pfound->flag)
|
||||
{
|
||||
*(pfound->flag) = pfound->val;
|
||||
return 0;
|
||||
}
|
||||
return pfound->val;
|
||||
}
|
||||
|
||||
/* Can't find it as a long option. If this is not getopt_long_only,
|
||||
or the option starts with '--' or is not a valid short
|
||||
option, then it's an error.
|
||||
Otherwise interpret it as a short option. */
|
||||
if (!long_only || argv[optind][1] == '-'
|
||||
|| my_index (optstring, *nextchar) == NULL)
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
if (argv[optind][1] == '-')
|
||||
/* --option */
|
||||
fprintf (stderr, "%s: unrecognized option `--%s'\n",
|
||||
argv[0], nextchar);
|
||||
else
|
||||
/* +option or -option */
|
||||
fprintf (stderr, "%s: unrecognized option `%c%s'\n",
|
||||
argv[0], argv[optind][0], nextchar);
|
||||
}
|
||||
nextchar = (char *) "";
|
||||
optind++;
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
/* Look at and handle the next short option-character. */
|
||||
|
||||
{
|
||||
char c = *nextchar++;
|
||||
char *temp = my_index (optstring, c);
|
||||
|
||||
/* Increment `optind' when we start to process its last character. */
|
||||
if (*nextchar == '\0')
|
||||
++optind;
|
||||
|
||||
if (temp == NULL || c == ':')
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
if (posixly_correct)
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
|
||||
else
|
||||
fprintf (stderr, "%s: invalid option -- %c\n", argv[0], c);
|
||||
}
|
||||
optopt = c;
|
||||
return '?';
|
||||
}
|
||||
if (temp[1] == ':')
|
||||
{
|
||||
if (temp[2] == ':')
|
||||
{
|
||||
/* This is an option that accepts an argument optionally. */
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
optarg = nextchar;
|
||||
optind++;
|
||||
}
|
||||
else
|
||||
optarg = NULL;
|
||||
nextchar = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is an option that requires an argument. */
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
optarg = nextchar;
|
||||
/* If we end this ARGV-element by taking the rest as an arg,
|
||||
we must advance to the next element now. */
|
||||
optind++;
|
||||
}
|
||||
else if (optind == argc)
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fprintf (stderr, "%s: option requires an argument -- %c\n",
|
||||
argv[0], c);
|
||||
}
|
||||
optopt = c;
|
||||
if (optstring[0] == ':')
|
||||
c = ':';
|
||||
else
|
||||
c = '?';
|
||||
}
|
||||
else
|
||||
/* We already incremented `optind' once;
|
||||
increment it again when taking next ARGV-elt as argument. */
|
||||
optarg = argv[optind++];
|
||||
nextchar = NULL;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __EMX__
|
||||
int getopt (int argc, char **argv, __const__ char *optstring)
|
||||
#else
|
||||
int
|
||||
getopt (int argc, char *const *argv, const char *optstring)
|
||||
#endif
|
||||
{
|
||||
return _getopt_internal (argc, argv, optstring,
|
||||
(const struct option *) 0,
|
||||
(int *) 0,
|
||||
0);
|
||||
}
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
/* Compile with -DTEST to make an executable for use in testing
|
||||
the above definition of `getopt'. */
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
int digit_optind = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int this_option_optind = optind ? optind : 1;
|
||||
|
||||
c = getopt (argc, argv, "abc:d:0123456789");
|
||||
if (c == EOF)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
||||
printf ("digits occur in two different argv-elements.\n");
|
||||
digit_optind = this_option_optind;
|
||||
printf ("option %c\n", c);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
printf ("option a\n");
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf ("option b\n");
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printf ("option c with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
printf ("non-option ARGV-elements: ");
|
||||
while (optind < argc)
|
||||
printf ("%s ", argv[optind++]);
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
170
module/Vendor/MDBC/libmariadb/getopt1.c
vendored
Normal file
170
module/Vendor/MDBC/libmariadb/getopt1.c
vendored
Normal file
@ -0,0 +1,170 @@
|
||||
/* getopt_long and getopt_long_only entry points for GNU getopt.
|
||||
Copyright (C) 1987, 88, 89, 90, 91, 92, 1993, 1994
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU C Library. Its master source is NOT part of
|
||||
the C library, however. The master source lives in /gd/gnu/lib.
|
||||
|
||||
The GNU C 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.
|
||||
|
||||
The GNU C 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 the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <my_global.h>
|
||||
#include "getopt.h"
|
||||
|
||||
#if (!defined (__STDC__) || !__STDC__) && !defined(MSDOS) && !defined(OS2)
|
||||
/* This is a separate conditional since some stdc systems
|
||||
reject `defined (const)'. */
|
||||
#ifndef const
|
||||
#define const
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <stdlib.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
int
|
||||
getopt_long (int argc, char *const *argv, const char *options, const struct option *long_options, int *opt_index)
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
|
||||
}
|
||||
|
||||
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
|
||||
If an option that starts with '-' (not '--') doesn't match a long option,
|
||||
but does match a short option, it is parsed as a short option
|
||||
instead. */
|
||||
|
||||
int
|
||||
getopt_long_only (int argc, char *const *argv, const char *options, const struct option *long_options, int *opt_index)
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
|
||||
}
|
||||
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
int digit_optind = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int this_option_optind = optind ? optind : 1;
|
||||
int option_index = 0;
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"add", 1, 0, 0},
|
||||
{"append", 0, 0, 0},
|
||||
{"delete", 1, 0, 0},
|
||||
{"verbose", 0, 0, 0},
|
||||
{"create", 0, 0, 0},
|
||||
{"file", 1, 0, 0},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
c = getopt_long (argc, argv, "abc:d:0123456789",
|
||||
long_options, &option_index);
|
||||
if (c == EOF)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 0:
|
||||
printf ("option %s", long_options[option_index].name);
|
||||
if (optarg)
|
||||
printf (" with arg %s", optarg);
|
||||
printf ("\n");
|
||||
break;
|
||||
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
||||
printf ("digits occur in two different argv-elements.\n");
|
||||
digit_optind = this_option_optind;
|
||||
printf ("option %c\n", c);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
printf ("option a\n");
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf ("option b\n");
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printf ("option c with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
printf ("option d with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
printf ("non-option ARGV-elements: ");
|
||||
while (optind < argc)
|
||||
printf ("%s ", argv[optind++]);
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
644
module/Vendor/MDBC/libmariadb/hash.c
vendored
Normal file
644
module/Vendor/MDBC/libmariadb/hash.c
vendored
Normal file
@ -0,0 +1,644 @@
|
||||
/************************************************************************************
|
||||
Copyright (C) 2000, 2012 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
|
||||
*************************************************************************************/
|
||||
|
||||
/* 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 uchar *key,uint length);
|
||||
static uint calc_hashnr_caseup(const uchar *key,uint length);
|
||||
static int hashcmp(HASH *hash,HASH_LINK *pos,const uchar *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 uchar* as HPUX11 compiler can't
|
||||
handle inline functions that are not defined as native types
|
||||
*/
|
||||
|
||||
static inline char*
|
||||
hash_key(HASH *hash,const uchar *record,uint *length,my_bool first)
|
||||
{
|
||||
if (hash->get_key)
|
||||
return (*hash->get_key)(record,(uint *)length,first);
|
||||
*length=hash->key_length;
|
||||
return (uchar*) 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;
|
||||
uchar *key= (uchar*) 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 uchar *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 uchar *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 uchar *key, uint len)
|
||||
{
|
||||
const uchar *end=key+len;
|
||||
uint hash;
|
||||
for (hash = 0; key < end; key++)
|
||||
{
|
||||
hash *= 16777619;
|
||||
hash ^= (uint) *(uchar*) key;
|
||||
}
|
||||
return (hash);
|
||||
}
|
||||
|
||||
uint calc_hashnr_caseup(const uchar *key, uint len)
|
||||
{
|
||||
const uchar *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 */
|
||||
static inline
|
||||
#endif
|
||||
unsigned int rec_hashnr(HASH *hash,const uchar *record)
|
||||
{
|
||||
uint length;
|
||||
uchar *key= (uchar*) 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 uchar *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 uchar *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 uchar *key,uint length)
|
||||
{
|
||||
uint rec_keylength;
|
||||
uchar *rec_key= (uchar*) hash_key(hash,pos->data,&rec_keylength,1);
|
||||
return (length && length != rec_keylength) ||
|
||||
memcmp(rec_key,key,rec_keylength);
|
||||
}
|
||||
|
||||
|
||||
/* Write a hash-key to the hash-index */
|
||||
|
||||
my_bool hash_insert(HASH *info,const uchar *record)
|
||||
{
|
||||
int flag;
|
||||
uint halfbuff,hash_nr,first_index,idx;
|
||||
uchar *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=(uchar*) 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=(uchar*) record;
|
||||
pos->next=(uint) (empty - data);
|
||||
}
|
||||
else
|
||||
{
|
||||
pos->data=(uchar*) 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,uchar *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)((uchar*) 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,uchar *record,uchar *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);
|
||||
}
|
||||
|
||||
|
||||
uchar *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
|
153
module/Vendor/MDBC/libmariadb/int2str.c
vendored
Normal file
153
module/Vendor/MDBC/libmariadb/int2str.c
vendored
Normal file
@ -0,0 +1,153 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/*
|
||||
Defines: int2str(), itoa(), ltoa()
|
||||
|
||||
int2str(dst, radix, val)
|
||||
converts the (long) integer "val" to character form and moves it to
|
||||
the destination string "dst" followed by a terminating NUL. The
|
||||
result is normally a pointer to this NUL character, but if the radix
|
||||
is dud the result will be NullS and nothing will be changed.
|
||||
|
||||
If radix is -2..-36, val is taken to be SIGNED.
|
||||
If radix is 2.. 36, val is taken to be UNSIGNED.
|
||||
That is, val is signed if and only if radix is. You will normally
|
||||
use radix -10 only through itoa and ltoa, for radix 2, 8, or 16
|
||||
unsigned is what you generally want.
|
||||
|
||||
_dig_vec is public just in case someone has a use for it.
|
||||
The definitions of itoa and ltoa are actually macros in m_string.h,
|
||||
but this is where the code is.
|
||||
|
||||
Note: The standard itoa() returns a pointer to the argument, when int2str
|
||||
returns the pointer to the end-null.
|
||||
itoa assumes that 10 -base numbers are allways signed and other arn't.
|
||||
*/
|
||||
|
||||
#include <my_global.h>
|
||||
#include "m_string.h"
|
||||
|
||||
char NEAR _dig_vec[] =
|
||||
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
|
||||
|
||||
char *int2str(register long int val, register char *dst, register int radix)
|
||||
{
|
||||
char buffer[65];
|
||||
register char *p;
|
||||
long int new_val;
|
||||
|
||||
if (radix < 0) {
|
||||
if (radix < -36 || radix > -2) return NullS;
|
||||
if (val < 0) {
|
||||
*dst++ = '-';
|
||||
val = -val;
|
||||
}
|
||||
radix = -radix;
|
||||
} else {
|
||||
if (radix > 36 || radix < 2) return NullS;
|
||||
}
|
||||
/* The slightly contorted code which follows is due to the
|
||||
fact that few machines directly support unsigned long / and %.
|
||||
Certainly the VAX C compiler generates a subroutine call. In
|
||||
the interests of efficiency (hollow laugh) I let this happen
|
||||
for the first digit only; after that "val" will be in range so
|
||||
that signed integer division will do. Sorry 'bout that.
|
||||
CHECK THE CODE PRODUCED BY YOUR C COMPILER. The first % and /
|
||||
should be unsigned, the second % and / signed, but C compilers
|
||||
tend to be extraordinarily sensitive to minor details of style.
|
||||
This works on a VAX, that's all I claim for it.
|
||||
*/
|
||||
p = &buffer[sizeof(buffer)-1];
|
||||
*p = '\0';
|
||||
new_val=(ulong) val / (ulong) radix;
|
||||
*--p = _dig_vec[(uchar) ((ulong) val- (ulong) new_val*(ulong) radix)];
|
||||
val = new_val;
|
||||
#ifdef HAVE_LDIV
|
||||
while (val != 0)
|
||||
{
|
||||
ldiv_t res;
|
||||
res=ldiv(val,radix);
|
||||
*--p = _dig_vec[res.rem];
|
||||
val= res.quot;
|
||||
}
|
||||
#else
|
||||
while (val != 0)
|
||||
{
|
||||
new_val=val/radix;
|
||||
*--p = _dig_vec[(uchar) (val-new_val*radix)];
|
||||
val= new_val;
|
||||
}
|
||||
#endif
|
||||
while ((*dst++ = *p++) != 0) ;
|
||||
return dst-1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This is a faster version of the above optimized for the normal case of
|
||||
radix 10 / -10
|
||||
*/
|
||||
|
||||
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 && val < 0) /* -10 */
|
||||
{
|
||||
*dst++ = '-';
|
||||
uval = (unsigned long int)0-uval;
|
||||
}
|
||||
|
||||
p = &buffer[sizeof(buffer)-1];
|
||||
*p = '\0';
|
||||
new_val= (long)(uval / 10);
|
||||
*--p = '0'+ (char)(uval - (unsigned long)new_val * 10);
|
||||
val = new_val;
|
||||
|
||||
while (val != 0)
|
||||
{
|
||||
new_val=val/10;
|
||||
*--p = '0' + (char) (val-new_val*10);
|
||||
val= new_val;
|
||||
}
|
||||
while ((*dst++ = *p++) != 0) ;
|
||||
return dst-1;
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_MY_ITOA
|
||||
|
||||
/* Change to less general itoa interface */
|
||||
|
||||
char *my_itoa(int val, char *dst, int radix)
|
||||
{
|
||||
VOID(int2str((long) val,dst,(radix == 10 ? -10 : radix)));
|
||||
return dst;
|
||||
}
|
||||
|
||||
char *my_ltoa(long int val, char *dst, int radix)
|
||||
{
|
||||
VOID(int2str((long) val,dst,(radix == 10 ? -10 : radix)));
|
||||
return dst;
|
||||
}
|
||||
|
||||
#endif
|
34
module/Vendor/MDBC/libmariadb/is_prefix.c
vendored
Normal file
34
module/Vendor/MDBC/libmariadb/is_prefix.c
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* File : is_prefix.c
|
||||
Author : Michael Widenius
|
||||
Defines: is_prefix()
|
||||
|
||||
is_prefix(s, t) returns 1 if s starts with t.
|
||||
A empty t is allways a prefix.
|
||||
*/
|
||||
|
||||
#include <my_global.h>
|
||||
#include "m_string.h"
|
||||
|
||||
int is_prefix(register const char *s, register const char *t)
|
||||
{
|
||||
while (*t)
|
||||
if (*s++ != *t++) return 0;
|
||||
return 1; /* WRONG */
|
||||
}
|
3728
module/Vendor/MDBC/libmariadb/libmariadb.c
vendored
Normal file
3728
module/Vendor/MDBC/libmariadb/libmariadb.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
116
module/Vendor/MDBC/libmariadb/list.c
vendored
Normal file
116
module/Vendor/MDBC/libmariadb/list.c
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/*
|
||||
Code for handling dubble-linked lists in C
|
||||
*/
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include <my_list.h>
|
||||
|
||||
|
||||
|
||||
/* Add a element to start of list */
|
||||
|
||||
LIST *list_add(LIST *root, LIST *element)
|
||||
{
|
||||
DBUG_ENTER("list_add");
|
||||
DBUG_PRINT("enter",("root: %lx element: %lx", root, element));
|
||||
if (root)
|
||||
{
|
||||
if (root->prev) /* If add in mid of list */
|
||||
root->prev->next= element;
|
||||
element->prev=root->prev;
|
||||
root->prev=element;
|
||||
}
|
||||
else
|
||||
element->prev=0;
|
||||
element->next=root;
|
||||
DBUG_RETURN(element); /* New root */
|
||||
}
|
||||
|
||||
|
||||
LIST *list_delete(LIST *root, LIST *element)
|
||||
{
|
||||
if (element->prev)
|
||||
element->prev->next=element->next;
|
||||
else
|
||||
root=element->next;
|
||||
if (element->next)
|
||||
element->next->prev=element->prev;
|
||||
return root;
|
||||
}
|
||||
|
||||
|
||||
void list_free(LIST *root, unsigned int free_data)
|
||||
{
|
||||
LIST *next;
|
||||
while (root)
|
||||
{
|
||||
next=root->next;
|
||||
if (free_data)
|
||||
my_free(root->data);
|
||||
my_free(root);
|
||||
root=next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LIST *list_cons(void *data, LIST *list)
|
||||
{
|
||||
LIST *new_charset=(LIST*) my_malloc(sizeof(LIST),MYF(MY_FAE));
|
||||
if (!new_charset)
|
||||
return 0;
|
||||
new_charset->data=data;
|
||||
return list_add(list,new_charset);
|
||||
}
|
||||
|
||||
|
||||
LIST *list_reverse(LIST *root)
|
||||
{
|
||||
LIST *last;
|
||||
|
||||
last=root;
|
||||
while (root)
|
||||
{
|
||||
last=root;
|
||||
root=root->next;
|
||||
last->next=last->prev;
|
||||
last->prev=root;
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
||||
uint list_length(LIST *list)
|
||||
{
|
||||
uint count;
|
||||
for (count=0 ; list ; list=list->next, count++) ;
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
int list_walk(LIST *list, list_walk_action action, gptr argument)
|
||||
{
|
||||
int error=0;
|
||||
while (list)
|
||||
{
|
||||
if ((error = (*action)(list->data,argument)))
|
||||
return error;
|
||||
list=rest(list);
|
||||
}
|
||||
return 0;
|
||||
}
|
36
module/Vendor/MDBC/libmariadb/llstr.c
vendored
Normal file
36
module/Vendor/MDBC/libmariadb/llstr.c
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/*
|
||||
Defines: llstr();
|
||||
|
||||
llstr(value, buff);
|
||||
|
||||
This function saves a longlong value in a buffer and returns the pointer to
|
||||
the buffer. This is useful when trying to portable print longlong
|
||||
variables with printf() as there is no usable printf() standard one can use.
|
||||
*/
|
||||
|
||||
|
||||
#include <my_global.h>
|
||||
#include "m_string.h"
|
||||
|
||||
char *llstr(longlong value,char *buff)
|
||||
{
|
||||
longlong2str(value,buff,-10);
|
||||
return buff;
|
||||
}
|
143
module/Vendor/MDBC/libmariadb/longlong2str.c
vendored
Normal file
143
module/Vendor/MDBC/libmariadb/longlong2str.c
vendored
Normal file
@ -0,0 +1,143 @@
|
||||
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/*
|
||||
Defines: longlong2str();
|
||||
|
||||
longlong2str(dst, radix, val)
|
||||
converts the (longlong) integer "val" to character form and moves it to
|
||||
the destination string "dst" followed by a terminating NUL. The
|
||||
result is normally a pointer to this NUL character, but if the radix
|
||||
is dud the result will be NullS and nothing will be changed.
|
||||
|
||||
If radix is -2..-36, val is taken to be SIGNED.
|
||||
If radix is 2.. 36, val is taken to be UNSIGNED.
|
||||
That is, val is signed if and only if radix is. You will normally
|
||||
use radix -10 only through itoa and ltoa, for radix 2, 8, or 16
|
||||
unsigned is what you generally want.
|
||||
|
||||
_dig_vec is public just in case someone has a use for it.
|
||||
The definitions of itoa and ltoa are actually macros in m_string.h,
|
||||
but this is where the code is.
|
||||
|
||||
Note: The standard itoa() returns a pointer to the argument, when int2str
|
||||
returns the pointer to the end-null.
|
||||
itoa assumes that 10 -base numbers are allways signed and other arn't.
|
||||
*/
|
||||
|
||||
#include <my_global.h>
|
||||
#include "m_string.h"
|
||||
|
||||
#if defined(HAVE_LONG_LONG) && !defined(longlong2str) && !defined(HAVE_LONGLONG2STR)
|
||||
|
||||
extern char NEAR _dig_vec[];
|
||||
|
||||
/*
|
||||
This assumes that longlong multiplication is faster than longlong division.
|
||||
*/
|
||||
|
||||
char *longlong2str(longlong val,char *dst,int radix)
|
||||
{
|
||||
char buffer[65];
|
||||
register char *p;
|
||||
long long_val;
|
||||
|
||||
if (radix < 0)
|
||||
{
|
||||
if (radix < -36 || radix > -2) return (char*) 0;
|
||||
if (val < 0) {
|
||||
*dst++ = '-';
|
||||
val = -val;
|
||||
}
|
||||
radix = -radix;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (radix > 36 || radix < 2) return (char*) 0;
|
||||
}
|
||||
if (val == 0)
|
||||
{
|
||||
*dst++='0';
|
||||
*dst='\0';
|
||||
return dst;
|
||||
}
|
||||
p = &buffer[sizeof(buffer)-1];
|
||||
*p = '\0';
|
||||
|
||||
while ((ulonglong) val > (ulonglong) LONG_MAX)
|
||||
{
|
||||
ulonglong quo=(ulonglong) val/(uint) radix;
|
||||
uint rem= (uint) (val- quo* (uint) radix);
|
||||
*--p = _dig_vec[rem];
|
||||
val= quo;
|
||||
}
|
||||
long_val= (long) val;
|
||||
while (long_val != 0)
|
||||
{
|
||||
long quo= long_val/radix;
|
||||
*--p = _dig_vec[(uchar) (long_val - quo*radix)];
|
||||
long_val= quo;
|
||||
}
|
||||
while ((*dst++ = *p++) != 0) ;
|
||||
return dst-1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef longlong10_to_str
|
||||
char *longlong10_to_str(longlong val,char *dst,int radix)
|
||||
{
|
||||
char buffer[65];
|
||||
register char *p;
|
||||
long long_val;
|
||||
|
||||
if (radix < 0)
|
||||
{
|
||||
if (val < 0)
|
||||
{
|
||||
*dst++ = '-';
|
||||
val = -val;
|
||||
}
|
||||
}
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
*dst++='0';
|
||||
*dst='\0';
|
||||
return dst;
|
||||
}
|
||||
p = &buffer[sizeof(buffer)-1];
|
||||
*p = '\0';
|
||||
|
||||
while ((ulonglong) val > (ulonglong) LONG_MAX)
|
||||
{
|
||||
ulonglong quo=(ulonglong) val/(uint) 10;
|
||||
uint rem= (uint) (val- quo* (uint) 10);
|
||||
*--p = _dig_vec[rem];
|
||||
val= quo;
|
||||
}
|
||||
long_val= (long) val;
|
||||
while (long_val != 0)
|
||||
{
|
||||
long quo= long_val/10;
|
||||
*--p = _dig_vec[(uchar) (long_val - quo*10)];
|
||||
long_val= quo;
|
||||
}
|
||||
while ((*dst++ = *p++) != 0) ;
|
||||
return dst-1;
|
||||
}
|
||||
#endif
|
1925
module/Vendor/MDBC/libmariadb/ma_dtoa.c
vendored
Normal file
1925
module/Vendor/MDBC/libmariadb/ma_dtoa.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4401
module/Vendor/MDBC/libmariadb/ma_dyncol.c
vendored
Normal file
4401
module/Vendor/MDBC/libmariadb/ma_dyncol.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
700
module/Vendor/MDBC/libmariadb/ma_secure.c
vendored
Normal file
700
module/Vendor/MDBC/libmariadb/ma_secure.c
vendored
Normal file
@ -0,0 +1,700 @@
|
||||
/************************************************************************************
|
||||
Copyright (C) 2012 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
|
||||
|
||||
*************************************************************************************/
|
||||
unsigned int mariadb_deinitialize_ssl= 1;
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include <my_global.h>
|
||||
#include <my_sys.h>
|
||||
#include <ma_common.h>
|
||||
#include <ma_secure.h>
|
||||
#include <errmsg.h>
|
||||
#include <violite.h>
|
||||
#include <mysql_async.h>
|
||||
#include <my_context.h>
|
||||
#include <string.h>
|
||||
|
||||
static my_bool my_ssl_initialized= FALSE;
|
||||
static SSL_CTX *SSL_context= NULL;
|
||||
|
||||
#define MAX_SSL_ERR_LEN 100
|
||||
|
||||
extern pthread_mutex_t LOCK_ssl_config;
|
||||
static pthread_mutex_t *LOCK_crypto= NULL;
|
||||
|
||||
/*
|
||||
SSL error handling
|
||||
*/
|
||||
static void my_SSL_error(MYSQL *mysql)
|
||||
{
|
||||
ulong ssl_errno= ERR_get_error();
|
||||
char ssl_error[MAX_SSL_ERR_LEN];
|
||||
const char *ssl_error_reason;
|
||||
|
||||
DBUG_ENTER("my_SSL_error");
|
||||
|
||||
if (mysql_errno(mysql))
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
if (!ssl_errno)
|
||||
{
|
||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "Unknown SSL error");
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
if ((ssl_error_reason= ERR_reason_error_string(ssl_errno)))
|
||||
{
|
||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||
ER(CR_SSL_CONNECTION_ERROR), ssl_error_reason);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
my_snprintf(ssl_error, MAX_SSL_ERR_LEN, "SSL errno=%lu", ssl_errno, mysql->charset);
|
||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||
ER(CR_SSL_CONNECTION_ERROR), ssl_error);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*
|
||||
thread safe callbacks for OpenSSL
|
||||
Crypto call back functions will be
|
||||
set during ssl_initialization
|
||||
*/
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10000000)
|
||||
static unsigned long my_cb_threadid(void)
|
||||
{
|
||||
/* cast pthread_t to unsigned long */
|
||||
return (unsigned long) pthread_self();
|
||||
}
|
||||
#else
|
||||
static void my_cb_threadid(CRYPTO_THREADID *id)
|
||||
{
|
||||
CRYPTO_THREADID_set_numeric(id, (unsigned long)pthread_self());
|
||||
}
|
||||
#endif
|
||||
|
||||
static void my_cb_locking(int mode, int n, const char *file, int line)
|
||||
{
|
||||
if (mode & CRYPTO_LOCK)
|
||||
pthread_mutex_lock(&LOCK_crypto[n]);
|
||||
else
|
||||
pthread_mutex_unlock(&LOCK_crypto[n]);
|
||||
}
|
||||
|
||||
|
||||
static int ssl_crypto_init()
|
||||
{
|
||||
int i, rc= 1, max= CRYPTO_num_locks();
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10000000)
|
||||
CRYPTO_set_id_callback(my_cb_threadid);
|
||||
#else
|
||||
rc= CRYPTO_THREADID_set_callback(my_cb_threadid);
|
||||
#endif
|
||||
|
||||
/* if someone else already set callbacks
|
||||
* there is nothing do */
|
||||
if (!rc)
|
||||
return 0;
|
||||
|
||||
if (LOCK_crypto == NULL)
|
||||
{
|
||||
if (!(LOCK_crypto=
|
||||
(pthread_mutex_t *)my_malloc(sizeof(pthread_mutex_t) * max, MYF(0))))
|
||||
return 1;
|
||||
|
||||
for (i=0; i < max; i++)
|
||||
pthread_mutex_init(&LOCK_crypto[i], NULL);
|
||||
}
|
||||
|
||||
CRYPTO_set_locking_callback(my_cb_locking);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
Initializes SSL and allocate global
|
||||
context SSL_context
|
||||
|
||||
SYNOPSIS
|
||||
my_ssl_start
|
||||
mysql connection handle
|
||||
|
||||
RETURN VALUES
|
||||
0 success
|
||||
1 error
|
||||
*/
|
||||
int my_ssl_start(MYSQL *mysql)
|
||||
{
|
||||
int rc= 0;
|
||||
DBUG_ENTER("my_ssl_start");
|
||||
/* lock mutex to prevent multiple initialization */
|
||||
pthread_mutex_lock(&LOCK_ssl_config);
|
||||
if (!my_ssl_initialized)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000
|
||||
if (ssl_crypto_init())
|
||||
goto end;
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
|
||||
#else
|
||||
SSL_library_init();
|
||||
#if SSLEAY_VERSION_NUMBER >= 0x00907000L
|
||||
OPENSSL_config(NULL);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* load errors */
|
||||
SSL_load_error_strings();
|
||||
/* digests and ciphers */
|
||||
OpenSSL_add_all_algorithms();
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
if (!(SSL_context= SSL_CTX_new(TLS_client_method())))
|
||||
#else
|
||||
if (!(SSL_context= SSL_CTX_new(SSLv23_client_method())))
|
||||
#endif
|
||||
{
|
||||
my_SSL_error(mysql);
|
||||
rc= 1;
|
||||
goto end;
|
||||
}
|
||||
/* use server preferences instead of client preferences:
|
||||
client sends lowest tls version (=1.0) first, and will
|
||||
update to the version the server sent in client hellp
|
||||
response packet */
|
||||
SSL_CTX_set_options(SSL_context, SSL_OP_ALL);
|
||||
my_ssl_initialized= TRUE;
|
||||
}
|
||||
end:
|
||||
pthread_mutex_unlock(&LOCK_ssl_config);
|
||||
DBUG_RETURN(rc);
|
||||
}
|
||||
|
||||
/*
|
||||
Release SSL and free resources
|
||||
Will be automatically executed by
|
||||
mysql_server_end() function
|
||||
|
||||
SYNOPSIS
|
||||
my_ssl_end()
|
||||
void
|
||||
|
||||
RETURN VALUES
|
||||
void
|
||||
*/
|
||||
void my_ssl_end()
|
||||
{
|
||||
DBUG_ENTER("my_ssl_end");
|
||||
pthread_mutex_lock(&LOCK_ssl_config);
|
||||
if (my_ssl_initialized)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (LOCK_crypto)
|
||||
{
|
||||
CRYPTO_set_locking_callback(NULL);
|
||||
CRYPTO_set_id_callback(NULL);
|
||||
|
||||
for (i=0; i < CRYPTO_num_locks(); i++)
|
||||
pthread_mutex_destroy(&LOCK_crypto[i]);
|
||||
|
||||
my_free(LOCK_crypto);
|
||||
LOCK_crypto= NULL;
|
||||
}
|
||||
|
||||
if (SSL_context)
|
||||
{
|
||||
SSL_CTX_free(SSL_context);
|
||||
SSL_context= FALSE;
|
||||
}
|
||||
if (mariadb_deinitialize_ssl)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000
|
||||
ERR_remove_state(0);
|
||||
#endif
|
||||
EVP_cleanup();
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
ERR_free_strings();
|
||||
CONF_modules_free();
|
||||
CONF_modules_unload(1);
|
||||
}
|
||||
my_ssl_initialized= FALSE;
|
||||
}
|
||||
pthread_mutex_unlock(&LOCK_ssl_config);
|
||||
pthread_mutex_destroy(&LOCK_ssl_config);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*
|
||||
Set certification stuff.
|
||||
*/
|
||||
static int my_ssl_set_certs(MYSQL *mysql)
|
||||
{
|
||||
char *certfile= mysql->options.ssl_cert,
|
||||
*keyfile= mysql->options.ssl_key;
|
||||
|
||||
DBUG_ENTER("my_ssl_set_certs");
|
||||
|
||||
/* Make sure that ssl was allocated and
|
||||
ssl_system was initialized */
|
||||
DBUG_ASSERT(my_ssl_initialized == TRUE);
|
||||
|
||||
/* add cipher */
|
||||
if ((mysql->options.ssl_cipher &&
|
||||
mysql->options.ssl_cipher[0] != 0) &&
|
||||
SSL_CTX_set_cipher_list(SSL_context, mysql->options.ssl_cipher) == 0)
|
||||
goto error;
|
||||
|
||||
/* ca_file and ca_path */
|
||||
if (SSL_CTX_load_verify_locations(SSL_context,
|
||||
mysql->options.ssl_ca,
|
||||
mysql->options.ssl_capath) == 0)
|
||||
{
|
||||
if (mysql->options.ssl_ca || mysql->options.ssl_capath)
|
||||
goto error;
|
||||
if (SSL_CTX_set_default_verify_paths(SSL_context) == 0)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (keyfile && !certfile)
|
||||
certfile= keyfile;
|
||||
if (certfile && !keyfile)
|
||||
keyfile= certfile;
|
||||
|
||||
/* set cert */
|
||||
if (certfile && certfile[0] != 0)
|
||||
if (SSL_CTX_use_certificate_file(SSL_context, certfile, SSL_FILETYPE_PEM) != 1)
|
||||
goto error;
|
||||
|
||||
/* set key */
|
||||
if (keyfile && keyfile[0])
|
||||
{
|
||||
if (SSL_CTX_use_PrivateKey_file(SSL_context, keyfile, SSL_FILETYPE_PEM) != 1)
|
||||
goto error;
|
||||
}
|
||||
/* verify key */
|
||||
if (certfile && !SSL_CTX_check_private_key(SSL_context))
|
||||
goto error;
|
||||
|
||||
if (mysql->options.extension &&
|
||||
(mysql->options.extension->ssl_crl || mysql->options.extension->ssl_crlpath))
|
||||
{
|
||||
X509_STORE *certstore;
|
||||
|
||||
if ((certstore= SSL_CTX_get_cert_store(SSL_context)))
|
||||
{
|
||||
if (X509_STORE_load_locations(certstore, mysql->options.extension->ssl_crl,
|
||||
mysql->options.extension->ssl_crlpath) == 0 ||
|
||||
X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL) == 0)
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
DBUG_RETURN(0);
|
||||
|
||||
error:
|
||||
my_SSL_error(mysql);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
static unsigned int ma_get_cert_fingerprint(X509 *cert, EVP_MD *digest,
|
||||
unsigned char *fingerprint, unsigned int *fp_length)
|
||||
{
|
||||
if (*fp_length < EVP_MD_size(digest))
|
||||
return 0;
|
||||
if (!X509_digest(cert, digest, fingerprint, fp_length))
|
||||
return 0;
|
||||
return *fp_length;
|
||||
}
|
||||
|
||||
static my_bool ma_check_fingerprint(char *fp1, unsigned int fp1_len,
|
||||
char *fp2, unsigned int fp2_len)
|
||||
{
|
||||
/* SHA1 fingerprint (160 bit) / 8 * 2 + 1 */
|
||||
char hexstr[41];
|
||||
|
||||
fp1_len= (unsigned int)mysql_hex_string(hexstr, fp1, fp1_len);
|
||||
#ifdef _WIN32
|
||||
if (_strnicmp(hexstr, fp2, fp1_len) != 0)
|
||||
#else
|
||||
if (strncasecmp(hexstr, fp2, fp1_len) != 0)
|
||||
#endif
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
allocates a new ssl object
|
||||
|
||||
SYNOPSIS
|
||||
my_ssl_init
|
||||
mysql connection object
|
||||
|
||||
RETURN VALUES
|
||||
NULL on error
|
||||
SSL new SSL object
|
||||
*/
|
||||
SSL *my_ssl_init(MYSQL *mysql)
|
||||
{
|
||||
SSL *ssl= NULL;
|
||||
|
||||
DBUG_ENTER("my_ssl_init");
|
||||
|
||||
DBUG_ASSERT(mysql->net.vio->ssl == NULL);
|
||||
|
||||
if (!my_ssl_initialized)
|
||||
my_ssl_start(mysql);
|
||||
|
||||
pthread_mutex_lock(&LOCK_ssl_config);
|
||||
if (my_ssl_set_certs(mysql))
|
||||
goto error;
|
||||
|
||||
if (!(ssl= SSL_new(SSL_context)))
|
||||
goto error;
|
||||
|
||||
if (!SSL_set_app_data(ssl, mysql))
|
||||
goto error;
|
||||
|
||||
pthread_mutex_unlock(&LOCK_ssl_config);
|
||||
DBUG_RETURN(ssl);
|
||||
error:
|
||||
pthread_mutex_unlock(&LOCK_ssl_config);
|
||||
if (ssl)
|
||||
SSL_free(ssl);
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
establish SSL connection between client
|
||||
and server
|
||||
|
||||
SYNOPSIS
|
||||
my_ssl_connect
|
||||
ssl ssl object
|
||||
|
||||
RETURN VALUES
|
||||
0 success
|
||||
1 error
|
||||
*/
|
||||
int my_ssl_connect(SSL *ssl)
|
||||
{
|
||||
my_bool blocking;
|
||||
MYSQL *mysql;
|
||||
long rc;
|
||||
my_bool try_connect= 1;
|
||||
|
||||
DBUG_ENTER("my_ssl_connect");
|
||||
|
||||
DBUG_ASSERT(ssl != NULL);
|
||||
|
||||
mysql= (MYSQL *)SSL_get_app_data(ssl);
|
||||
CLEAR_CLIENT_ERROR(mysql);
|
||||
|
||||
/* Set socket to non blocking */
|
||||
if (!(blocking= vio_is_blocking(mysql->net.vio)))
|
||||
vio_blocking(mysql->net.vio, FALSE, 0);
|
||||
|
||||
SSL_clear(ssl);
|
||||
SSL_SESSION_set_timeout(SSL_get_session(ssl),
|
||||
mysql->options.connect_timeout);
|
||||
SSL_set_fd(ssl, mysql->net.vio->sd);
|
||||
|
||||
while (try_connect && (rc= SSL_connect(ssl)) == -1)
|
||||
{
|
||||
switch(SSL_get_error(ssl, rc)) {
|
||||
case SSL_ERROR_WANT_READ:
|
||||
if (vio_wait_or_timeout(mysql->net.vio, TRUE, mysql->options.connect_timeout) < 1)
|
||||
try_connect= 0;
|
||||
break;
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
if (vio_wait_or_timeout(mysql->net.vio, TRUE, mysql->options.connect_timeout) < 1)
|
||||
try_connect= 0;
|
||||
break;
|
||||
default:
|
||||
try_connect= 0;
|
||||
}
|
||||
}
|
||||
if (rc != 1)
|
||||
{
|
||||
my_SSL_error(mysql);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
if ((mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT))
|
||||
{
|
||||
rc= SSL_get_verify_result(ssl);
|
||||
if (rc != X509_V_OK)
|
||||
{
|
||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||
ER(CR_SSL_CONNECTION_ERROR), X509_verify_cert_error_string(rc));
|
||||
/* restore blocking mode */
|
||||
if (!blocking)
|
||||
vio_blocking(mysql->net.vio, FALSE, 0);
|
||||
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
|
||||
vio_reset(mysql->net.vio, VIO_TYPE_SSL, mysql->net.vio->sd, 0, 0);
|
||||
mysql->net.vio->ssl= ssl;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
int ma_ssl_verify_fingerprint(SSL *ssl)
|
||||
{
|
||||
X509 *cert= SSL_get_peer_certificate(ssl);
|
||||
MYSQL *mysql= (MYSQL *)SSL_get_app_data(ssl);
|
||||
unsigned char fingerprint[EVP_MAX_MD_SIZE];
|
||||
EVP_MD *digest;
|
||||
unsigned int fp_length;
|
||||
|
||||
DBUG_ENTER("ma_ssl_verify_fingerprint");
|
||||
|
||||
if (!cert)
|
||||
{
|
||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||
ER(CR_SSL_CONNECTION_ERROR),
|
||||
"Unable to get server certificate");
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
digest= (EVP_MD *)EVP_sha1();
|
||||
fp_length= sizeof(fingerprint);
|
||||
|
||||
if (!ma_get_cert_fingerprint(cert, digest, fingerprint, &fp_length))
|
||||
{
|
||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||
ER(CR_SSL_CONNECTION_ERROR),
|
||||
"Unable to get finger print of server certificate");
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
/* single finger print was specified */
|
||||
if (mysql->options.extension->ssl_fp)
|
||||
{
|
||||
if (ma_check_fingerprint(fingerprint, fp_length, mysql->options.extension->ssl_fp,
|
||||
strlen(mysql->options.extension->ssl_fp)))
|
||||
{
|
||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||
ER(CR_SSL_CONNECTION_ERROR),
|
||||
"invalid finger print of server certificate");
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* white list of finger prints was specified */
|
||||
if (mysql->options.extension->ssl_fp_list)
|
||||
{
|
||||
FILE *fp;
|
||||
char buff[255];
|
||||
|
||||
if (!(fp = my_fopen(mysql->options.extension->ssl_fp_list ,O_RDONLY, MYF(0))))
|
||||
{
|
||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||
ER(CR_SSL_CONNECTION_ERROR),
|
||||
"Can't open finger print list");
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
while (fgets(buff, sizeof(buff)-1, fp))
|
||||
{
|
||||
/* remove trailing new line character */
|
||||
char *pos= strchr(buff, '\r');
|
||||
if (!pos)
|
||||
pos= strchr(buff, '\n');
|
||||
if (pos)
|
||||
*pos= '\0';
|
||||
|
||||
if (!ma_check_fingerprint(fingerprint, fp_length, buff, strlen(buff)))
|
||||
{
|
||||
/* finger print is valid: close file and exit */
|
||||
my_fclose(fp, MYF(0));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* No finger print matched - close file and return error */
|
||||
my_fclose(fp, MYF(0));
|
||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||
ER(CR_SSL_CONNECTION_ERROR),
|
||||
"invalid finger print of server certificate");
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/*
|
||||
verify server certificate
|
||||
|
||||
SYNOPSIS
|
||||
my_ssl_verify_server_cert()
|
||||
MYSQL mysql
|
||||
mybool verify_server_cert;
|
||||
|
||||
RETURN VALUES
|
||||
1 Error
|
||||
0 OK
|
||||
*/
|
||||
|
||||
int my_ssl_verify_server_cert(SSL *ssl)
|
||||
{
|
||||
X509 *cert;
|
||||
MYSQL *mysql;
|
||||
X509_NAME *x509sn;
|
||||
int cn_pos;
|
||||
X509_NAME_ENTRY *cn_entry;
|
||||
ASN1_STRING *cn_asn1;
|
||||
const char *cn_str;
|
||||
|
||||
DBUG_ENTER("my_ssl_verify_server_cert");
|
||||
|
||||
mysql= (MYSQL *)SSL_get_app_data(ssl);
|
||||
|
||||
if (!mysql->host)
|
||||
{
|
||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||
ER(CR_SSL_CONNECTION_ERROR),
|
||||
"Invalid (empty) hostname");
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
if (!(cert= SSL_get_peer_certificate(ssl)))
|
||||
{
|
||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||
ER(CR_SSL_CONNECTION_ERROR),
|
||||
"Unable to get server certificate");
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
x509sn= X509_get_subject_name(cert);
|
||||
|
||||
if ((cn_pos= X509_NAME_get_index_by_NID(x509sn, NID_commonName, -1)) < 0)
|
||||
goto error;
|
||||
|
||||
if (!(cn_entry= X509_NAME_get_entry(x509sn, cn_pos)))
|
||||
goto error;
|
||||
|
||||
if (!(cn_asn1 = X509_NAME_ENTRY_get_data(cn_entry)))
|
||||
goto error;
|
||||
|
||||
cn_str = (char *)ASN1_STRING_data(cn_asn1);
|
||||
|
||||
/* Make sure there is no embedded \0 in the CN */
|
||||
if ((size_t)ASN1_STRING_length(cn_asn1) != strlen(cn_str))
|
||||
goto error;
|
||||
|
||||
if (strcmp(cn_str, mysql->host))
|
||||
goto error;
|
||||
|
||||
X509_free(cert);
|
||||
|
||||
DBUG_RETURN(0);
|
||||
|
||||
error:
|
||||
X509_free(cert);
|
||||
|
||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||
ER(CR_SSL_CONNECTION_ERROR),
|
||||
"Validation of SSL server certificate failed");
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
/*
|
||||
write to ssl socket
|
||||
|
||||
SYNOPSIS
|
||||
my_ssl_write()
|
||||
vio vio
|
||||
buf write buffer
|
||||
size size of buffer
|
||||
|
||||
RETURN VALUES
|
||||
bytes written
|
||||
*/
|
||||
size_t my_ssl_write(Vio *vio, const uchar* buf, size_t size)
|
||||
{
|
||||
size_t written;
|
||||
DBUG_ENTER("my_ssl_write");
|
||||
if (vio->async_context && vio->async_context->active)
|
||||
written= my_ssl_write_async(vio->async_context, (SSL *)vio->ssl, buf,
|
||||
size);
|
||||
else
|
||||
written= SSL_write((SSL*) vio->ssl, buf, size);
|
||||
DBUG_RETURN(written);
|
||||
}
|
||||
|
||||
/*
|
||||
read from ssl socket
|
||||
|
||||
SYNOPSIS
|
||||
my_ssl_read()
|
||||
vio vio
|
||||
buf read buffer
|
||||
size_t max number of bytes to read
|
||||
|
||||
RETURN VALUES
|
||||
number of bytes read
|
||||
*/
|
||||
size_t my_ssl_read(Vio *vio, uchar* buf, size_t size)
|
||||
{
|
||||
size_t read;
|
||||
DBUG_ENTER("my_ssl_read");
|
||||
|
||||
if (vio->async_context && vio->async_context->active)
|
||||
read= my_ssl_read_async(vio->async_context, (SSL *)vio->ssl, buf, size);
|
||||
else
|
||||
read= SSL_read((SSL*) vio->ssl, buf, size);
|
||||
DBUG_RETURN(read);
|
||||
}
|
||||
|
||||
/*
|
||||
close ssl connection and free
|
||||
ssl object
|
||||
|
||||
SYNOPSIS
|
||||
my_ssl_close()
|
||||
vio vio
|
||||
|
||||
RETURN VALUES
|
||||
1 ok
|
||||
0 or -1 on error
|
||||
*/
|
||||
int my_ssl_close(Vio *vio)
|
||||
{
|
||||
int i, rc;
|
||||
DBUG_ENTER("my_ssl_close");
|
||||
|
||||
if (!vio || !vio->ssl)
|
||||
DBUG_RETURN(1);
|
||||
|
||||
SSL_set_quiet_shutdown(vio->ssl, 1);
|
||||
/* 2 x pending + 2 * data = 4 */
|
||||
for (i=0; i < 4; i++)
|
||||
if ((rc= SSL_shutdown(vio->ssl)))
|
||||
break;
|
||||
|
||||
SSL_free(vio->ssl);
|
||||
vio->ssl= NULL;
|
||||
|
||||
DBUG_RETURN(rc);
|
||||
}
|
||||
|
||||
#endif /* HAVE_OPENSSL */
|
65
module/Vendor/MDBC/libmariadb/ma_time.c
vendored
Normal file
65
module/Vendor/MDBC/libmariadb/ma_time.c
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
/****************************************************************************
|
||||
Copyright (C) 2013 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
|
||||
*****************************************************************************/
|
||||
#include "mysys_priv.h"
|
||||
#include <my_global.h>
|
||||
#include <mysql.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
size_t mariadb_time_to_string(const MYSQL_TIME *tm, char *time_str, size_t len,
|
||||
unsigned int digits)
|
||||
{
|
||||
size_t length;
|
||||
|
||||
if (!time_str || !len)
|
||||
return 0;
|
||||
|
||||
if (digits == AUTO_SEC_PART_DIGITS)
|
||||
digits= MIN((tm->second_part) ? SEC_PART_DIGITS : 0, 15);
|
||||
|
||||
switch(tm->time_type) {
|
||||
case MYSQL_TIMESTAMP_DATE:
|
||||
length= snprintf(time_str, len, "%04u-%02u-%02u", tm->year, tm->month, tm->day);
|
||||
digits= 0;
|
||||
break;
|
||||
case MYSQL_TIMESTAMP_DATETIME:
|
||||
length= snprintf(time_str, len, "%04u-%02u-%02u %02u:%02u:%02u",
|
||||
tm->year, tm->month, tm->day, tm->hour, tm->minute, tm->second);
|
||||
break;
|
||||
case MYSQL_TIMESTAMP_TIME:
|
||||
length= snprintf(time_str, len, "%s%02u:%02u:%02u",
|
||||
(tm->neg ? "-" : ""), tm->hour, tm->minute, tm->second);
|
||||
break;
|
||||
default:
|
||||
time_str[0]= '\0';
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
if (digits && (len < length))
|
||||
{
|
||||
char helper[16];
|
||||
snprintf(helper, 16, ".%%0%du", digits);
|
||||
length+= snprintf(time_str + length, len - length, helper, digits);
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
100
module/Vendor/MDBC/libmariadb/mf_dirname.c
vendored
Normal file
100
module/Vendor/MDBC/libmariadb/mf_dirname.c
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include <m_string.h>
|
||||
|
||||
/* Functions definied in this file */
|
||||
|
||||
uint dirname_length(const char *name)
|
||||
{
|
||||
register my_string pos,gpos;
|
||||
#ifdef FN_DEVCHAR
|
||||
if ((pos=(char*)strrchr(name,FN_DEVCHAR)) == 0)
|
||||
#endif
|
||||
pos=(char*) name-1;
|
||||
|
||||
gpos= pos++;
|
||||
for ( ; *pos ; pos++) /* Find last FN_LIBCHAR */
|
||||
if (*pos == FN_LIBCHAR || *pos == '/'
|
||||
#ifdef FN_C_AFTER_DIR
|
||||
|| *pos == FN_C_AFTER_DIR || *pos == FN_C_AFTER_DIR_2
|
||||
#endif
|
||||
)
|
||||
gpos=pos;
|
||||
return ((uint) (uint) (gpos+1-(char*) name));
|
||||
}
|
||||
|
||||
|
||||
/* Gives directory part of filename. Directory ends with '/' */
|
||||
/* Returns length of directory part */
|
||||
|
||||
uint dirname_part(my_string to, const char *name)
|
||||
{
|
||||
uint length;
|
||||
DBUG_ENTER("dirname_part");
|
||||
DBUG_PRINT("enter",("'%s'",name));
|
||||
|
||||
length=dirname_length(name);
|
||||
(void) strmake(to,(char*) name,min(length,FN_REFLEN-2));
|
||||
convert_dirname(to); /* Convert chars */
|
||||
DBUG_RETURN(length);
|
||||
} /* dirname */
|
||||
|
||||
|
||||
/* convert dirname to use under this system */
|
||||
/* If MSDOS converts '/' to '\' */
|
||||
/* If VMS converts '<' to '[' and '>' to ']' */
|
||||
/* Adds a '/' to end if there isn't one and the last isn't a dev_char */
|
||||
/* ARGSUSED */
|
||||
|
||||
#ifndef FN_DEVCHAR
|
||||
#define FN_DEVCHAR '\0' /* For easier code */
|
||||
#endif
|
||||
|
||||
char *convert_dirname(my_string to)
|
||||
{
|
||||
reg1 char *pos;
|
||||
#if FN_LIBCHAR != '/'
|
||||
{
|
||||
pos=to-1; /* Change from '/' */
|
||||
while ((pos=strchr(pos+1,'/')) != 0)
|
||||
*pos=FN_LIBCHAR;
|
||||
}
|
||||
#endif
|
||||
#ifdef FN_C_BEFORE_DIR_2
|
||||
{
|
||||
for (pos=to ; *pos ; pos++)
|
||||
{
|
||||
if (*pos == FN_C_BEFORE_DIR_2)
|
||||
*pos=FN_C_BEFORE_DIR;
|
||||
if (*pos == FN_C_AFTER_DIR_2)
|
||||
*pos=FN_C_AFTER_DIR;
|
||||
}
|
||||
}
|
||||
#else
|
||||
{ /* Append FN_LIBCHAR if not there */
|
||||
pos=strend(to);
|
||||
if (pos != to && (pos[-1] != FN_LIBCHAR && pos[-1] != FN_DEVCHAR))
|
||||
{
|
||||
*pos++=FN_LIBCHAR;
|
||||
*pos=0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return pos; /* Pointer to end of dir */
|
||||
} /* convert_dirname */
|
46
module/Vendor/MDBC/libmariadb/mf_fn_ext.c
vendored
Normal file
46
module/Vendor/MDBC/libmariadb/mf_fn_ext.c
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* Returnerar en pekare till filnamnets extension. */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include <m_string.h>
|
||||
|
||||
/* Return a pointerto the extension of the filename
|
||||
The pointer points at the extension character (normally '.'))
|
||||
If there isn't any extension, the pointer points at the end
|
||||
NULL of the filename
|
||||
*/
|
||||
|
||||
my_string fn_ext(const char *name)
|
||||
{
|
||||
register my_string pos,gpos;
|
||||
DBUG_ENTER("fn_ext");
|
||||
DBUG_PRINT("mfunkt",("name: '%s'",name));
|
||||
|
||||
#if defined(FN_DEVCHAR) || defined(FN_C_AFTER_DIR)
|
||||
{
|
||||
char buff[FN_REFLEN];
|
||||
gpos=(my_string) name+dirname_part(buff,(char*) name);
|
||||
}
|
||||
#else
|
||||
if (!(gpos=strrchr(name,FNLIBCHAR)))
|
||||
gpos=name;
|
||||
#endif
|
||||
pos=strrchr(gpos,FN_EXTCHAR);
|
||||
DBUG_RETURN (pos ? pos : strend(gpos));
|
||||
} /* fn_ext */
|
156
module/Vendor/MDBC/libmariadb/mf_format.c
vendored
Normal file
156
module/Vendor/MDBC/libmariadb/mf_format.c
vendored
Normal file
@ -0,0 +1,156 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include <m_string.h>
|
||||
#ifdef HAVE_REALPATH
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
/* format a filename with replace of library and extension */
|
||||
/* params to and name may be identicall */
|
||||
/* function doesn't change name if name != to */
|
||||
/* Flag may be: 1 replace filenames library with 'dsk' */
|
||||
/* 2 replace extension with 'form' */
|
||||
/* 4 Unpack filename (replace ~ with home) */
|
||||
/* 8 Pack filename as short as possibly */
|
||||
/* 16 Resolve symbolic links for filename */
|
||||
/* 32 Resolve filename to full path */
|
||||
/* 64 Return NULL if too long path */
|
||||
|
||||
#ifdef SCO
|
||||
#define BUFF_LEN 4097
|
||||
#else
|
||||
#ifdef MAXPATHLEN
|
||||
#define BUFF_LEN MAXPATHLEN
|
||||
#else
|
||||
#define BUFF_LEN FN_LEN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
my_string fn_format(my_string to, const char *name, const char *dsk,
|
||||
const char *form, int flag)
|
||||
{
|
||||
reg1 uint length;
|
||||
char dev[FN_REFLEN], buff[BUFF_LEN], *pos, *startpos;
|
||||
const char *ext;
|
||||
DBUG_ENTER("fn_format");
|
||||
DBUG_PRINT("enter",("name: %s dsk: %s form: %s flag: %d",
|
||||
name,dsk,form,flag));
|
||||
|
||||
/* Kopiera & skippa enheten */
|
||||
name+=(length=dirname_part(dev,(startpos=(my_string) name)));
|
||||
if (length == 0 || flag & 1)
|
||||
{
|
||||
(void) strmake(dev,dsk, sizeof(dev) - 2);
|
||||
/* Use given directory */
|
||||
convert_dirname(dev); /* Fix to this OS */
|
||||
}
|
||||
if (flag & 8)
|
||||
pack_dirname(dev,dev); /* Put in ./.. and ~/.. */
|
||||
if (flag & 4)
|
||||
(void) unpack_dirname(dev,dev); /* Replace ~/.. with dir */
|
||||
if ((pos=(char*)strchr(name,FN_EXTCHAR)) != NullS)
|
||||
{
|
||||
if ((flag & 2) == 0) /* Skall vi byta extension ? */
|
||||
{
|
||||
length=strlength(name); /* Old extension */
|
||||
ext = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
length=(uint) (pos-(char*) name); /* Change extension */
|
||||
ext= form;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
length=strlength(name); /* Har ingen ext- tag nya */
|
||||
ext=form;
|
||||
}
|
||||
|
||||
if (strlen(dev)+length+strlen(ext) >= FN_REFLEN || length >= FN_LEN )
|
||||
{ /* To long path, return original */
|
||||
uint tmp_length;
|
||||
if (flag & 64)
|
||||
return 0;
|
||||
tmp_length=strlength(startpos);
|
||||
DBUG_PRINT("error",("dev: '%s' ext: '%s' length: %d",dev,ext,length));
|
||||
(void) strmake(to,startpos,min(tmp_length,FN_REFLEN-1));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (to == startpos)
|
||||
{
|
||||
bmove(buff,(char*) name,length); /* Save name for last copy */
|
||||
name=buff;
|
||||
}
|
||||
pos=strmake(strmov(to,dev),name,length);
|
||||
#ifdef FN_UPPER_CASE
|
||||
caseup_str(to);
|
||||
#endif
|
||||
#ifdef FN_LOWER_CASE
|
||||
casedn_str(to);
|
||||
#endif
|
||||
(void) strmov(pos,ext); /* Don't convert extension */
|
||||
}
|
||||
/* Purify gives a lot of UMR errors when using realpath */
|
||||
#if defined(HAVE_REALPATH) && !defined(HAVE_purify) && !defined(HAVE_BROKEN_REALPATH)
|
||||
if (flag & 16)
|
||||
{
|
||||
struct stat stat_buff;
|
||||
if (flag & 32 || (!lstat(to,&stat_buff) && S_ISLNK(stat_buff.st_mode)))
|
||||
{
|
||||
if (realpath(to,buff))
|
||||
strmake(to,buff,FN_REFLEN-1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
DBUG_RETURN (to);
|
||||
} /* fn_format */
|
||||
|
||||
|
||||
/*
|
||||
strlength(const string str)
|
||||
Return length of string with end-space:s not counted.
|
||||
*/
|
||||
|
||||
size_s strlength(const char *str)
|
||||
{
|
||||
reg1 my_string pos;
|
||||
reg2 my_string found;
|
||||
DBUG_ENTER("strlength");
|
||||
|
||||
pos=found=(char*) str;
|
||||
|
||||
while (*pos)
|
||||
{
|
||||
if (*pos != ' ')
|
||||
{
|
||||
while (*++pos && *pos != ' ') {};
|
||||
if (!*pos)
|
||||
{
|
||||
found=pos; /* String ends here */
|
||||
break;
|
||||
}
|
||||
}
|
||||
found=pos;
|
||||
while (*++pos == ' ') {};
|
||||
}
|
||||
DBUG_RETURN((size_s) (found-(char*) str));
|
||||
} /* strlength */
|
54
module/Vendor/MDBC/libmariadb/mf_loadpath.c
vendored
Normal file
54
module/Vendor/MDBC/libmariadb/mf_loadpath.c
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include <m_string.h>
|
||||
|
||||
/* Returns full load-path for a file. to may be = path */
|
||||
/* if path is a hard-path return path */
|
||||
/* if path starts with home-dir return path */
|
||||
/* if path starts with current dir or parent-dir unpack path */
|
||||
/* if there is no path, prepend with own_path_prefix if given */
|
||||
/* else unpack path according to current dir */
|
||||
|
||||
my_string my_load_path(my_string to, const char *path,
|
||||
const char *own_path_prefix)
|
||||
{
|
||||
char buff[FN_REFLEN];
|
||||
DBUG_ENTER("my_load_path");
|
||||
DBUG_PRINT("enter",("path: %s prefix: %s",path,
|
||||
own_path_prefix ? own_path_prefix : ""));
|
||||
|
||||
if ((path[0] == FN_HOMELIB && path[1] == FN_LIBCHAR) ||
|
||||
test_if_hard_path(path))
|
||||
VOID(strmov(buff,path));
|
||||
else if ((path[0] == FN_CURLIB && path[1] == FN_LIBCHAR) ||
|
||||
(is_prefix((gptr) path,FN_PARENTDIR) &&
|
||||
path[strlen(FN_PARENTDIR)] == FN_LIBCHAR) ||
|
||||
! own_path_prefix)
|
||||
{
|
||||
if (! my_getwd(buff,(uint) (FN_REFLEN-strlen(path)),MYF(0)))
|
||||
VOID(strcat(buff,path));
|
||||
else
|
||||
VOID(strmov(buff,path));
|
||||
}
|
||||
else
|
||||
VOID(strxmov(buff,own_path_prefix,path,NullS));
|
||||
strmov(to,buff);
|
||||
DBUG_PRINT("exit",("to: %s",to));
|
||||
DBUG_RETURN(to);
|
||||
} /* my_load_path */
|
532
module/Vendor/MDBC/libmariadb/mf_pack.c
vendored
Normal file
532
module/Vendor/MDBC/libmariadb/mf_pack.c
vendored
Normal file
@ -0,0 +1,532 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include <m_string.h>
|
||||
#ifdef HAVE_PWD_H
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
#ifdef VMS
|
||||
#include <rms.h>
|
||||
#include <iodef.h>
|
||||
#include <descrip.h>
|
||||
#endif /* VMS */
|
||||
|
||||
static my_string NEAR_F expand_tilde(my_string *path);
|
||||
|
||||
/* Pack a dirname ; Changes HOME to ~/ and current dev to ./ */
|
||||
/* from is a dirname (from dirname() ?) ending with FN_LIBCHAR */
|
||||
/* to may be == from */
|
||||
|
||||
void pack_dirname(my_string to, const char *from)
|
||||
{
|
||||
int cwd_err;
|
||||
uint d_length,length,buff_length= 0;
|
||||
my_string start;
|
||||
char buff[FN_REFLEN];
|
||||
DBUG_ENTER("pack_dirname");
|
||||
|
||||
(void) intern_filename(to,from); /* Change to intern name */
|
||||
|
||||
#ifdef FN_DEVCHAR
|
||||
if ((start=strrchr(to,FN_DEVCHAR)) != 0) /* Skipp device part */
|
||||
start++;
|
||||
else
|
||||
#endif
|
||||
start=to;
|
||||
|
||||
LINT_INIT(buff_length);
|
||||
if (!(cwd_err= my_getwd(buff,FN_REFLEN,MYF(0))))
|
||||
{
|
||||
buff_length= (uint) strlen(buff);
|
||||
d_length=(uint) (start-to);
|
||||
if ((start == to ||
|
||||
(buff_length == d_length && !bcmp(buff,start,d_length))) &&
|
||||
*start != FN_LIBCHAR && *start)
|
||||
{ /* Put current dir before */
|
||||
bchange(to,d_length,buff,buff_length,(uint) strlen(to)+1);
|
||||
}
|
||||
}
|
||||
|
||||
if ((d_length= cleanup_dirname(to,to)) != 0)
|
||||
{
|
||||
length=0;
|
||||
if (home_dir)
|
||||
{
|
||||
length= (uint) strlen(home_dir);
|
||||
if (home_dir[length-1] == FN_LIBCHAR)
|
||||
length--; /* Don't test last '/' */
|
||||
}
|
||||
if (length > 1 && length < d_length)
|
||||
{ /* test if /xx/yy -> ~/yy */
|
||||
if (bcmp(to,home_dir,length) == 0 && to[length] == FN_LIBCHAR)
|
||||
{
|
||||
to[0]=FN_HOMELIB; /* Filename begins with ~ */
|
||||
(void) strmov_overlapp(to+1,to+length);
|
||||
}
|
||||
}
|
||||
if (! cwd_err)
|
||||
{ /* Test if cwd is ~/... */
|
||||
if (length > 1 && length < buff_length)
|
||||
{
|
||||
if (bcmp(buff,home_dir,length) == 0 && buff[length] == FN_LIBCHAR)
|
||||
{
|
||||
buff[0]=FN_HOMELIB;
|
||||
(void) strmov_overlapp(buff+1,buff+length);
|
||||
}
|
||||
}
|
||||
if (is_prefix(to,buff))
|
||||
{
|
||||
length= (uint) strlen(buff);
|
||||
if (to[length])
|
||||
(void) strmov_overlapp(to,to+length); /* Remove everything before */
|
||||
else
|
||||
{
|
||||
to[0]= FN_CURLIB; /* Put ./ instead of cwd */
|
||||
to[1]= FN_LIBCHAR;
|
||||
to[2]= '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DBUG_PRINT("exit",("to: '%s'",to));
|
||||
DBUG_VOID_RETURN;
|
||||
} /* pack_dirname */
|
||||
|
||||
|
||||
/* remove unwanted chars from dirname */
|
||||
/* if "/../" removes prev dir; "/~/" removes all before ~ */
|
||||
/* "//" is same as "/", except on Win32 at start of a file */
|
||||
/* "/./" is removed */
|
||||
/* Unpacks home_dir if "~/.." used */
|
||||
/* Unpacks current dir if if "./.." used */
|
||||
|
||||
uint cleanup_dirname(register my_string to, const char *from)
|
||||
/* to may be == from */
|
||||
|
||||
{
|
||||
reg5 uint length;
|
||||
reg2 my_string pos;
|
||||
reg3 my_string from_ptr;
|
||||
reg4 my_string start;
|
||||
char parent[5], /* for "FN_PARENTDIR" */
|
||||
buff[FN_REFLEN+1],*end_parentdir;
|
||||
DBUG_ENTER("cleanup_dirname");
|
||||
DBUG_PRINT("enter",("from: '%s'",from));
|
||||
|
||||
start=buff;
|
||||
from_ptr=(my_string) from;
|
||||
#ifdef FN_DEVCHAR
|
||||
if ((pos=strrchr(from_ptr,FN_DEVCHAR)) != 0)
|
||||
{ /* Skipp device part */
|
||||
length=(uint) (pos-from_ptr)+1;
|
||||
start=strnmov(buff,from_ptr,length); from_ptr+=length;
|
||||
}
|
||||
#endif
|
||||
|
||||
parent[0]=FN_LIBCHAR;
|
||||
length=(uint) (strmov(parent+1,FN_PARENTDIR)-parent);
|
||||
for (pos=start ; (*pos= *from_ptr++) != 0 ; pos++)
|
||||
{
|
||||
if (*pos == '/')
|
||||
*pos = FN_LIBCHAR;
|
||||
if (*pos == FN_LIBCHAR)
|
||||
{
|
||||
if ((uint) (pos-start) > length && bcmp(pos-length,parent,length) == 0)
|
||||
{ /* If .../../; skipp prev */
|
||||
pos-=length;
|
||||
if (pos != start)
|
||||
{ /* not /../ */
|
||||
pos--;
|
||||
if (*pos == FN_HOMELIB && (pos == start || pos[-1] == FN_LIBCHAR))
|
||||
{
|
||||
if (!home_dir)
|
||||
{
|
||||
pos+=length+1; /* Don't unpack ~/.. */
|
||||
continue;
|
||||
}
|
||||
pos=strmov(buff,home_dir)-1; /* Unpacks ~/.. */
|
||||
if (*pos == FN_LIBCHAR)
|
||||
pos--; /* home ended with '/' */
|
||||
}
|
||||
if (*pos == FN_CURLIB && (pos == start || pos[-1] == FN_LIBCHAR))
|
||||
{
|
||||
if (my_getwd(curr_dir,FN_REFLEN,MYF(0)))
|
||||
{
|
||||
pos+=length+1; /* Don't unpack ./.. */
|
||||
continue;
|
||||
}
|
||||
pos=strmov(buff,curr_dir)-1; /* Unpacks ./.. */
|
||||
if (*pos == FN_LIBCHAR)
|
||||
pos--; /* home ended with '/' */
|
||||
}
|
||||
end_parentdir=pos;
|
||||
while (pos >= start && *pos != FN_LIBCHAR) /* remove prev dir */
|
||||
pos--;
|
||||
if (pos[1] == FN_HOMELIB || bcmp(pos,parent,length) == 0)
|
||||
{ /* Don't remove ~user/ */
|
||||
pos=strmov(end_parentdir+1,parent);
|
||||
*pos=FN_LIBCHAR;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((uint) (pos-start) == length-1 &&
|
||||
!bcmp(start,parent+1,length-1))
|
||||
start=pos; /* Starts with "../" */
|
||||
else if (pos-start > 0 && pos[-1] == FN_LIBCHAR)
|
||||
{
|
||||
#ifdef FN_NETWORK_DRIVES
|
||||
if (pos-start != 1)
|
||||
#endif
|
||||
pos--; /* Remove dupplicate '/' */
|
||||
}
|
||||
else if (pos-start > 1 && pos[-1] == FN_CURLIB && pos[-2] == FN_LIBCHAR)
|
||||
pos-=2; /* Skipp /./ */
|
||||
else if (pos > buff+1 && pos[-1] == FN_HOMELIB && pos[-2] == FN_LIBCHAR)
|
||||
{ /* Found ..../~/ */
|
||||
buff[0]=FN_HOMELIB;
|
||||
buff[1]=FN_LIBCHAR;
|
||||
start=buff; pos=buff+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
(void) strmov(to,buff);
|
||||
DBUG_PRINT("exit",("to: '%s'",to));
|
||||
DBUG_RETURN((uint) (pos-buff));
|
||||
} /* cleanup_dirname */
|
||||
|
||||
|
||||
/*
|
||||
On system where you don't have symbolic links, the following
|
||||
code will allow you to create a file:
|
||||
directory-name.lnk that should contain the real path
|
||||
to the directory. This will be used if the directory name
|
||||
doesn't exists
|
||||
*/
|
||||
|
||||
|
||||
my_bool my_use_symdir=0; /* Set this if you want to use symdirs */
|
||||
|
||||
#ifdef USE_SYMDIR
|
||||
void symdirget(char *dir)
|
||||
{
|
||||
char buff[FN_REFLEN];
|
||||
char *pos=strend(dir);
|
||||
if (dir[0] && pos[-1] != FN_DEVCHAR && access(dir, F_OK))
|
||||
{
|
||||
FILE *fp;
|
||||
char temp= *(--pos); /* May be "/" or "\" */
|
||||
strmov(pos,".sym");
|
||||
fp = my_fopen(dir, O_RDONLY,MYF(0));
|
||||
*pos++=temp; *pos=0; /* Restore old filename */
|
||||
if (fp)
|
||||
{
|
||||
if (fgets(buff, sizeof(buff)-1, fp))
|
||||
{
|
||||
for (pos=strend(buff);
|
||||
pos > buff && (iscntrl(pos[-1]) || isspace(pos[-1])) ;
|
||||
pos --);
|
||||
|
||||
/* Ensure that the symlink ends with the directory symbol */
|
||||
if (pos == buff || pos[-1] != FN_LIBCHAR)
|
||||
*pos++=FN_LIBCHAR;
|
||||
|
||||
strmake(dir,buff, (uint) (pos-buff));
|
||||
}
|
||||
my_fclose(fp,MYF(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* USE_SYMDIR */
|
||||
|
||||
/* Unpacks dirname to name that can be used by open... */
|
||||
/* Make that last char of to is '/' if from not empty and
|
||||
from doesn't end in FN_DEVCHAR */
|
||||
/* Uses cleanup_dirname and changes ~/.. to home_dir/.. */
|
||||
/* Returns length of new directory */
|
||||
|
||||
uint unpack_dirname(my_string to, const char *from)
|
||||
|
||||
/* to may be == from */
|
||||
{
|
||||
uint length,h_length;
|
||||
char buff[FN_REFLEN+1+4],*suffix,*tilde_expansion;
|
||||
DBUG_ENTER("unpack_dirname");
|
||||
|
||||
(void) intern_filename(buff,from); /* Change to intern name */
|
||||
length= (uint) strlen(buff); /* Fix that '/' is last */
|
||||
if (length &&
|
||||
#ifdef FN_DEVCHAR
|
||||
buff[length-1] != FN_DEVCHAR &&
|
||||
#endif
|
||||
buff[length-1] != FN_LIBCHAR && buff[length-1] != '/')
|
||||
{
|
||||
buff[length]=FN_LIBCHAR;
|
||||
buff[length+1]= '\0';
|
||||
}
|
||||
|
||||
length=cleanup_dirname(buff,buff);
|
||||
if (buff[0] == FN_HOMELIB)
|
||||
{
|
||||
suffix=buff+1; tilde_expansion=expand_tilde(&suffix);
|
||||
if (tilde_expansion)
|
||||
{
|
||||
length-=(uint) (suffix-buff)-1;
|
||||
if (length+(h_length= (uint) strlen(tilde_expansion)) <= FN_REFLEN)
|
||||
{
|
||||
if (tilde_expansion[h_length-1] == FN_LIBCHAR)
|
||||
h_length--;
|
||||
if (buff+h_length < suffix)
|
||||
bmove(buff+h_length,suffix,length);
|
||||
else
|
||||
bmove_upp(buff+h_length+length,suffix+length,length);
|
||||
bmove(buff,tilde_expansion,h_length);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef USE_SYMDIR
|
||||
if (my_use_symdir)
|
||||
symdirget(buff);
|
||||
#endif
|
||||
DBUG_RETURN(system_filename(to,buff)); /* Fix for open */
|
||||
} /* unpack_dirname */
|
||||
|
||||
|
||||
/* Expand tilde to home or user-directory */
|
||||
/* Path is reset to point at FN_LIBCHAR after ~xxx */
|
||||
|
||||
static my_string NEAR_F expand_tilde(my_string *path)
|
||||
{
|
||||
if (path[0][0] == FN_LIBCHAR)
|
||||
return home_dir; /* ~/ expanded to home */
|
||||
#ifdef HAVE_GETPWNAM
|
||||
{
|
||||
char *str,save;
|
||||
struct passwd *user_entry;
|
||||
|
||||
if (!(str=strchr(*path,FN_LIBCHAR)))
|
||||
str=strend(*path);
|
||||
save= *str; *str= '\0';
|
||||
user_entry=getpwnam(*path);
|
||||
*str=save;
|
||||
endpwent();
|
||||
if (user_entry)
|
||||
{
|
||||
*path=str;
|
||||
return user_entry->pw_dir;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return (my_string) 0;
|
||||
}
|
||||
|
||||
/* fix filename so it can be used by open, create .. */
|
||||
/* to may be == from */
|
||||
/* Returns to */
|
||||
|
||||
my_string unpack_filename(my_string to, const char *from)
|
||||
{
|
||||
uint length,n_length;
|
||||
char buff[FN_REFLEN];
|
||||
DBUG_ENTER("unpack_filename");
|
||||
|
||||
length=dirname_part(buff,from); /* copy & convert dirname */
|
||||
n_length=unpack_dirname(buff,buff);
|
||||
if (n_length+strlen(from+length) < FN_REFLEN)
|
||||
{
|
||||
(void) strmov(buff+n_length,from+length);
|
||||
(void) system_filename(to,buff); /* Fix to usably filename */
|
||||
}
|
||||
else
|
||||
(void) system_filename(to,from); /* Fix to usably filename */
|
||||
DBUG_RETURN(to);
|
||||
} /* unpack_filename */
|
||||
|
||||
|
||||
/* Convert filename (unix standard) to system standard */
|
||||
/* Used before system command's like open(), create() .. */
|
||||
/* Returns to */
|
||||
|
||||
uint system_filename(my_string to, const char *from)
|
||||
{
|
||||
#ifndef FN_C_BEFORE_DIR
|
||||
return (uint) (strmake(to,from,FN_REFLEN-1)-to);
|
||||
#else /* VMS */
|
||||
|
||||
/* change 'dev:lib/xxx' to 'dev:[lib]xxx' */
|
||||
/* change 'dev:xxx' to 'dev:xxx' */
|
||||
/* change './xxx' to 'xxx' */
|
||||
/* change './lib/' or lib/ to '[.lib]' */
|
||||
/* change '/x/y/z to '[x.y]x' */
|
||||
/* change 'dev:/x' to 'dev:[000000]x' */
|
||||
|
||||
int libchar_found,length;
|
||||
my_string to_pos,from_pos,pos;
|
||||
char buff[FN_REFLEN];
|
||||
DBUG_ENTER("system_filename");
|
||||
|
||||
libchar_found=0;
|
||||
(void) strmov(buff,from); /* If to == from */
|
||||
from_pos= buff;
|
||||
if ((pos=strrchr(from_pos,FN_DEVCHAR))) /* Skipp device part */
|
||||
{
|
||||
pos++;
|
||||
to_pos=strnmov(to,from_pos,(size_s) (pos-from_pos));
|
||||
from_pos=pos;
|
||||
}
|
||||
else
|
||||
to_pos=to;
|
||||
|
||||
if (from_pos[0] == FN_CURLIB && from_pos[1] == FN_LIBCHAR)
|
||||
from_pos+=2; /* Skipp './' */
|
||||
if (strchr(from_pos,FN_LIBCHAR))
|
||||
{
|
||||
*(to_pos++) = FN_C_BEFORE_DIR;
|
||||
if (strinstr(from_pos,FN_ROOTDIR) == 1)
|
||||
{
|
||||
from_pos+=strlen(FN_ROOTDIR); /* Actually +1 but... */
|
||||
if (! strchr(from_pos,FN_LIBCHAR))
|
||||
{ /* No dir, use [000000] */
|
||||
to_pos=strmov(to_pos,FN_C_ROOT_DIR);
|
||||
libchar_found++;
|
||||
}
|
||||
}
|
||||
else
|
||||
*(to_pos++)=FN_C_DIR_SEP; /* '.' gives current dir */
|
||||
|
||||
while ((pos=strchr(from_pos,FN_LIBCHAR)))
|
||||
{
|
||||
if (libchar_found++)
|
||||
*(to_pos++)=FN_C_DIR_SEP; /* Add '.' between dirs */
|
||||
if (strinstr(from_pos,FN_PARENTDIR) == 1 &&
|
||||
from_pos+strlen(FN_PARENTDIR) == pos)
|
||||
to_pos=strmov(to_pos,FN_C_PARENT_DIR); /* Found '../' */
|
||||
else
|
||||
to_pos=strnmov(to_pos,from_pos,(size_s) (pos-from_pos));
|
||||
from_pos=pos+1;
|
||||
}
|
||||
*(to_pos++)=FN_C_AFTER_DIR;
|
||||
}
|
||||
length=(int) (strmov(to_pos,from_pos)-to);
|
||||
DBUG_PRINT("exit",("name: '%s'",to));
|
||||
DBUG_RETURN((uint) length);
|
||||
#endif
|
||||
} /* system_filename */
|
||||
|
||||
|
||||
/* Fix a filename to intern (UNIX format) */
|
||||
|
||||
my_string intern_filename(my_string to, const char *from)
|
||||
{
|
||||
#ifndef VMS
|
||||
{
|
||||
uint length;
|
||||
char buff[FN_REFLEN];
|
||||
if (from == to)
|
||||
{ /* Dirname may destroy from */
|
||||
strmov(buff,from);
|
||||
from=buff;
|
||||
}
|
||||
length=dirname_part(to,from); /* Copy dirname & fix chars */
|
||||
(void) strcat(to,from+length);
|
||||
return (to);
|
||||
}
|
||||
#else /* VMS */
|
||||
|
||||
/* change 'dev:[lib]xxx' to 'dev:lib/xxx' */
|
||||
/* change 'dev:xxx' to 'dev:xxx' */
|
||||
/* change 'dev:x/y/[.lib]' to 'dev:x/y/lib/ */
|
||||
/* change '[.lib]' to './lib/' */
|
||||
/* change '[x.y]' or '[x.][y]' or '[x][.y]' to '/x/y/' */
|
||||
/* change '[000000.x] or [x.000000]' to '/x/' */
|
||||
|
||||
int par_length,root_length;
|
||||
my_string pos,from_pos,to_pos,end_pos;
|
||||
char buff[FN_REFLEN];
|
||||
|
||||
(void) strmov(buff,from);
|
||||
convert_dirname(buff); /* change '<>' to '[]' */
|
||||
from_pos=buff;
|
||||
if ((pos=strrchr(from_pos,FN_DEVCHAR))) /* Skipp device part */
|
||||
{
|
||||
pos++;
|
||||
to_pos=strnmov(to,from_pos,(size_s) (pos-from_pos));
|
||||
from_pos=pos;
|
||||
}
|
||||
else
|
||||
to_pos=to;
|
||||
|
||||
root_length=strlen(FN_C_ROOT_DIR);
|
||||
if ((pos = strchr(from_pos,FN_C_BEFORE_DIR)) &&
|
||||
(end_pos = strrchr(pos+1,FN_C_AFTER_DIR)))
|
||||
{
|
||||
to_pos=strnmov(to_pos,from_pos,(size_s) (pos-from_pos));
|
||||
/* Copy all between ':' and '[' */
|
||||
from_pos=pos+1;
|
||||
if (strinstr(from_pos,FN_C_ROOT_DIR) == 1 &&
|
||||
(from_pos[root_length] == FN_C_DIR_SEP ||
|
||||
from_pos[root_length] == FN_C_AFTER_DIR))
|
||||
{
|
||||
from_pos+=root_length+1;
|
||||
}
|
||||
else if (*from_pos == FN_C_DIR_SEP)
|
||||
*(to_pos++) = FN_CURLIB; /* Set ./ first */
|
||||
*(to_pos++) = FN_LIBCHAR;
|
||||
|
||||
par_length=strlen(FN_C_PARENT_DIR);
|
||||
pos=to_pos;
|
||||
for (; from_pos <= end_pos ; from_pos++)
|
||||
{
|
||||
switch (*from_pos) {
|
||||
case FN_C_DIR_SEP:
|
||||
case FN_C_AFTER_DIR:
|
||||
if (pos != to_pos)
|
||||
{
|
||||
if ((int) (to_pos-pos) == root_length &&
|
||||
is_suffix(pos,FN_C_ROOT_DIR))
|
||||
to_pos=pos; /* remove root-pos */
|
||||
else
|
||||
{
|
||||
*(to_pos++)=FN_LIBCHAR; /* Find lib */
|
||||
pos=to_pos;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FN_C_BEFORE_DIR:
|
||||
break;
|
||||
case '-': /* *(FN_C_PARENT_DIR): */
|
||||
if (to_pos[-1] == FN_LIBCHAR &&
|
||||
strncmp(from_pos,FN_C_PARENT_DIR,par_length) == 0)
|
||||
{ /* Change '-' to '..' */
|
||||
to_pos=strmov(to_pos,FN_PARENTDIR);
|
||||
*(to_pos++)=FN_LIBCHAR;
|
||||
pos=to_pos;
|
||||
from_pos+=par_length-1;
|
||||
break;
|
||||
}
|
||||
/* Fall through */
|
||||
default:
|
||||
*(to_pos++)= *from_pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
(void) strmov(to_pos,from_pos);
|
||||
return (to);
|
||||
#endif /* VMS */
|
||||
} /* intern_filename */
|
120
module/Vendor/MDBC/libmariadb/mf_path.c
vendored
Normal file
120
module/Vendor/MDBC/libmariadb/mf_path.c
vendored
Normal file
@ -0,0 +1,120 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include <m_string.h>
|
||||
|
||||
static char *find_file_in_path(char *to,const char *name);
|
||||
|
||||
/* Finds where program can find it's files.
|
||||
pre_pathname is found by first locking at progname (argv[0]).
|
||||
if progname contains path the path is returned.
|
||||
else if progname is found in path, return it
|
||||
else if progname is given and POSIX environment variable "_" is set
|
||||
then path is taken from "_".
|
||||
If filename doesn't contain a path append MY_BASEDIR_VERSION or
|
||||
MY_BASEDIR if defined, else append "/my/running".
|
||||
own_path_name_part is concatinated to result.
|
||||
my_path puts result in to and returns to */
|
||||
|
||||
my_string my_path(my_string to, const char *progname,
|
||||
const char *own_pathname_part)
|
||||
{
|
||||
my_string start,end,prog;
|
||||
DBUG_ENTER("my_path");
|
||||
|
||||
start=to; /* Return this */
|
||||
if (progname && (dirname_part(to, progname) ||
|
||||
find_file_in_path(to,progname) ||
|
||||
((prog=getenv("_")) != 0 && dirname_part(to,prog))))
|
||||
{
|
||||
VOID(intern_filename(to,to));
|
||||
if (!test_if_hard_path(to))
|
||||
{
|
||||
if (!my_getwd(curr_dir,FN_REFLEN,MYF(0)))
|
||||
bchange(to,0,curr_dir, (uint) strlen(curr_dir), (uint) strlen(to)+1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((end = getenv("MY_BASEDIR_VERSION")) == 0 &&
|
||||
(end = getenv("MY_BASEDIR")) == 0)
|
||||
{
|
||||
#ifdef DEFAULT_BASEDIR
|
||||
end= (char*) DEFAULT_BASEDIR;
|
||||
#else
|
||||
end= (char*) "/my/";
|
||||
#endif
|
||||
}
|
||||
VOID(intern_filename(to,end));
|
||||
to=strend(to);
|
||||
if (to != start && to[-1] != FN_LIBCHAR)
|
||||
*to++ = FN_LIBCHAR;
|
||||
VOID(strmov(to,own_pathname_part));
|
||||
}
|
||||
DBUG_PRINT("exit",("to: '%s'",start));
|
||||
DBUG_RETURN(start);
|
||||
} /* my_path */
|
||||
|
||||
|
||||
/* 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(_WIN32) || defined(__EMX__) || defined(OS2)
|
||||
#define F_OK 0
|
||||
#define PATH_SEP ';'
|
||||
#define PROGRAM_EXTENSION ".exe"
|
||||
#else
|
||||
#define PATH_SEP ':'
|
||||
#endif
|
||||
|
||||
static char *find_file_in_path(char *to, const char *name)
|
||||
{
|
||||
char *path,*pos,dir[2];
|
||||
const char *ext="";
|
||||
|
||||
if (!(path=getenv("PATH")))
|
||||
return NullS;
|
||||
dir[0]=FN_LIBCHAR; dir[1]=0;
|
||||
#ifdef PROGRAM_EXTENSION
|
||||
if (!fn_ext(name)[0])
|
||||
ext=PROGRAM_EXTENSION;
|
||||
#endif
|
||||
|
||||
for (pos=path ; (pos=strchr(pos,PATH_SEP)) ; path= ++pos)
|
||||
{
|
||||
if (path != pos)
|
||||
{
|
||||
strxmov(strnmov(to,path,(uint) (pos-path)),dir,name,ext,NullS);
|
||||
if (!access(to,F_OK))
|
||||
{
|
||||
to[(uint) (pos-path)+1]=0; /* Return path only */
|
||||
return to;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef _WIN32
|
||||
to[0]=FN_CURLIB;
|
||||
strxmov(to+1,dir,name,ext,NullS);
|
||||
if (!access(to,F_OK)) /* Test in current dir */
|
||||
{
|
||||
to[2]=0; /* Leave ".\" */
|
||||
return to;
|
||||
}
|
||||
#endif
|
||||
return NullS; /* File not found */
|
||||
}
|
33
module/Vendor/MDBC/libmariadb/mf_unixpath.c
vendored
Normal file
33
module/Vendor/MDBC/libmariadb/mf_unixpath.c
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include <m_string.h>
|
||||
|
||||
/* convert filename to unix style filename */
|
||||
/* If MSDOS converts '\' to '/' */
|
||||
|
||||
void to_unix_path(my_string to __attribute__((unused)))
|
||||
{
|
||||
#if FN_LIBCHAR != '/'
|
||||
{
|
||||
to--;
|
||||
while ((to=strchr(to+1,FN_LIBCHAR)) != 0)
|
||||
*to='/';
|
||||
}
|
||||
#endif
|
||||
}
|
68
module/Vendor/MDBC/libmariadb/mf_wcomp.c
vendored
Normal file
68
module/Vendor/MDBC/libmariadb/mf_wcomp.c
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* Funktions for comparing with wild-cards */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
|
||||
/* Test if a string is "comparable" to a wild-card string */
|
||||
/* returns 0 if the strings are "comparable" */
|
||||
|
||||
char wild_many='*';
|
||||
char wild_one='?';
|
||||
char wild_prefix=0;
|
||||
|
||||
int wild_compare(register const char *str, register const char *wildstr)
|
||||
{
|
||||
reg3 int flag;
|
||||
DBUG_ENTER("wild_compare");
|
||||
|
||||
while (*wildstr)
|
||||
{
|
||||
while (*wildstr && *wildstr != wild_many && *wildstr != wild_one)
|
||||
{
|
||||
if (*wildstr == wild_prefix && wildstr[1])
|
||||
wildstr++;
|
||||
if (*wildstr++ != *str++) DBUG_RETURN(1);
|
||||
}
|
||||
if (! *wildstr ) DBUG_RETURN (*str != 0);
|
||||
if (*wildstr++ == wild_one)
|
||||
{
|
||||
if (! *str++) DBUG_RETURN (1); /* One char; skipp */
|
||||
}
|
||||
else
|
||||
{ /* Found '*' */
|
||||
if (!*wildstr) DBUG_RETURN(0); /* '*' as last char: OK */
|
||||
flag=(*wildstr != wild_many && *wildstr != wild_one);
|
||||
do
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
char cmp;
|
||||
if ((cmp= *wildstr) == wild_prefix && wildstr[1])
|
||||
cmp=wildstr[1];
|
||||
while (*str && *str != cmp)
|
||||
str++;
|
||||
if (!*str) DBUG_RETURN (1);
|
||||
}
|
||||
if (wild_compare(str,wildstr) == 0) DBUG_RETURN (0);
|
||||
} while (*str++ && wildstr[0] != wild_many);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
DBUG_RETURN (*str != '\0');
|
||||
} /* wild_compare */
|
53
module/Vendor/MDBC/libmariadb/mulalloc.c
vendored
Normal file
53
module/Vendor/MDBC/libmariadb/mulalloc.c
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* Malloc many pointers at the same time */
|
||||
/* format myFlags,ptr,length,ptr,length ... until null ptr */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
gptr my_multi_malloc(myf myFlags, ...)
|
||||
{
|
||||
va_list args;
|
||||
char **ptr,*start,*res;
|
||||
uint tot_length,length;
|
||||
DBUG_ENTER("my_multi_malloc");
|
||||
|
||||
va_start(args,myFlags);
|
||||
tot_length=0;
|
||||
while ((ptr=va_arg(args, char **)))
|
||||
{
|
||||
length=va_arg(args,uint);
|
||||
tot_length+=ALIGN_SIZE(length);
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
if (!(start=(char *) my_malloc(tot_length,myFlags)))
|
||||
DBUG_RETURN(0); /* purecov: inspected */
|
||||
|
||||
va_start(args,myFlags);
|
||||
res=start;
|
||||
while ((ptr=va_arg(args, char **)))
|
||||
{
|
||||
*ptr=res;
|
||||
length=va_arg(args,uint);
|
||||
res+=ALIGN_SIZE(length);
|
||||
}
|
||||
va_end(args);
|
||||
DBUG_RETURN((gptr) start);
|
||||
}
|
169
module/Vendor/MDBC/libmariadb/my_alloc.c
vendored
Normal file
169
module/Vendor/MDBC/libmariadb/my_alloc.c
vendored
Normal file
@ -0,0 +1,169 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* Routines to handle mallocing of results which will be freed the same time */
|
||||
|
||||
#include <my_global.h>
|
||||
#include <my_sys.h>
|
||||
#include <m_string.h>
|
||||
|
||||
void init_alloc_root(MEM_ROOT *mem_root, size_t block_size, size_t pre_alloc_size)
|
||||
{
|
||||
mem_root->free= mem_root->used= mem_root->pre_alloc= 0;
|
||||
mem_root->min_malloc=32;
|
||||
mem_root->block_size= (block_size-MALLOC_OVERHEAD-sizeof(USED_MEM)+8);
|
||||
mem_root->error_handler=0;
|
||||
mem_root->block_num= 4;
|
||||
mem_root->first_block_usage= 0;
|
||||
#if !(defined(HAVE_purify) && defined(EXTRA_DEBUG))
|
||||
if (pre_alloc_size)
|
||||
{
|
||||
if ((mem_root->free = mem_root->pre_alloc=
|
||||
(USED_MEM*) my_malloc(pre_alloc_size+ ALIGN_SIZE(sizeof(USED_MEM)),
|
||||
MYF(0))))
|
||||
{
|
||||
mem_root->free->size=pre_alloc_size+ALIGN_SIZE(sizeof(USED_MEM));
|
||||
mem_root->free->left=pre_alloc_size;
|
||||
mem_root->free->next=0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
gptr alloc_root(MEM_ROOT *mem_root, size_t Size)
|
||||
{
|
||||
#if defined(HAVE_purify) && defined(EXTRA_DEBUG)
|
||||
reg1 USED_MEM *next;
|
||||
Size+=ALIGN_SIZE(sizeof(USED_MEM));
|
||||
|
||||
if (!(next = (USED_MEM*) my_malloc(Size,MYF(MY_WME))))
|
||||
{
|
||||
if (mem_root->error_handler)
|
||||
(*mem_root->error_handler)();
|
||||
return((gptr) 0); /* purecov: inspected */
|
||||
}
|
||||
next->next=mem_root->used;
|
||||
mem_root->used=next;
|
||||
return (gptr) (((char*) next)+ALIGN_SIZE(sizeof(USED_MEM)));
|
||||
#else
|
||||
size_t get_size,max_left;
|
||||
gptr point;
|
||||
reg1 USED_MEM *next= 0;
|
||||
reg2 USED_MEM **prev;
|
||||
|
||||
Size= ALIGN_SIZE(Size);
|
||||
max_left=0;
|
||||
|
||||
if ((*(prev= &mem_root->free)))
|
||||
{
|
||||
if ((*prev)->left < Size &&
|
||||
mem_root->first_block_usage++ >= 16 &&
|
||||
(*prev)->left < 4096)
|
||||
{
|
||||
next= *prev;
|
||||
*prev= next->next;
|
||||
next->next= mem_root->used;
|
||||
mem_root->used= next;
|
||||
mem_root->first_block_usage= 0;
|
||||
}
|
||||
for (next= *prev; next && next->left < Size; next= next->next)
|
||||
prev= &next->next;
|
||||
}
|
||||
|
||||
if (! next)
|
||||
{ /* Time to alloc new block */
|
||||
get_size= MAX(Size+ALIGN_SIZE(sizeof(USED_MEM)),
|
||||
(mem_root->block_size & ~1) * (mem_root->block_num >> 2));
|
||||
|
||||
if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME))))
|
||||
{
|
||||
if (mem_root->error_handler)
|
||||
(*mem_root->error_handler)();
|
||||
return((gptr) 0); /* purecov: inspected */
|
||||
}
|
||||
mem_root->block_num++;
|
||||
next->next= *prev;
|
||||
next->size= get_size;
|
||||
next->left= get_size-ALIGN_SIZE(sizeof(USED_MEM));
|
||||
*prev=next;
|
||||
}
|
||||
point= (gptr) ((char*) next+ (next->size-next->left));
|
||||
if ((next->left-= Size) < mem_root->min_malloc)
|
||||
{ /* Full block */
|
||||
*prev=next->next; /* Remove block from list */
|
||||
next->next=mem_root->used;
|
||||
mem_root->used=next;
|
||||
mem_root->first_block_usage= 0;
|
||||
}
|
||||
return(point);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* deallocate everything used by alloc_root */
|
||||
|
||||
void free_root(MEM_ROOT *root, myf MyFlags)
|
||||
{
|
||||
reg1 USED_MEM *next,*old;
|
||||
DBUG_ENTER("free_root");
|
||||
|
||||
if (!root)
|
||||
DBUG_VOID_RETURN; /* purecov: inspected */
|
||||
if (!(MyFlags & MY_KEEP_PREALLOC))
|
||||
root->pre_alloc=0;
|
||||
|
||||
for ( next=root->used; next ;)
|
||||
{
|
||||
old=next; next= next->next ;
|
||||
if (old != root->pre_alloc)
|
||||
my_free(old);
|
||||
}
|
||||
for (next= root->free ; next ; )
|
||||
{
|
||||
old=next; next= next->next ;
|
||||
if (old != root->pre_alloc)
|
||||
my_free(old);
|
||||
}
|
||||
root->used=root->free=0;
|
||||
if (root->pre_alloc)
|
||||
{
|
||||
root->free=root->pre_alloc;
|
||||
root->free->left=root->pre_alloc->size-ALIGN_SIZE(sizeof(USED_MEM));
|
||||
root->free->next=0;
|
||||
}
|
||||
root->block_num= 4;
|
||||
root->first_block_usage= 0;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
char *strdup_root(MEM_ROOT *root,const char *str)
|
||||
{
|
||||
size_t len= strlen(str)+1;
|
||||
char *pos;
|
||||
if ((pos=alloc_root(root,len)))
|
||||
memcpy(pos,str,len);
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
char *memdup_root(MEM_ROOT *root, const char *str, size_t len)
|
||||
{
|
||||
char *pos;
|
||||
if ((pos=alloc_root(root,len)))
|
||||
memcpy(pos,str,len);
|
||||
return pos;
|
||||
}
|
742
module/Vendor/MDBC/libmariadb/my_auth.c
vendored
Normal file
742
module/Vendor/MDBC/libmariadb/my_auth.c
vendored
Normal file
@ -0,0 +1,742 @@
|
||||
/************************************************************************************
|
||||
Copyright (C) 2012-2015 Monty Program AB, MariaDB Corporation 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
|
||||
|
||||
Originally written by Sergei Golubchik
|
||||
*************************************************************************************/
|
||||
#include <my_global.h>
|
||||
#include <my_sys.h>
|
||||
#include <m_string.h>
|
||||
#include <errmsg.h>
|
||||
#include <ma_common.h>
|
||||
#include <mysql/client_plugin.h>
|
||||
#include <violite.h>
|
||||
#ifdef HAVE_OPENSSL
|
||||
#include <ma_secure.h>
|
||||
#endif
|
||||
|
||||
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);
|
||||
extern uchar *ma_send_connect_attr(MYSQL *mysql, uchar *buffer);
|
||||
|
||||
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},
|
||||
"LGPL",
|
||||
NULL,
|
||||
NULL,
|
||||
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},
|
||||
"LGPL",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
old_password_auth_client
|
||||
};
|
||||
typedef struct st_mariadb_client_plugin_DBAPI dbapi_plugin_t;
|
||||
|
||||
#ifdef HAVE_SQLITE
|
||||
extern dbapi_plugin_t sqlite3_plugin;
|
||||
#endif
|
||||
|
||||
struct st_mysql_client_plugin *mysql_client_builtins[]=
|
||||
{
|
||||
(struct st_mysql_client_plugin *)&old_password_client_plugin,
|
||||
(struct st_mysql_client_plugin *)&native_password_client_plugin,
|
||||
#ifdef HAVE_SQLITE
|
||||
(struct st_mysql_client_plugin *)&sqlite3_plugin,
|
||||
#endif
|
||||
0
|
||||
};
|
||||
|
||||
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 */
|
||||
memmove(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;
|
||||
}
|
||||
|
||||
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;
|
||||
size_t conn_attr_len= (mysql->options.extension) ?
|
||||
mysql->options.extension->connect_attrs_len : 0;
|
||||
|
||||
buff= my_alloca(USERNAME_LENGTH+1 + data_len+1 + NAME_LEN+1 + 2 + NAME_LEN+1 + 9 + conn_attr_len);
|
||||
|
||||
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;
|
||||
|
||||
end= ma_send_connect_attr(mysql, end);
|
||||
|
||||
res= simple_command(mysql, MYSQL_COM_CHANGE_USER,
|
||||
buff, (ulong)(end-buff), 1, NULL);
|
||||
|
||||
error:
|
||||
my_afree(buff);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
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;
|
||||
size_t conn_attr_len= (mysql->options.extension) ?
|
||||
mysql->options.extension->connect_attrs_len : 0;
|
||||
|
||||
/* 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 + conn_attr_len + 9);
|
||||
|
||||
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;
|
||||
|
||||
/* if server doesn't support SSL and verification of server certificate
|
||||
was set to mandatory, we need to return an error */
|
||||
if (mysql->options.use_ssl && !(mysql->server_capabilities & CLIENT_SSL))
|
||||
{
|
||||
if ((mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) ||
|
||||
(mysql->options.extension && (mysql->options.extension->ssl_fp ||
|
||||
mysql->options.extension->ssl_fp_list)))
|
||||
{
|
||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||
ER(CR_SSL_CONNECTION_ERROR),
|
||||
"Server doesn't support SSL");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
#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->options.ssl_key ||
|
||||
mysql->options.ssl_cert ||
|
||||
mysql->options.ssl_ca ||
|
||||
mysql->options.ssl_capath ||
|
||||
mysql->options.ssl_cipher
|
||||
#ifdef CRL_IMPLEMENTED
|
||||
|| (mysql->options.extension &&
|
||||
(mysql->options.extension->ssl_crl ||
|
||||
mysql->options.extension->ssl_crlpath))
|
||||
#endif
|
||||
)
|
||||
mysql->options.use_ssl= 1;
|
||||
|
||||
if (mysql->options.use_ssl &&
|
||||
(mysql->client_flag & CLIENT_SSL))
|
||||
{
|
||||
SSL *ssl;
|
||||
/*
|
||||
Send mysql->client_flag, max_packet_size - unencrypted otherwise
|
||||
the server does not know we want to do SSL
|
||||
*/
|
||||
if (my_net_write(net, (char*)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 SSL */
|
||||
if (!(ssl= my_ssl_init(mysql)))
|
||||
goto error;
|
||||
|
||||
/* Connect to the server */
|
||||
if (my_ssl_connect(ssl))
|
||||
{
|
||||
SSL_free(ssl);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (mysql->options.extension &&
|
||||
(mysql->options.extension->ssl_fp || mysql->options.extension->ssl_fp_list))
|
||||
{
|
||||
if (ma_ssl_verify_fingerprint(ssl))
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((mysql->options.ssl_ca || mysql->options.ssl_capath) &&
|
||||
(mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) &&
|
||||
my_ssl_verify_server_cert(ssl))
|
||||
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));
|
||||
|
||||
/* 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;
|
||||
|
||||
end= ma_send_connect_attr(mysql, end);
|
||||
|
||||
/* 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, (int)pkt_len);
|
||||
else
|
||||
res= send_client_reply_packet(mpvio, pkt, (int)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);
|
||||
|
||||
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= (uint)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;
|
||||
}
|
||||
|
1466
module/Vendor/MDBC/libmariadb/my_charset.c
vendored
Normal file
1466
module/Vendor/MDBC/libmariadb/my_charset.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
89
module/Vendor/MDBC/libmariadb/my_compress.c
vendored
Normal file
89
module/Vendor/MDBC/libmariadb/my_compress.c
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* Written by Sinisa Milivojevic <sinisa@coresinc.com> */
|
||||
|
||||
#include <my_global.h>
|
||||
#ifdef HAVE_COMPRESS
|
||||
#include <my_sys.h>
|
||||
#include <m_string.h>
|
||||
#include <zlib.h>
|
||||
|
||||
/*
|
||||
** This replaces the packet with a compressed packet
|
||||
** Returns 1 on error
|
||||
** *complen is 0 if the packet wasn't compressed
|
||||
*/
|
||||
|
||||
my_bool my_compress(unsigned char *packet, size_t *len, size_t *complen)
|
||||
{
|
||||
if (*len < MIN_COMPRESS_LENGTH)
|
||||
*complen=0;
|
||||
else
|
||||
{
|
||||
unsigned char *compbuf=my_compress_alloc(packet,len,complen);
|
||||
if (!compbuf)
|
||||
return *complen ? 0 : 1;
|
||||
memcpy(packet,compbuf,*len);
|
||||
my_free(compbuf);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
unsigned char *my_compress_alloc(const unsigned char *packet, size_t *len, size_t *complen)
|
||||
{
|
||||
unsigned char *compbuf;
|
||||
*complen = *len * 120 / 100 + 12;
|
||||
if (!(compbuf = (unsigned char *) my_malloc(*complen,MYF(MY_WME))))
|
||||
return 0; /* Not enough memory */
|
||||
if (compress((Bytef*) compbuf,(ulong *) complen, (Bytef*) packet,
|
||||
(uLong) *len ) != Z_OK)
|
||||
{
|
||||
my_free(compbuf);
|
||||
return 0;
|
||||
}
|
||||
if (*complen >= *len)
|
||||
{
|
||||
*complen=0;
|
||||
my_free(compbuf);
|
||||
return 0;
|
||||
}
|
||||
swap(ulong,*len,*complen); /* *len is now packet length */
|
||||
return compbuf;
|
||||
}
|
||||
|
||||
my_bool my_uncompress (unsigned char *packet, size_t *len, size_t *complen)
|
||||
{
|
||||
if (*complen) /* If compressed */
|
||||
{
|
||||
unsigned char *compbuf = (unsigned char *) my_malloc (*complen,MYF(MY_WME));
|
||||
if (!compbuf)
|
||||
return 1; /* Not enough memory */
|
||||
if (uncompress((Bytef*) compbuf, (uLongf *)complen, (Bytef*) packet, (uLongf)*len) != Z_OK)
|
||||
{ /* Probably wrong packet */
|
||||
my_free (compbuf);
|
||||
return 1;
|
||||
}
|
||||
*len = *complen;
|
||||
memcpy(packet,compbuf,*len);
|
||||
my_free(compbuf);
|
||||
}
|
||||
else *complen= *len;
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_COMPRESS */
|
760
module/Vendor/MDBC/libmariadb/my_context.c
vendored
Normal file
760
module/Vendor/MDBC/libmariadb/my_context.c
vendored
Normal file
@ -0,0 +1,760 @@
|
||||
/*
|
||||
Copyright 2011, 2012 Kristian Nielsen and Monty Program Ab
|
||||
|
||||
This file is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
Implementation of async context spawning using Posix ucontext and
|
||||
swapcontext().
|
||||
*/
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include "m_string.h"
|
||||
#include "my_context.h"
|
||||
|
||||
#ifdef HAVE_VALGRIND
|
||||
#include <valgrind/valgrind.h>
|
||||
#endif
|
||||
|
||||
#ifdef MY_CONTEXT_USE_UCONTEXT
|
||||
/*
|
||||
The makecontext() only allows to pass integers into the created context :-(
|
||||
We want to pass pointers, so we do it this kinda hackish way.
|
||||
Anyway, it should work everywhere, and at least it does not break strict
|
||||
aliasing.
|
||||
*/
|
||||
union pass_void_ptr_as_2_int {
|
||||
int a[2];
|
||||
void *p;
|
||||
};
|
||||
|
||||
/*
|
||||
We use old-style function definition here, as this is passed to
|
||||
makecontext(). And the type of the makecontext() argument does not match
|
||||
the actual type (as the actual type can differ from call to call).
|
||||
*/
|
||||
static void
|
||||
my_context_spawn_internal(i0, i1)
|
||||
int i0, i1;
|
||||
{
|
||||
int err;
|
||||
struct my_context *c;
|
||||
union pass_void_ptr_as_2_int u;
|
||||
|
||||
u.a[0]= i0;
|
||||
u.a[1]= i1;
|
||||
c= (struct my_context *)u.p;
|
||||
|
||||
(*c->user_func)(c->user_data);
|
||||
c->active= 0;
|
||||
err= setcontext(&c->base_context);
|
||||
fprintf(stderr, "Aieie, setcontext() failed: %d (errno=%d)\n", err, errno);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
my_context_continue(struct my_context *c)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (!c->active)
|
||||
return 0;
|
||||
|
||||
DBUG_SWAP_CODE_STATE(&c->dbug_state);
|
||||
err= swapcontext(&c->base_context, &c->spawned_context);
|
||||
DBUG_SWAP_CODE_STATE(&c->dbug_state);
|
||||
if (err)
|
||||
{
|
||||
fprintf(stderr, "Aieie, swapcontext() failed: %d (errno=%d)\n",
|
||||
err, errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return c->active;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
my_context_spawn(struct my_context *c, void (*f)(void *), void *d)
|
||||
{
|
||||
int err;
|
||||
union pass_void_ptr_as_2_int u;
|
||||
|
||||
err= getcontext(&c->spawned_context);
|
||||
if (err)
|
||||
return -1;
|
||||
c->spawned_context.uc_stack.ss_sp= c->stack;
|
||||
c->spawned_context.uc_stack.ss_size= c->stack_size;
|
||||
c->spawned_context.uc_link= NULL;
|
||||
c->user_func= f;
|
||||
c->user_data= d;
|
||||
c->active= 1;
|
||||
u.p= c;
|
||||
makecontext(&c->spawned_context, my_context_spawn_internal, 2,
|
||||
u.a[0], u.a[1]);
|
||||
|
||||
return my_context_continue(c);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
my_context_yield(struct my_context *c)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (!c->active)
|
||||
return -1;
|
||||
|
||||
err= swapcontext(&c->spawned_context, &c->base_context);
|
||||
if (err)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
my_context_init(struct my_context *c, size_t stack_size)
|
||||
{
|
||||
#if SIZEOF_CHARP > SIZEOF_INT*2
|
||||
#error Error: Unable to store pointer in 2 ints on this architecture
|
||||
#endif
|
||||
|
||||
bzero(c, sizeof(*c));
|
||||
if (!(c->stack= malloc(stack_size)))
|
||||
return -1; /* Out of memory */
|
||||
c->stack_size= stack_size;
|
||||
#ifdef HAVE_VALGRIND
|
||||
c->valgrind_stack_id=
|
||||
VALGRIND_STACK_REGISTER(c->stack, ((unsigned char *)(c->stack))+stack_size);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
my_context_destroy(struct my_context *c)
|
||||
{
|
||||
if (c->stack)
|
||||
{
|
||||
#ifdef HAVE_VALGRIND
|
||||
VALGRIND_STACK_DEREGISTER(c->valgrind_stack_id);
|
||||
#endif
|
||||
free(c->stack);
|
||||
}
|
||||
DBUG_FREE_CODE_STATE(&c->dbug_state);
|
||||
}
|
||||
|
||||
#endif /* MY_CONTEXT_USE_UCONTEXT */
|
||||
|
||||
|
||||
#ifdef MY_CONTEXT_USE_X86_64_GCC_ASM
|
||||
/*
|
||||
GCC-amd64 implementation of my_context.
|
||||
|
||||
This is slightly optimized in the common case where we never yield
|
||||
(eg. fetch next row and it is already fully received in buffer). In this
|
||||
case we do not need to restore registers at return (though we still need to
|
||||
save them as we cannot know if we will yield or not in advance).
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
Layout of saved registers etc.
|
||||
Since this is accessed through gcc inline assembler, it is simpler to just
|
||||
use numbers than to try to define nice constants or structs.
|
||||
|
||||
0 0 %rsp
|
||||
1 8 %rbp
|
||||
2 16 %rbx
|
||||
3 24 %r12
|
||||
4 32 %r13
|
||||
5 40 %r14
|
||||
6 48 %r15
|
||||
7 56 %rip for done
|
||||
8 64 %rip for yield/continue
|
||||
*/
|
||||
|
||||
int
|
||||
my_context_spawn(struct my_context *c, void (*f)(void *), void *d)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DBUG_SWAP_CODE_STATE(&c->dbug_state);
|
||||
|
||||
/*
|
||||
There are 6 callee-save registers we need to save and restore when
|
||||
suspending and continuing, plus stack pointer %rsp and instruction pointer
|
||||
%rip.
|
||||
|
||||
However, if we never suspend, the user-supplied function will in any case
|
||||
restore the 6 callee-save registers, so we can avoid restoring them in
|
||||
this case.
|
||||
*/
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"movq %%rsp, (%[save])\n\t"
|
||||
"movq %[stack], %%rsp\n\t"
|
||||
#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4 && !defined(__INTEL_COMPILER)
|
||||
/*
|
||||
This emits a DWARF DW_CFA_undefined directive to make the return address
|
||||
undefined. This indicates that this is the top of the stack frame, and
|
||||
helps tools that use DWARF stack unwinding to obtain stack traces.
|
||||
(I use numeric constant to avoid a dependency on libdwarf includes).
|
||||
*/
|
||||
".cfi_escape 0x07, 16\n\t"
|
||||
#endif
|
||||
"movq %%rbp, 8(%[save])\n\t"
|
||||
"movq %%rbx, 16(%[save])\n\t"
|
||||
"movq %%r12, 24(%[save])\n\t"
|
||||
"movq %%r13, 32(%[save])\n\t"
|
||||
"movq %%r14, 40(%[save])\n\t"
|
||||
"movq %%r15, 48(%[save])\n\t"
|
||||
"leaq 1f(%%rip), %%rax\n\t"
|
||||
"leaq 2f(%%rip), %%rcx\n\t"
|
||||
"movq %%rax, 56(%[save])\n\t"
|
||||
"movq %%rcx, 64(%[save])\n\t"
|
||||
/*
|
||||
Constraint below puts the argument to the user function into %rdi, as
|
||||
needed for the calling convention.
|
||||
*/
|
||||
"callq *%[f]\n\t"
|
||||
"jmpq *56(%[save])\n"
|
||||
/*
|
||||
Come here when operation is done.
|
||||
We do not need to restore callee-save registers, as the called function
|
||||
will do this for us if needed.
|
||||
*/
|
||||
"1:\n\t"
|
||||
"movq (%[save]), %%rsp\n\t"
|
||||
"xorl %[ret], %[ret]\n\t"
|
||||
"jmp 3f\n"
|
||||
/* Come here when operation was suspended. */
|
||||
"2:\n\t"
|
||||
"movl $1, %[ret]\n"
|
||||
"3:\n"
|
||||
: [ret] "=a" (ret),
|
||||
[f] "+S" (f),
|
||||
/* Need this in %rdi to follow calling convention. */
|
||||
[d] "+D" (d)
|
||||
: [stack] "a" (c->stack_top),
|
||||
/* Need this in callee-save register to preserve in function call. */
|
||||
[save] "b" (&c->save[0])
|
||||
: "rcx", "rdx", "r8", "r9", "r10", "r11", "memory", "cc"
|
||||
);
|
||||
|
||||
DBUG_SWAP_CODE_STATE(&c->dbug_state);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
my_context_continue(struct my_context *c)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DBUG_SWAP_CODE_STATE(&c->dbug_state);
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"movq (%[save]), %%rax\n\t"
|
||||
"movq %%rsp, (%[save])\n\t"
|
||||
"movq %%rax, %%rsp\n\t"
|
||||
"movq 8(%[save]), %%rax\n\t"
|
||||
"movq %%rbp, 8(%[save])\n\t"
|
||||
"movq %%rax, %%rbp\n\t"
|
||||
"movq 24(%[save]), %%rax\n\t"
|
||||
"movq %%r12, 24(%[save])\n\t"
|
||||
"movq %%rax, %%r12\n\t"
|
||||
"movq 32(%[save]), %%rax\n\t"
|
||||
"movq %%r13, 32(%[save])\n\t"
|
||||
"movq %%rax, %%r13\n\t"
|
||||
"movq 40(%[save]), %%rax\n\t"
|
||||
"movq %%r14, 40(%[save])\n\t"
|
||||
"movq %%rax, %%r14\n\t"
|
||||
"movq 48(%[save]), %%rax\n\t"
|
||||
"movq %%r15, 48(%[save])\n\t"
|
||||
"movq %%rax, %%r15\n\t"
|
||||
|
||||
"leaq 1f(%%rip), %%rax\n\t"
|
||||
"leaq 2f(%%rip), %%rcx\n\t"
|
||||
"movq %%rax, 56(%[save])\n\t"
|
||||
"movq 64(%[save]), %%rax\n\t"
|
||||
"movq %%rcx, 64(%[save])\n\t"
|
||||
|
||||
"movq 16(%[save]), %%rcx\n\t"
|
||||
"movq %%rbx, 16(%[save])\n\t"
|
||||
"movq %%rcx, %%rbx\n\t"
|
||||
|
||||
"jmpq *%%rax\n"
|
||||
/*
|
||||
Come here when operation is done.
|
||||
Be sure to use the same callee-save register for %[save] here and in
|
||||
my_context_spawn(), so we preserve the value correctly at this point.
|
||||
*/
|
||||
"1:\n\t"
|
||||
"movq (%[save]), %%rsp\n\t"
|
||||
"movq 8(%[save]), %%rbp\n\t"
|
||||
/* %rbx is preserved from my_context_spawn() in this case. */
|
||||
"movq 24(%[save]), %%r12\n\t"
|
||||
"movq 32(%[save]), %%r13\n\t"
|
||||
"movq 40(%[save]), %%r14\n\t"
|
||||
"movq 48(%[save]), %%r15\n\t"
|
||||
"xorl %[ret], %[ret]\n\t"
|
||||
"jmp 3f\n"
|
||||
/* Come here when operation is suspended. */
|
||||
"2:\n\t"
|
||||
"movl $1, %[ret]\n"
|
||||
"3:\n"
|
||||
: [ret] "=a" (ret)
|
||||
: /* Need this in callee-save register to preserve in function call. */
|
||||
[save] "b" (&c->save[0])
|
||||
: "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", "r11", "memory", "cc"
|
||||
);
|
||||
|
||||
DBUG_SWAP_CODE_STATE(&c->dbug_state);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
my_context_yield(struct my_context *c)
|
||||
{
|
||||
uint64_t *save= &c->save[0];
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"movq (%[save]), %%rax\n\t"
|
||||
"movq %%rsp, (%[save])\n\t"
|
||||
"movq %%rax, %%rsp\n\t"
|
||||
"movq 8(%[save]), %%rax\n\t"
|
||||
"movq %%rbp, 8(%[save])\n\t"
|
||||
"movq %%rax, %%rbp\n\t"
|
||||
"movq 16(%[save]), %%rax\n\t"
|
||||
"movq %%rbx, 16(%[save])\n\t"
|
||||
"movq %%rax, %%rbx\n\t"
|
||||
"movq 24(%[save]), %%rax\n\t"
|
||||
"movq %%r12, 24(%[save])\n\t"
|
||||
"movq %%rax, %%r12\n\t"
|
||||
"movq 32(%[save]), %%rax\n\t"
|
||||
"movq %%r13, 32(%[save])\n\t"
|
||||
"movq %%rax, %%r13\n\t"
|
||||
"movq 40(%[save]), %%rax\n\t"
|
||||
"movq %%r14, 40(%[save])\n\t"
|
||||
"movq %%rax, %%r14\n\t"
|
||||
"movq 48(%[save]), %%rax\n\t"
|
||||
"movq %%r15, 48(%[save])\n\t"
|
||||
"movq %%rax, %%r15\n\t"
|
||||
"movq 64(%[save]), %%rax\n\t"
|
||||
"leaq 1f(%%rip), %%rcx\n\t"
|
||||
"movq %%rcx, 64(%[save])\n\t"
|
||||
|
||||
"jmpq *%%rax\n"
|
||||
|
||||
"1:\n"
|
||||
: [save] "+D" (save)
|
||||
:
|
||||
: "rax", "rcx", "rdx", "rsi", "r8", "r9", "r10", "r11", "memory", "cc"
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
my_context_init(struct my_context *c, size_t stack_size)
|
||||
{
|
||||
bzero(c, sizeof(*c));
|
||||
|
||||
if (!(c->stack_bot= malloc(stack_size)))
|
||||
return -1; /* Out of memory */
|
||||
/*
|
||||
The x86_64 ABI specifies 16-byte stack alignment.
|
||||
Also put two zero words at the top of the stack.
|
||||
*/
|
||||
c->stack_top= (void *)
|
||||
(( ((intptr)c->stack_bot + stack_size) & ~(intptr)0xf) - 16);
|
||||
bzero(c->stack_top, 16);
|
||||
|
||||
#ifdef HAVE_VALGRIND
|
||||
c->valgrind_stack_id=
|
||||
VALGRIND_STACK_REGISTER(c->stack_bot, c->stack_top);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
my_context_destroy(struct my_context *c)
|
||||
{
|
||||
if (c->stack_bot)
|
||||
{
|
||||
free(c->stack_bot);
|
||||
#ifdef HAVE_VALGRIND
|
||||
VALGRIND_STACK_DEREGISTER(c->valgrind_stack_id);
|
||||
#endif
|
||||
}
|
||||
DBUG_FREE_CODE_STATE(&c->dbug_state);
|
||||
}
|
||||
|
||||
#endif /* MY_CONTEXT_USE_X86_64_GCC_ASM */
|
||||
|
||||
|
||||
#ifdef MY_CONTEXT_USE_I386_GCC_ASM
|
||||
/*
|
||||
GCC-i386 implementation of my_context.
|
||||
|
||||
This is slightly optimized in the common case where we never yield
|
||||
(eg. fetch next row and it is already fully received in buffer). In this
|
||||
case we do not need to restore registers at return (though we still need to
|
||||
save them as we cannot know if we will yield or not in advance).
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
Layout of saved registers etc.
|
||||
Since this is accessed through gcc inline assembler, it is simpler to just
|
||||
use numbers than to try to define nice constants or structs.
|
||||
|
||||
0 0 %esp
|
||||
1 4 %ebp
|
||||
2 8 %ebx
|
||||
3 12 %esi
|
||||
4 16 %edi
|
||||
5 20 %eip for done
|
||||
6 24 %eip for yield/continue
|
||||
*/
|
||||
|
||||
int
|
||||
my_context_spawn(struct my_context *c, void (*f)(void *), void *d)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DBUG_SWAP_CODE_STATE(&c->dbug_state);
|
||||
|
||||
/*
|
||||
There are 4 callee-save registers we need to save and restore when
|
||||
suspending and continuing, plus stack pointer %esp and instruction pointer
|
||||
%eip.
|
||||
|
||||
However, if we never suspend, the user-supplied function will in any case
|
||||
restore the 4 callee-save registers, so we can avoid restoring them in
|
||||
this case.
|
||||
*/
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"movl %%esp, (%[save])\n\t"
|
||||
"movl %[stack], %%esp\n\t"
|
||||
#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4 && !defined(__INTEL_COMPILER)
|
||||
/*
|
||||
This emits a DWARF DW_CFA_undefined directive to make the return address
|
||||
undefined. This indicates that this is the top of the stack frame, and
|
||||
helps tools that use DWARF stack unwinding to obtain stack traces.
|
||||
(I use numeric constant to avoid a dependency on libdwarf includes).
|
||||
*/
|
||||
".cfi_escape 0x07, 8\n\t"
|
||||
#endif
|
||||
/* Push the parameter on the stack. */
|
||||
"pushl %[d]\n\t"
|
||||
"movl %%ebp, 4(%[save])\n\t"
|
||||
"movl %%ebx, 8(%[save])\n\t"
|
||||
"movl %%esi, 12(%[save])\n\t"
|
||||
"movl %%edi, 16(%[save])\n\t"
|
||||
/* Get label addresses in -fPIC-compatible way (no pc-relative on 32bit) */
|
||||
"call 1f\n"
|
||||
"1:\n\t"
|
||||
"popl %%eax\n\t"
|
||||
"addl $(2f-1b), %%eax\n\t"
|
||||
"movl %%eax, 20(%[save])\n\t"
|
||||
"addl $(3f-2f), %%eax\n\t"
|
||||
"movl %%eax, 24(%[save])\n\t"
|
||||
"call *%[f]\n\t"
|
||||
"jmp *20(%[save])\n"
|
||||
/*
|
||||
Come here when operation is done.
|
||||
We do not need to restore callee-save registers, as the called function
|
||||
will do this for us if needed.
|
||||
*/
|
||||
"2:\n\t"
|
||||
"movl (%[save]), %%esp\n\t"
|
||||
"xorl %[ret], %[ret]\n\t"
|
||||
"jmp 4f\n"
|
||||
/* Come here when operation was suspended. */
|
||||
"3:\n\t"
|
||||
"movl $1, %[ret]\n"
|
||||
"4:\n"
|
||||
: [ret] "=a" (ret),
|
||||
[f] "+c" (f),
|
||||
[d] "+d" (d)
|
||||
: [stack] "a" (c->stack_top),
|
||||
/* Need this in callee-save register to preserve across function call. */
|
||||
[save] "D" (&c->save[0])
|
||||
: "memory", "cc"
|
||||
);
|
||||
|
||||
DBUG_SWAP_CODE_STATE(&c->dbug_state);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
my_context_continue(struct my_context *c)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DBUG_SWAP_CODE_STATE(&c->dbug_state);
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"movl (%[save]), %%eax\n\t"
|
||||
"movl %%esp, (%[save])\n\t"
|
||||
"movl %%eax, %%esp\n\t"
|
||||
"movl 4(%[save]), %%eax\n\t"
|
||||
"movl %%ebp, 4(%[save])\n\t"
|
||||
"movl %%eax, %%ebp\n\t"
|
||||
"movl 8(%[save]), %%eax\n\t"
|
||||
"movl %%ebx, 8(%[save])\n\t"
|
||||
"movl %%eax, %%ebx\n\t"
|
||||
"movl 12(%[save]), %%eax\n\t"
|
||||
"movl %%esi, 12(%[save])\n\t"
|
||||
"movl %%eax, %%esi\n\t"
|
||||
|
||||
"movl 24(%[save]), %%eax\n\t"
|
||||
"call 1f\n"
|
||||
"1:\n\t"
|
||||
"popl %%ecx\n\t"
|
||||
"addl $(2f-1b), %%ecx\n\t"
|
||||
"movl %%ecx, 20(%[save])\n\t"
|
||||
"addl $(3f-2f), %%ecx\n\t"
|
||||
"movl %%ecx, 24(%[save])\n\t"
|
||||
|
||||
/* Must restore %edi last as it is also our %[save] register. */
|
||||
"movl 16(%[save]), %%ecx\n\t"
|
||||
"movl %%edi, 16(%[save])\n\t"
|
||||
"movl %%ecx, %%edi\n\t"
|
||||
|
||||
"jmp *%%eax\n"
|
||||
/*
|
||||
Come here when operation is done.
|
||||
Be sure to use the same callee-save register for %[save] here and in
|
||||
my_context_spawn(), so we preserve the value correctly at this point.
|
||||
*/
|
||||
"2:\n\t"
|
||||
"movl (%[save]), %%esp\n\t"
|
||||
"movl 4(%[save]), %%ebp\n\t"
|
||||
"movl 8(%[save]), %%ebx\n\t"
|
||||
"movl 12(%[save]), %%esi\n\t"
|
||||
"movl 16(%[save]), %%edi\n\t"
|
||||
"xorl %[ret], %[ret]\n\t"
|
||||
"jmp 4f\n"
|
||||
/* Come here when operation is suspended. */
|
||||
"3:\n\t"
|
||||
"movl $1, %[ret]\n"
|
||||
"4:\n"
|
||||
: [ret] "=a" (ret)
|
||||
: /* Need this in callee-save register to preserve in function call. */
|
||||
[save] "D" (&c->save[0])
|
||||
: "ecx", "edx", "memory", "cc"
|
||||
);
|
||||
|
||||
DBUG_SWAP_CODE_STATE(&c->dbug_state);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
my_context_yield(struct my_context *c)
|
||||
{
|
||||
uint64_t *save= &c->save[0];
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"movl (%[save]), %%eax\n\t"
|
||||
"movl %%esp, (%[save])\n\t"
|
||||
"movl %%eax, %%esp\n\t"
|
||||
"movl 4(%[save]), %%eax\n\t"
|
||||
"movl %%ebp, 4(%[save])\n\t"
|
||||
"movl %%eax, %%ebp\n\t"
|
||||
"movl 8(%[save]), %%eax\n\t"
|
||||
"movl %%ebx, 8(%[save])\n\t"
|
||||
"movl %%eax, %%ebx\n\t"
|
||||
"movl 12(%[save]), %%eax\n\t"
|
||||
"movl %%esi, 12(%[save])\n\t"
|
||||
"movl %%eax, %%esi\n\t"
|
||||
"movl 16(%[save]), %%eax\n\t"
|
||||
"movl %%edi, 16(%[save])\n\t"
|
||||
"movl %%eax, %%edi\n\t"
|
||||
|
||||
"movl 24(%[save]), %%eax\n\t"
|
||||
"call 1f\n"
|
||||
"1:\n\t"
|
||||
"popl %%ecx\n\t"
|
||||
"addl $(2f-1b), %%ecx\n\t"
|
||||
"movl %%ecx, 24(%[save])\n\t"
|
||||
|
||||
"jmp *%%eax\n"
|
||||
|
||||
"2:\n"
|
||||
: [save] "+d" (save)
|
||||
:
|
||||
: "eax", "ecx", "memory", "cc"
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
my_context_init(struct my_context *c, size_t stack_size)
|
||||
{
|
||||
bzero(c, sizeof(*c));
|
||||
if (!(c->stack_bot= malloc(stack_size)))
|
||||
return -1; /* Out of memory */
|
||||
c->stack_top= (void *)
|
||||
(( ((intptr)c->stack_bot + stack_size) & ~(intptr)0xf) - 16);
|
||||
bzero(c->stack_top, 16);
|
||||
|
||||
#ifdef HAVE_VALGRIND
|
||||
c->valgrind_stack_id=
|
||||
VALGRIND_STACK_REGISTER(c->stack_bot, c->stack_top);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
my_context_destroy(struct my_context *c)
|
||||
{
|
||||
if (c->stack_bot)
|
||||
{
|
||||
free(c->stack_bot);
|
||||
#ifdef HAVE_VALGRIND
|
||||
VALGRIND_STACK_DEREGISTER(c->valgrind_stack_id);
|
||||
#endif
|
||||
}
|
||||
DBUG_FREE_CODE_STATE(&c->dbug_state);
|
||||
}
|
||||
|
||||
#endif /* MY_CONTEXT_USE_I386_GCC_ASM */
|
||||
|
||||
|
||||
#ifdef MY_CONTEXT_USE_WIN32_FIBERS
|
||||
int
|
||||
my_context_yield(struct my_context *c)
|
||||
{
|
||||
c->return_value= 1;
|
||||
SwitchToFiber(c->app_fiber);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void WINAPI
|
||||
my_context_trampoline(void *p)
|
||||
{
|
||||
struct my_context *c= (struct my_context *)p;
|
||||
/*
|
||||
Reuse the Fiber by looping infinitely, each time we are scheduled we
|
||||
spawn the appropriate function and switch back when it is done.
|
||||
|
||||
This way we avoid the overhead of CreateFiber() for every asynchroneous
|
||||
operation.
|
||||
*/
|
||||
for(;;)
|
||||
{
|
||||
(*(c->user_func))(c->user_arg);
|
||||
c->return_value= 0;
|
||||
SwitchToFiber(c->app_fiber);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
my_context_init(struct my_context *c, size_t stack_size)
|
||||
{
|
||||
bzero(c, sizeof(*c));
|
||||
c->lib_fiber= CreateFiber(stack_size, my_context_trampoline, c);
|
||||
if (c->lib_fiber)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
my_context_destroy(struct my_context *c)
|
||||
{
|
||||
DBUG_FREE_CODE_STATE(&c->dbug_state);
|
||||
if (c->lib_fiber)
|
||||
{
|
||||
DeleteFiber(c->lib_fiber);
|
||||
c->lib_fiber= NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
my_context_spawn(struct my_context *c, void (*f)(void *), void *d)
|
||||
{
|
||||
void *current_fiber;
|
||||
c->user_func= f;
|
||||
c->user_arg= d;
|
||||
/*
|
||||
This seems to be a common trick to run ConvertThreadToFiber() only on the
|
||||
first occurence in a thread, in a way that works on multiple Windows
|
||||
versions.
|
||||
*/
|
||||
current_fiber= GetCurrentFiber();
|
||||
if (current_fiber == NULL || current_fiber == (void *)0x1e00)
|
||||
current_fiber= ConvertThreadToFiber(c);
|
||||
c->app_fiber= current_fiber;
|
||||
DBUG_SWAP_CODE_STATE(&c->dbug_state);
|
||||
SwitchToFiber(c->lib_fiber);
|
||||
DBUG_SWAP_CODE_STATE(&c->dbug_state);
|
||||
return c->return_value;
|
||||
}
|
||||
|
||||
int
|
||||
my_context_continue(struct my_context *c)
|
||||
{
|
||||
DBUG_SWAP_CODE_STATE(&c->dbug_state);
|
||||
SwitchToFiber(c->lib_fiber);
|
||||
DBUG_SWAP_CODE_STATE(&c->dbug_state);
|
||||
return c->return_value;
|
||||
}
|
||||
|
||||
#endif /* MY_CONTEXT_USE_WIN32_FIBERS */
|
||||
|
||||
#ifdef MY_CONTEXT_DISABLE
|
||||
int
|
||||
my_context_continue(struct my_context *c)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
my_context_spawn(struct my_context *c, void (*f)(void *), void *d)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
my_context_yield(struct my_context *c)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
my_context_init(struct my_context *c, size_t stack_size)
|
||||
{
|
||||
return -1; /* Out of memory */
|
||||
}
|
||||
|
||||
void
|
||||
my_context_destroy(struct my_context *c)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
31
module/Vendor/MDBC/libmariadb/my_div.c
vendored
Normal file
31
module/Vendor/MDBC/libmariadb/my_div.c
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
|
||||
my_string my_filename(File fd)
|
||||
{
|
||||
DBUG_ENTER("my_filename");
|
||||
if (fd >= MY_NFILE)
|
||||
DBUG_RETURN((char*) "UNKNOWN");
|
||||
if (fd >= 0 && my_file_info[fd].type != UNOPEN)
|
||||
{
|
||||
DBUG_RETURN(my_file_info[fd].name);
|
||||
}
|
||||
else
|
||||
DBUG_RETURN((char*) "UNOPENED"); /* Debug message */
|
||||
}
|
124
module/Vendor/MDBC/libmariadb/my_error.c
vendored
Normal file
124
module/Vendor/MDBC/libmariadb/my_error.c
vendored
Normal file
@ -0,0 +1,124 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include "mysys_err.h"
|
||||
#include <m_string.h>
|
||||
#include <stdarg.h>
|
||||
#include <m_ctype.h>
|
||||
|
||||
/* Define some external variables for error handling */
|
||||
|
||||
const char ** NEAR my_errmsg[MAXMAPS]={0,0,0,0};
|
||||
char NEAR errbuff[NRERRBUFFS][ERRMSGSIZE];
|
||||
|
||||
/* Error message to user */
|
||||
/*VARARGS2*/
|
||||
|
||||
int my_error(int nr,myf MyFlags, ...)
|
||||
{
|
||||
va_list ap;
|
||||
uint olen, plen;
|
||||
reg1 const char *tpos;
|
||||
reg2 char *endpos;
|
||||
char * par;
|
||||
char ebuff[ERRMSGSIZE+20];
|
||||
DBUG_ENTER("my_error");
|
||||
|
||||
va_start(ap,MyFlags);
|
||||
DBUG_PRINT("my", ("nr: %d MyFlags: %d errno: %d", nr, MyFlags, errno));
|
||||
|
||||
if (nr / ERRMOD == GLOB && my_errmsg[GLOB] == 0)
|
||||
init_glob_errs();
|
||||
|
||||
olen=(uint) strlen(tpos=my_errmsg[nr / ERRMOD][nr % ERRMOD - EE_FIRSTERROR]);
|
||||
endpos=ebuff;
|
||||
|
||||
while (*tpos)
|
||||
{
|
||||
if (tpos[0] != '%')
|
||||
{
|
||||
*endpos++= *tpos++; /* Copy ordinary char */
|
||||
olen++;
|
||||
continue;
|
||||
}
|
||||
if (*++tpos == '%') /* test if %% */
|
||||
{
|
||||
olen--;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Skipp if max size is used (to be compatible with printf) */
|
||||
while (isdigit(*tpos) || *tpos == '.' || *tpos == '-')
|
||||
tpos++;
|
||||
if (*tpos == 'l') /* Skipp 'l' argument */
|
||||
tpos++;
|
||||
if (*tpos == 's') /* String parameter */
|
||||
{
|
||||
par = va_arg(ap, char *);
|
||||
plen = (uint) strlen(par);
|
||||
if (olen + plen < ERRMSGSIZE+2) /* Replace if possible */
|
||||
{
|
||||
endpos=strmov(endpos,par);
|
||||
tpos++;
|
||||
olen+=plen-2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (*tpos == 'd' || *tpos == 'u') /* Integer parameter */
|
||||
{
|
||||
register int iarg;
|
||||
iarg = va_arg(ap, int);
|
||||
if (*tpos == 'd')
|
||||
plen= (uint) (int2str((long) iarg,endpos, -10) - endpos);
|
||||
else
|
||||
plen= (uint) (int2str((long) (uint) iarg,endpos,10)- endpos);
|
||||
if (olen + plen < ERRMSGSIZE+2) /* Replace parameter if possible */
|
||||
{
|
||||
endpos+=plen;
|
||||
tpos++;
|
||||
olen+=plen-2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
*endpos++='%'; /* % used as % or unknown code */
|
||||
}
|
||||
*endpos='\0'; /* End of errmessage */
|
||||
va_end(ap);
|
||||
DBUG_RETURN((*error_handler_hook)(nr, ebuff, MyFlags));
|
||||
}
|
||||
|
||||
/* Error as printf */
|
||||
|
||||
int my_printf_error (uint error, const char *format, myf MyFlags, ...)
|
||||
{
|
||||
va_list args;
|
||||
char ebuff[ERRMSGSIZE+20];
|
||||
|
||||
va_start(args,MyFlags);
|
||||
(void) vsprintf (ebuff,format,args);
|
||||
va_end(args);
|
||||
return (*error_handler_hook)(error, ebuff, MyFlags);
|
||||
}
|
||||
|
||||
/* Give message using error_handler_hook */
|
||||
|
||||
int my_message(uint error, const char *str, register myf MyFlags)
|
||||
{
|
||||
return (*error_handler_hook)(error, str, MyFlags);
|
||||
}
|
178
module/Vendor/MDBC/libmariadb/my_fopen.c
vendored
Normal file
178
module/Vendor/MDBC/libmariadb/my_fopen.c
vendored
Normal file
@ -0,0 +1,178 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include "my_static.h"
|
||||
#include <errno.h>
|
||||
#include "mysys_err.h"
|
||||
|
||||
static void make_ftype(my_string to,int flag);
|
||||
|
||||
/* Open a file as stream */
|
||||
|
||||
FILE *my_fopen(const char *FileName, int Flags, myf MyFlags)
|
||||
/* Path-name of file */
|
||||
/* Read | write .. */
|
||||
/* Special flags */
|
||||
{
|
||||
FILE *fd;
|
||||
char type[5];
|
||||
DBUG_ENTER("my_fopen");
|
||||
DBUG_PRINT("my",("Name: '%s' Flags: %d MyFlags: %d",
|
||||
FileName, Flags, MyFlags));
|
||||
|
||||
make_ftype(type,Flags);
|
||||
#ifdef _WIN32
|
||||
if (fopen_s(&fd, FileName, type) == 0)
|
||||
#else
|
||||
if ((fd = fopen(FileName, type)) != 0)
|
||||
#endif
|
||||
{
|
||||
/*
|
||||
The test works if MY_NFILE < 128. The problem is that fileno() is char
|
||||
on some OS (SUNOS). Actually the filename save isn't that important
|
||||
so we can ignore if this doesn't work.
|
||||
*/
|
||||
if ((uint) fileno(fd) >= MY_NFILE)
|
||||
{
|
||||
thread_safe_increment(my_stream_opened,&THR_LOCK_open);
|
||||
DBUG_RETURN(fd); /* safeguard */
|
||||
}
|
||||
pthread_mutex_lock(&THR_LOCK_open);
|
||||
if ((my_file_info[fileno(fd)].name = (char*)
|
||||
my_strdup(FileName,MyFlags)))
|
||||
{
|
||||
my_stream_opened++;
|
||||
my_file_info[fileno(fd)].type = STREAM_BY_FOPEN;
|
||||
pthread_mutex_unlock(&THR_LOCK_open);
|
||||
DBUG_PRINT("exit",("stream: %lx",fd));
|
||||
DBUG_RETURN(fd);
|
||||
}
|
||||
pthread_mutex_unlock(&THR_LOCK_open);
|
||||
(void) my_fclose(fd,MyFlags);
|
||||
my_errno=ENOMEM;
|
||||
}
|
||||
else
|
||||
my_errno=errno;
|
||||
DBUG_PRINT("error",("Got error %d on open",my_errno));
|
||||
if (MyFlags & (MY_FFNF | MY_FAE | MY_WME))
|
||||
my_error((Flags & O_RDONLY) || (Flags == O_RDONLY ) ? EE_FILENOTFOUND :
|
||||
EE_CANTCREATEFILE,
|
||||
MYF(ME_BELL+ME_WAITTANG), FileName,my_errno);
|
||||
DBUG_RETURN((FILE*) 0);
|
||||
} /* my_fopen */
|
||||
|
||||
|
||||
/* Close a stream */
|
||||
|
||||
int my_fclose(FILE *fd, myf MyFlags)
|
||||
{
|
||||
int err,file;
|
||||
DBUG_ENTER("my_fclose");
|
||||
DBUG_PRINT("my",("stream: %lx MyFlags: %d",fd, MyFlags));
|
||||
|
||||
pthread_mutex_lock(&THR_LOCK_open);
|
||||
file=fileno(fd);
|
||||
if ((err = fclose(fd)) < 0)
|
||||
{
|
||||
my_errno=errno;
|
||||
if (MyFlags & (MY_FAE | MY_WME))
|
||||
my_error(EE_BADCLOSE, MYF(ME_BELL+ME_WAITTANG),
|
||||
my_filename(file),errno);
|
||||
}
|
||||
else
|
||||
my_stream_opened--;
|
||||
if ((uint) file < MY_NFILE && my_file_info[file].type != UNOPEN)
|
||||
{
|
||||
my_file_info[file].type = UNOPEN;
|
||||
my_free(my_file_info[file].name);
|
||||
}
|
||||
pthread_mutex_unlock(&THR_LOCK_open);
|
||||
DBUG_RETURN(err);
|
||||
} /* my_fclose */
|
||||
|
||||
|
||||
/* Make a stream out of a file handle */
|
||||
/* Name may be 0 */
|
||||
|
||||
FILE *my_fdopen(File Filedes, const char *name, int Flags, myf MyFlags)
|
||||
{
|
||||
FILE *fd;
|
||||
char type[5];
|
||||
DBUG_ENTER("my_fdopen");
|
||||
DBUG_PRINT("my",("Fd: %d Flags: %d MyFlags: %d",
|
||||
Filedes, Flags, MyFlags));
|
||||
|
||||
make_ftype(type,Flags);
|
||||
if ((fd = fdopen(Filedes, type)) == 0)
|
||||
{
|
||||
my_errno=errno;
|
||||
if (MyFlags & (MY_FAE | MY_WME))
|
||||
my_error(EE_CANT_OPEN_STREAM, MYF(ME_BELL+ME_WAITTANG),errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
pthread_mutex_lock(&THR_LOCK_open);
|
||||
my_stream_opened++;
|
||||
if (Filedes < MY_NFILE)
|
||||
{
|
||||
if (my_file_info[Filedes].type != UNOPEN)
|
||||
{
|
||||
my_file_opened--; /* File is opened with my_open ! */
|
||||
}
|
||||
else
|
||||
{
|
||||
my_file_info[Filedes].name= my_strdup(name,MyFlags);
|
||||
}
|
||||
my_file_info[Filedes].type = STREAM_BY_FDOPEN;
|
||||
}
|
||||
pthread_mutex_unlock(&THR_LOCK_open);
|
||||
}
|
||||
|
||||
DBUG_PRINT("exit",("stream: %lx",fd));
|
||||
DBUG_RETURN(fd);
|
||||
} /* my_fdopen */
|
||||
|
||||
|
||||
/* Make a filehandler-open-typestring from ordinary inputflags */
|
||||
|
||||
static void make_ftype(register my_string to, register int flag)
|
||||
{
|
||||
#if FILE_BINARY /* If we have binary-files */
|
||||
reg3 int org_flag=flag;
|
||||
#endif
|
||||
flag&= ~FILE_BINARY; /* remove binary bit */
|
||||
if (flag == O_RDONLY)
|
||||
*to++= 'r';
|
||||
else if (flag == O_WRONLY)
|
||||
*to++= 'w';
|
||||
else
|
||||
{ /* Add '+' after theese */
|
||||
if (flag == O_RDWR)
|
||||
*to++= 'r';
|
||||
else if (flag & O_APPEND)
|
||||
*to++= 'a';
|
||||
else
|
||||
*to++= 'w'; /* Create file */
|
||||
*to++= '+';
|
||||
}
|
||||
#if FILE_BINARY /* If we have binary-files */
|
||||
if (org_flag & FILE_BINARY)
|
||||
*to++='b';
|
||||
#endif
|
||||
*to='\0';
|
||||
} /* make_ftype */
|
171
module/Vendor/MDBC/libmariadb/my_fstream.c
vendored
Normal file
171
module/Vendor/MDBC/libmariadb/my_fstream.c
vendored
Normal file
@ -0,0 +1,171 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* USE_MY_STREAM isn't set because we can't thrust my_fclose! */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include "mysys_err.h"
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef HAVE_FSEEKO
|
||||
#undef ftell
|
||||
#undef fseek
|
||||
#define ftell(A) ftello(A)
|
||||
#define fseek(A,B,C) fseeko((A),(B),(C))
|
||||
#endif
|
||||
|
||||
/* Read a chunk of bytes from a file */
|
||||
/* Returns (uint) -1 if error as my_read() */
|
||||
|
||||
uint my_fread(FILE *stream, unsigned char *Buffer, uint Count, myf MyFlags)
|
||||
/* File descriptor */
|
||||
/* Buffer must be at least count bytes */
|
||||
/* Max number of bytes returnd */
|
||||
/* Flags on what to do on error */
|
||||
{
|
||||
uint readbytes;
|
||||
DBUG_ENTER("my_fread");
|
||||
DBUG_PRINT("my",("stream: %lx Buffer: %lx Count: %u MyFlags: %d",
|
||||
stream, Buffer, Count, MyFlags));
|
||||
|
||||
if ((readbytes = (uint) fread(Buffer,sizeof(char),(size_t) Count,stream))
|
||||
!= Count)
|
||||
{
|
||||
DBUG_PRINT("error",("Read only %d bytes",readbytes));
|
||||
if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
|
||||
{
|
||||
if (ferror(stream))
|
||||
my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG),
|
||||
my_filename(fileno(stream)),errno);
|
||||
else
|
||||
if (MyFlags & (MY_NABP | MY_FNABP))
|
||||
my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG),
|
||||
my_filename(fileno(stream)),errno);
|
||||
}
|
||||
my_errno=errno ? errno : -1;
|
||||
if (ferror(stream) || MyFlags & (MY_NABP | MY_FNABP))
|
||||
DBUG_RETURN((uint) -1); /* Return with error */
|
||||
}
|
||||
if (MyFlags & (MY_NABP | MY_FNABP))
|
||||
DBUG_RETURN(0); /* Read ok */
|
||||
DBUG_RETURN(readbytes);
|
||||
} /* my_fread */
|
||||
|
||||
|
||||
/*
|
||||
** Write a chunk of bytes to a stream
|
||||
** Returns (uint) -1 if error as my_write()
|
||||
** Does retries if interrupted
|
||||
*/
|
||||
|
||||
uint my_fwrite(FILE *stream, const unsigned char *Buffer, uint Count, myf MyFlags)
|
||||
{
|
||||
uint writenbytes=0;
|
||||
off_t seekptr;
|
||||
#if !defined(NO_BACKGROUND) && defined(USE_MY_STREAM)
|
||||
uint errors;
|
||||
#endif
|
||||
DBUG_ENTER("my_fwrite");
|
||||
DBUG_PRINT("my",("stream: %lx Buffer: %lx Count: %u MyFlags: %d",
|
||||
stream, Buffer, Count, MyFlags));
|
||||
|
||||
#if !defined(NO_BACKGROUND) && defined(USE_MY_STREAM)
|
||||
errors=0;
|
||||
#endif
|
||||
seekptr=ftell(stream);
|
||||
for (;;)
|
||||
{
|
||||
uint writen;
|
||||
if ((writen = (uint) fwrite((char*) Buffer,sizeof(char),
|
||||
(size_t) Count, stream)) != Count)
|
||||
{
|
||||
DBUG_PRINT("error",("Write only %d bytes",writenbytes));
|
||||
my_errno=errno;
|
||||
if (writen != (uint) -1)
|
||||
{
|
||||
seekptr+=writen;
|
||||
Buffer+=writen;
|
||||
writenbytes+=writen;
|
||||
Count-=writen;
|
||||
}
|
||||
#ifdef EINTR
|
||||
if (errno == EINTR)
|
||||
{
|
||||
VOID(my_fseek(stream,seekptr,MY_SEEK_SET,MYF(0)));
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
#if !defined(NO_BACKGROUND) && defined(USE_MY_STREAM)
|
||||
#ifdef THREAD
|
||||
if (my_thread_var->abort)
|
||||
MyFlags&= ~ MY_WAIT_IF_FULL; /* End if aborted by user */
|
||||
#endif
|
||||
if (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));
|
||||
sleep(MY_WAIT_FOR_USER_TO_FIX_PANIC);
|
||||
VOID(my_fseek(stream,seekptr,MY_SEEK_SET,MYF(0)));
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (ferror(stream) || (MyFlags & (MY_NABP | MY_FNABP)))
|
||||
{
|
||||
if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
|
||||
{
|
||||
my_error(EE_WRITE, MYF(ME_BELL+ME_WAITTANG),
|
||||
my_filename(fileno(stream)),errno);
|
||||
}
|
||||
writenbytes=(uint) -1; /* Return that we got error */
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (MyFlags & (MY_NABP | MY_FNABP))
|
||||
writenbytes=0; /* Everything OK */
|
||||
else
|
||||
writenbytes+=writen;
|
||||
break;
|
||||
}
|
||||
DBUG_RETURN(writenbytes);
|
||||
} /* my_fwrite */
|
||||
|
||||
/* Seek to position in file */
|
||||
/* ARGSUSED */
|
||||
|
||||
my_off_t my_fseek(FILE *stream, my_off_t pos, int whence, myf MyFlags)
|
||||
{
|
||||
DBUG_ENTER("my_fseek");
|
||||
DBUG_PRINT("my",("stream: %lx pos: %lu whence: %d MyFlags: %d",
|
||||
stream, pos, whence, MyFlags));
|
||||
DBUG_RETURN(fseek(stream, (off_t) pos, whence) ?
|
||||
MY_FILEPOS_ERROR : (my_off_t) ftell(stream));
|
||||
} /* my_seek */
|
||||
|
||||
|
||||
/* Tell current position of file */
|
||||
/* ARGSUSED */
|
||||
|
||||
my_off_t my_ftell(FILE *stream, myf MyFlags)
|
||||
{
|
||||
off_t pos;
|
||||
DBUG_ENTER("my_ftell");
|
||||
DBUG_PRINT("my",("stream: %lx MyFlags: %d",stream, MyFlags));
|
||||
pos=ftell(stream);
|
||||
DBUG_PRINT("exit",("ftell: %lu",(ulong) pos));
|
||||
DBUG_RETURN((my_off_t) pos);
|
||||
} /* my_ftell */
|
202
module/Vendor/MDBC/libmariadb/my_getwd.c
vendored
Normal file
202
module/Vendor/MDBC/libmariadb/my_getwd.c
vendored
Normal file
@ -0,0 +1,202 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* my_setwd() and my_getwd() works with intern_filenames !! */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include <m_string.h>
|
||||
#include "mysys_err.h"
|
||||
#ifdef HAVE_GETWD
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
#if defined(MSDOS) || defined(_WIN32)
|
||||
#include <m_ctype.h>
|
||||
#include <dos.h>
|
||||
#include <direct.h>
|
||||
#endif
|
||||
#if defined(OS2)
|
||||
#include <direct.h>
|
||||
#endif
|
||||
|
||||
#ifdef __EMX__
|
||||
// chdir2 support also drive change
|
||||
#define chdir _chdir2
|
||||
#endif
|
||||
|
||||
/* Gets current working directory in buff. Directory is allways ended
|
||||
with FN_LIBCHAR */
|
||||
/* One must pass a buffer to my_getwd. One can allways use
|
||||
curr_dir[] */
|
||||
|
||||
int my_getwd(my_string buf, uint size, myf MyFlags)
|
||||
{
|
||||
my_string pos;
|
||||
DBUG_ENTER("my_getwd");
|
||||
DBUG_PRINT("my",("buf: %lx size: %d MyFlags %d", buf,size,MyFlags));
|
||||
|
||||
#if ! defined(MSDOS)
|
||||
if (curr_dir[0]) /* Current pos is saved here */
|
||||
VOID(strmake(buf,&curr_dir[0],size-1));
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#if defined(HAVE_GETCWD)
|
||||
#ifdef _WIN32
|
||||
if (!(_getcwd(buf,size-2)) && MyFlags & MY_WME)
|
||||
#else
|
||||
if (!(getcwd(buf,size-2)) && MyFlags & MY_WME)
|
||||
#endif
|
||||
{
|
||||
my_errno=errno;
|
||||
my_error(EE_GETWD,MYF(ME_BELL+ME_WAITTANG),errno);
|
||||
return(-1);
|
||||
}
|
||||
#elif defined(HAVE_GETWD)
|
||||
{
|
||||
char pathname[MAXPATHLEN];
|
||||
getwd(pathname);
|
||||
strmake(buf,pathname,size-1);
|
||||
}
|
||||
#elif defined(VMS)
|
||||
if (!getcwd(buf,size-2,1) && MyFlags & MY_WME)
|
||||
{
|
||||
my_errno=errno;
|
||||
my_error(EE_GETWD,MYF(ME_BELL+ME_WAITTANG),errno);
|
||||
return(-1);
|
||||
}
|
||||
intern_filename(buf,buf);
|
||||
#else
|
||||
#error "No way to get current directory"
|
||||
#endif
|
||||
if (*((pos=strend(buf))-1) != FN_LIBCHAR) /* End with FN_LIBCHAR */
|
||||
{
|
||||
pos[0]= FN_LIBCHAR;
|
||||
pos[1]=0;
|
||||
}
|
||||
(void) strmake(&curr_dir[0],buf,(size_s) (FN_REFLEN-1));
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
} /* my_getwd */
|
||||
|
||||
|
||||
/* Set new working directory */
|
||||
|
||||
int my_setwd(const char *dir, myf MyFlags)
|
||||
{
|
||||
int res;
|
||||
size_s length;
|
||||
my_string start,pos;
|
||||
#if defined(VMS) || defined(MSDOS) || defined(OS2)
|
||||
char buff[FN_REFLEN];
|
||||
#endif
|
||||
DBUG_ENTER("my_setwd");
|
||||
DBUG_PRINT("my",("dir: '%s' MyFlags %d", dir, MyFlags));
|
||||
|
||||
start=(my_string) dir;
|
||||
#if defined(MSDOS) || defined(OS2) /* OS2/MSDOS chdir can't change drive */
|
||||
#if !defined(_DDL) && !defined(WIN32)
|
||||
if ((pos=(char*) strchr(dir,FN_DEVCHAR)) != 0)
|
||||
{
|
||||
uint drive,drives;
|
||||
|
||||
pos++; /* Skipp FN_DEVCHAR */
|
||||
drive=(uint) (toupper(dir[0])-'A'+1); drives= (uint) -1;
|
||||
if ((pos-(byte*) dir) == 2 && drive > 0 && drive < 32)
|
||||
{
|
||||
#ifdef OS2
|
||||
_chdrive(drive);
|
||||
drives = _getdrive();
|
||||
#else
|
||||
_dos_setdrive(drive,&drives);
|
||||
_dos_getdrive(&drives);
|
||||
#endif
|
||||
}
|
||||
if (drive != drives)
|
||||
{
|
||||
*pos='\0'; /* Dir is now only drive */
|
||||
my_errno=errno;
|
||||
my_error(EE_SETWD,MYF(ME_BELL+ME_WAITTANG),dir,ENOENT);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
dir=pos; /* drive changed, change now path */
|
||||
}
|
||||
#endif
|
||||
if (*((pos=strend(dir)-1)) == FN_LIBCHAR && pos != dir)
|
||||
{
|
||||
strmov(buff,dir)[-1]=0; /* Remove last '/' */
|
||||
dir=buff;
|
||||
}
|
||||
#endif /* MSDOS*/
|
||||
if (! dir[0] || (dir[0] == FN_LIBCHAR && dir[1] == 0))
|
||||
dir=FN_ROOTDIR;
|
||||
#ifdef VMS
|
||||
{
|
||||
pos=strmov(buff,dir);
|
||||
if (pos[-1] != FN_LIBCHAR)
|
||||
{
|
||||
pos[0]=FN_LIBCHAR; /* Mark as directory */
|
||||
pos[1]=0;
|
||||
}
|
||||
system_filename(buff,buff); /* Change to VMS format */
|
||||
dir=buff;
|
||||
}
|
||||
#endif /* VMS */
|
||||
#ifdef _WIN32
|
||||
if ((res=_chdir((char*) dir)) != 0)
|
||||
#else
|
||||
if ((res=chdir((char*) dir)) != 0)
|
||||
#endif
|
||||
{
|
||||
my_errno=errno;
|
||||
if (MyFlags & MY_WME)
|
||||
my_error(EE_SETWD,MYF(ME_BELL+ME_WAITTANG),start,errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (test_if_hard_path(start))
|
||||
{ /* Hard pathname */
|
||||
pos=strmake(&curr_dir[0],start,(size_s) FN_REFLEN-1);
|
||||
if (pos[-1] != FN_LIBCHAR)
|
||||
{
|
||||
length=(uint) (pos-(char*) curr_dir);
|
||||
curr_dir[length]=FN_LIBCHAR; /* must end with '/' */
|
||||
curr_dir[length+1]='\0';
|
||||
}
|
||||
}
|
||||
else
|
||||
curr_dir[0]='\0'; /* Don't save name */
|
||||
}
|
||||
DBUG_RETURN(res);
|
||||
} /* my_setwd */
|
||||
|
||||
|
||||
|
||||
/* Test if hard pathname */
|
||||
/* Returns 1 if dirname is a hard path */
|
||||
|
||||
int test_if_hard_path(register const char *dir_name)
|
||||
{
|
||||
if (dir_name[0] == FN_HOMELIB && dir_name[1] == FN_LIBCHAR)
|
||||
return (home_dir != NullS && test_if_hard_path(home_dir));
|
||||
if (dir_name[0] == FN_LIBCHAR)
|
||||
return (TRUE);
|
||||
#ifdef FN_DEVCHAR
|
||||
return (strchr(dir_name,FN_DEVCHAR) != 0);
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
} /* test_if_hard_path */
|
273
module/Vendor/MDBC/libmariadb/my_init.c
vendored
Normal file
273
module/Vendor/MDBC/libmariadb/my_init.c
vendored
Normal file
@ -0,0 +1,273 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include "my_static.h"
|
||||
#include "mysys_err.h"
|
||||
#include "m_ctype.h"
|
||||
#include <m_string.h>
|
||||
#include <m_ctype.h>
|
||||
#ifdef HAVE_GETRUSAGE
|
||||
#include <sys/resource.h>
|
||||
/* extern int getrusage(int, struct rusage *); */
|
||||
#endif
|
||||
#include <signal.h>
|
||||
#ifdef VMS
|
||||
#include <my_static.c>
|
||||
#include <m_ctype.h>
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
#include <locale.h>
|
||||
#include <crtdbg.h>
|
||||
#endif
|
||||
my_bool have_tcpip=0;
|
||||
static void my_win_init(void);
|
||||
static my_bool win32_have_tcpip(void);
|
||||
static my_bool win32_init_tcp_ip();
|
||||
#else
|
||||
#define my_win_init()
|
||||
#endif
|
||||
|
||||
my_bool my_init_done=0;
|
||||
|
||||
|
||||
|
||||
static ulong atoi_octal(const char *str)
|
||||
{
|
||||
long int tmp;
|
||||
while (*str && isspace(*str))
|
||||
str++;
|
||||
str2int(str,
|
||||
(*str == '0' ? 8 : 10), /* Octalt or decimalt */
|
||||
0, INT_MAX, &tmp);
|
||||
return (ulong) tmp;
|
||||
}
|
||||
|
||||
|
||||
/* Init my_sys functions and my_sys variabels */
|
||||
|
||||
void my_init(void)
|
||||
{
|
||||
my_string str;
|
||||
if (my_init_done)
|
||||
return;
|
||||
my_init_done=1;
|
||||
#ifdef THREAD
|
||||
#if defined(HAVE_PTHREAD_INIT)
|
||||
pthread_init(); /* Must be called before DBUG_ENTER */
|
||||
#endif
|
||||
my_thread_global_init();
|
||||
#ifndef _WIN32
|
||||
sigfillset(&my_signals); /* signals blocked by mf_brkhant */
|
||||
#endif
|
||||
#endif /* THREAD */
|
||||
#ifdef UNIXWARE_7
|
||||
(void) isatty(0); /* Go around connect() bug in UW7 */
|
||||
#endif
|
||||
{
|
||||
DBUG_ENTER("my_init");
|
||||
DBUG_PROCESS(my_progname ? my_progname : (char*) "unknown");
|
||||
if (!home_dir)
|
||||
{ /* Don't initialize twice */
|
||||
if ((home_dir=getenv("HOME")) != 0)
|
||||
home_dir=intern_filename(home_dir_buff,home_dir);
|
||||
#ifndef VMS
|
||||
/* Default creation of new files */
|
||||
if ((str=getenv("UMASK")) != 0)
|
||||
my_umask=(int) (atoi_octal(str) | 0600);
|
||||
/* Default creation of new dir's */
|
||||
if ((str=getenv("UMASK_DIR")) != 0)
|
||||
my_umask_dir=(int) (atoi_octal(str) | 0700);
|
||||
#endif
|
||||
#ifdef VMS
|
||||
init_ctype(); /* Stupid linker don't link _ctype.c */
|
||||
#endif
|
||||
DBUG_PRINT("exit",("home: '%s'",home_dir));
|
||||
}
|
||||
#ifdef _WIN32
|
||||
my_win_init();
|
||||
#endif
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
} /* my_init */
|
||||
|
||||
|
||||
/* End my_sys */
|
||||
|
||||
void my_end(int infoflag)
|
||||
{
|
||||
FILE *info_file;
|
||||
if (!(info_file=DBUG_FILE))
|
||||
info_file=stderr;
|
||||
if (infoflag & MY_CHECK_ERROR || info_file != stderr)
|
||||
{ /* Test if some file is left open */
|
||||
if (my_file_opened | my_stream_opened)
|
||||
{
|
||||
sprintf(errbuff[0],EE(EE_OPEN_WARNING),my_file_opened,my_stream_opened);
|
||||
(void) my_message_no_curses(EE_OPEN_WARNING,errbuff[0],ME_BELL);
|
||||
DBUG_PRINT("error",("%s",errbuff[0]));
|
||||
}
|
||||
}
|
||||
if (infoflag & MY_GIVE_INFO || info_file != stderr)
|
||||
{
|
||||
#ifdef HAVE_GETRUSAGE
|
||||
struct rusage rus;
|
||||
if (!getrusage(RUSAGE_SELF, &rus))
|
||||
fprintf(info_file,"\n\
|
||||
User time %.2f, System time %.2f\n\
|
||||
Maximum resident set size %ld, Integral resident set size %ld\n\
|
||||
Non-physical pagefaults %ld, Physical pagefaults %ld, Swaps %ld\n\
|
||||
Blocks in %ld out %ld, Messages in %ld out %ld, Signals %ld\n\
|
||||
Voluntary context switches %ld, Involuntary context switches %ld\n",
|
||||
(rus.ru_utime.tv_sec * SCALE_SEC +
|
||||
rus.ru_utime.tv_usec / SCALE_USEC) / 100.0,
|
||||
(rus.ru_stime.tv_sec * SCALE_SEC +
|
||||
rus.ru_stime.tv_usec / SCALE_USEC) / 100.0,
|
||||
rus.ru_maxrss, rus.ru_idrss,
|
||||
rus.ru_minflt, rus.ru_majflt,
|
||||
rus.ru_nswap, rus.ru_inblock, rus.ru_oublock,
|
||||
rus.ru_msgsnd, rus.ru_msgrcv, rus.ru_nsignals,
|
||||
rus.ru_nvcsw, rus.ru_nivcsw);
|
||||
#endif
|
||||
#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(_WIN32) && defined(_MSC_VER)
|
||||
_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
|
||||
_CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDERR );
|
||||
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
|
||||
_CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDERR );
|
||||
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
|
||||
_CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDERR );
|
||||
_CrtCheckMemory();
|
||||
_CrtDumpMemoryLeaks();
|
||||
#endif
|
||||
}
|
||||
#ifdef THREAD
|
||||
pthread_mutex_destroy(&THR_LOCK_malloc);
|
||||
pthread_mutex_destroy(&THR_LOCK_open);
|
||||
pthread_mutex_destroy(&THR_LOCK_net);
|
||||
DBUG_END(); /* Must be done before my_thread_end */
|
||||
my_thread_end();
|
||||
my_thread_global_end();
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
if (have_tcpip);
|
||||
WSACleanup( );
|
||||
#endif /* _WIN32 */
|
||||
my_init_done=0;
|
||||
} /* my_end */
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/*
|
||||
This code is specially for running MySQL, but it should work in
|
||||
other cases too.
|
||||
|
||||
Inizializzazione delle variabili d'ambiente per Win a 32 bit.
|
||||
|
||||
Vengono inserite nelle variabili d'ambiente (utilizzando cosi'
|
||||
le funzioni getenv e putenv) i valori presenti nelle chiavi
|
||||
del file di registro:
|
||||
|
||||
HKEY_LOCAL_MACHINE\software\MySQL
|
||||
|
||||
Se la kiave non esiste nonn inserisce nessun valore
|
||||
*/
|
||||
|
||||
/* Crea la stringa d'ambiente */
|
||||
|
||||
void setEnvString(char *ret, const char *name, const char *value)
|
||||
{
|
||||
DBUG_ENTER("setEnvString");
|
||||
strxmov(ret, name,"=",value,NullS);
|
||||
DBUG_VOID_RETURN ;
|
||||
}
|
||||
|
||||
static void my_win_init(void)
|
||||
{
|
||||
DBUG_ENTER("my_win_init");
|
||||
win32_init_tcp_ip();
|
||||
DBUG_VOID_RETURN ;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
** Name: CheckForTcpip| Desc: checks if tcpip has been installed on system
|
||||
** According to Microsoft Developers documentation the first registry
|
||||
** entry should be enough to check if TCP/IP is installed, but as expected
|
||||
** this doesn't work on all Win32 machines :(
|
||||
------------------------------------------------------------------*/
|
||||
|
||||
#define TCPIPKEY "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"
|
||||
#define WINSOCK2KEY "SYSTEM\\CurrentControlSet\\Services\\Winsock2\\Parameters"
|
||||
#define WINSOCKKEY "SYSTEM\\CurrentControlSet\\Services\\Winsock\\Parameters"
|
||||
|
||||
static my_bool win32_have_tcpip(void)
|
||||
{
|
||||
HKEY hTcpipRegKey;
|
||||
if (RegOpenKeyEx ( HKEY_LOCAL_MACHINE, TCPIPKEY, 0, KEY_READ,
|
||||
&hTcpipRegKey) != ERROR_SUCCESS)
|
||||
{
|
||||
if (RegOpenKeyEx ( HKEY_LOCAL_MACHINE, WINSOCK2KEY, 0, KEY_READ,
|
||||
&hTcpipRegKey) != ERROR_SUCCESS)
|
||||
{
|
||||
if (RegOpenKeyEx ( HKEY_LOCAL_MACHINE, WINSOCKKEY, 0, KEY_READ,
|
||||
&hTcpipRegKey) != ERROR_SUCCESS)
|
||||
if (!getenv("HAVE_TCPIP") || have_tcpip) /* Provide a workaround */
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
RegCloseKey ( hTcpipRegKey);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static my_bool win32_init_tcp_ip()
|
||||
{
|
||||
if (win32_have_tcpip())
|
||||
{
|
||||
WORD wVersionRequested = MAKEWORD( 2, 0 );
|
||||
WSADATA wsaData;
|
||||
/* Be a good citizen: maybe another lib has already initialised
|
||||
sockets, so dont clobber them unless necessary */
|
||||
if (WSAStartup( wVersionRequested, &wsaData ))
|
||||
{
|
||||
/* Load failed, maybe because of previously loaded
|
||||
incompatible version; try again */
|
||||
WSACleanup( );
|
||||
if (!WSAStartup( wVersionRequested, &wsaData ))
|
||||
have_tcpip=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wsaData.wVersion != wVersionRequested)
|
||||
{
|
||||
/* Version is no good, try again */
|
||||
WSACleanup( );
|
||||
if (!WSAStartup( wVersionRequested, &wsaData ))
|
||||
have_tcpip=1;
|
||||
}
|
||||
else
|
||||
have_tcpip=1;
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
#endif
|
614
module/Vendor/MDBC/libmariadb/my_lib.c
vendored
Normal file
614
module/Vendor/MDBC/libmariadb/my_lib.c
vendored
Normal file
@ -0,0 +1,614 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* TODO: check for overun of memory for names. */
|
||||
/* Convert MSDOS-TIME to standar time_t */
|
||||
|
||||
#define USES_TYPES /* sys/types is included */
|
||||
#include "mysys_priv.h"
|
||||
#include <m_string.h>
|
||||
#include <my_dir.h> /* Structs used by my_dir,includes sys/types */
|
||||
#include "mysys_err.h"
|
||||
#if defined(HAVE_DIRENT_H)
|
||||
# include <dirent.h>
|
||||
# define NAMLEN(dirent) strlen((dirent)->d_name)
|
||||
#else
|
||||
#ifndef OS2
|
||||
# define dirent direct
|
||||
#endif
|
||||
# define NAMLEN(dirent) (dirent)->d_namlen
|
||||
# if defined(HAVE_SYS_NDIR_H)
|
||||
# include <sys/ndir.h>
|
||||
# endif
|
||||
# if defined(HAVE_SYS_DIR_H)
|
||||
# include <sys/dir.h>
|
||||
# endif
|
||||
# if defined(HAVE_NDIR_H)
|
||||
# include <ndir.h>
|
||||
# endif
|
||||
# if defined(MSDOS) || defined(_WIN32)
|
||||
# include <dos.h>
|
||||
# ifdef __BORLANDC__
|
||||
# include <dir.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#ifdef VMS
|
||||
#include <rms.h>
|
||||
#include <iodef.h>
|
||||
#include <descrip.h>
|
||||
#endif
|
||||
|
||||
#ifdef OS2
|
||||
#include "my_os2dirsrch.h"
|
||||
#endif
|
||||
|
||||
#if defined(THREAD) && defined(HAVE_READDIR_R)
|
||||
#define READDIR(A,B,C) ((errno=readdir_r(A,B,&C)) != 0 || !C)
|
||||
#else
|
||||
#define READDIR(A,B,C) (!(C=readdir(A)))
|
||||
#endif
|
||||
|
||||
|
||||
#define STARTSIZE ONCE_ALLOC_INIT*8 /* some mallocmargin */
|
||||
|
||||
static int comp_names(struct fileinfo *a,struct fileinfo *b);
|
||||
|
||||
|
||||
/* We need this because program don't know with malloc we used */
|
||||
|
||||
void my_dirend(MY_DIR *buffer)
|
||||
{
|
||||
DBUG_ENTER("my_dirend");
|
||||
if (buffer)
|
||||
my_free(buffer);
|
||||
DBUG_VOID_RETURN;
|
||||
} /* my_dirend */
|
||||
|
||||
|
||||
/* Compare in sort of filenames */
|
||||
|
||||
static int comp_names(struct fileinfo *a, struct fileinfo *b)
|
||||
{
|
||||
return (strcmp(a->name,b->name));
|
||||
} /* comp_names */
|
||||
|
||||
|
||||
#if !defined(MSDOS) && !defined(_WIN32)
|
||||
|
||||
MY_DIR *my_dir(const char *path, myf MyFlags)
|
||||
{
|
||||
DIR *dirp;
|
||||
struct dirent *dp;
|
||||
struct fileinfo *fnames;
|
||||
char *buffer, *obuffer, *tempptr;
|
||||
uint fcnt,i,size,firstfcnt, maxfcnt,length;
|
||||
char tmp_path[FN_REFLEN+1],*tmp_file;
|
||||
my_ptrdiff_t diff;
|
||||
bool eof;
|
||||
#ifdef THREAD
|
||||
char dirent_tmp[sizeof(struct dirent)+_POSIX_PATH_MAX+1];
|
||||
#endif
|
||||
DBUG_ENTER("my_dir");
|
||||
DBUG_PRINT("my",("path: '%s' stat: %d MyFlags: %d",path,MyFlags));
|
||||
|
||||
#if defined(THREAD) && !defined(HAVE_READDIR_R)
|
||||
pthread_mutex_lock(&THR_LOCK_open);
|
||||
#endif
|
||||
|
||||
dirp = opendir(directory_file_name(tmp_path,(my_string) path));
|
||||
size = STARTSIZE;
|
||||
if (dirp == NULL || ! (buffer = (char *) my_malloc(size, MyFlags)))
|
||||
goto error;
|
||||
|
||||
fcnt = 0;
|
||||
tmp_file=strend(tmp_path);
|
||||
firstfcnt = maxfcnt = (size - sizeof(MY_DIR)) /
|
||||
(sizeof(struct fileinfo) + FN_LEN);
|
||||
fnames= (struct fileinfo *) (buffer + sizeof(MY_DIR));
|
||||
tempptr = (char *) (fnames + maxfcnt);
|
||||
|
||||
#ifdef THREAD
|
||||
dp= (struct dirent*) dirent_tmp;
|
||||
#else
|
||||
dp=0;
|
||||
#endif
|
||||
eof=0;
|
||||
for (;;)
|
||||
{
|
||||
while (fcnt < maxfcnt &&
|
||||
!(eof= READDIR(dirp,(struct dirent*) dirent_tmp,dp)))
|
||||
{
|
||||
bzero((gptr) (fnames+fcnt),sizeof(fnames[0])); /* for purify */
|
||||
fnames[fcnt].name = tempptr;
|
||||
tempptr = strmov(tempptr,dp->d_name) + 1;
|
||||
if (MyFlags & MY_WANT_STAT)
|
||||
{
|
||||
(void)strmov(tmp_file,dp->d_name);
|
||||
(void)my_stat(tmp_path, &fnames[fcnt].mystat, MyFlags);
|
||||
}
|
||||
++fcnt;
|
||||
}
|
||||
if (eof)
|
||||
break;
|
||||
size += STARTSIZE; obuffer = buffer;
|
||||
if (!(buffer = (char *) my_realloc((gptr) buffer, size,
|
||||
MyFlags | MY_FREE_ON_ERROR)))
|
||||
goto error; /* No memory */
|
||||
length= (uint) (sizeof(struct fileinfo ) * firstfcnt);
|
||||
diff= PTR_BYTE_DIFF(buffer , obuffer) + (int) length;
|
||||
fnames= (struct fileinfo *) (buffer + sizeof(MY_DIR));
|
||||
tempptr= ADD_TO_PTR(tempptr,diff,char*);
|
||||
for (i = 0; i < maxfcnt; i++)
|
||||
fnames[i].name = ADD_TO_PTR(fnames[i].name,diff,char*);
|
||||
|
||||
/* move filenames upp a bit */
|
||||
maxfcnt += firstfcnt;
|
||||
bmove_upp(tempptr,tempptr-length,
|
||||
(uint) (tempptr- (char*) (fnames+maxfcnt)));
|
||||
}
|
||||
|
||||
(void) closedir(dirp);
|
||||
{
|
||||
MY_DIR * s = (MY_DIR *) buffer;
|
||||
s->number_off_files = (uint) fcnt;
|
||||
s->dir_entry = fnames;
|
||||
}
|
||||
if (!(MyFlags & MY_DONT_SORT))
|
||||
qsort((void *) fnames, (size_s) fcnt, sizeof(struct fileinfo),
|
||||
(qsort_cmp) comp_names);
|
||||
#if defined(THREAD) && !defined(HAVE_READDIR_R)
|
||||
pthread_mutex_unlock(&THR_LOCK_open);
|
||||
#endif
|
||||
DBUG_RETURN((MY_DIR *) buffer);
|
||||
|
||||
error:
|
||||
#if defined(THREAD) && !defined(HAVE_READDIR_R)
|
||||
pthread_mutex_unlock(&THR_LOCK_open);
|
||||
#endif
|
||||
my_errno=errno;
|
||||
if (dirp)
|
||||
(void) closedir(dirp);
|
||||
if (MyFlags & (MY_FAE+MY_WME))
|
||||
my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,my_errno);
|
||||
DBUG_RETURN((MY_DIR *) NULL);
|
||||
} /* my_dir */
|
||||
|
||||
|
||||
/*
|
||||
* Convert from directory name to filename.
|
||||
* On VMS:
|
||||
* xyzzy:[mukesh.emacs] => xyzzy:[mukesh]emacs.dir.1
|
||||
* xyzzy:[mukesh] => xyzzy:[000000]mukesh.dir.1
|
||||
* On UNIX, it's simple: just make sure there is a terminating /
|
||||
|
||||
* Returns pointer to dst;
|
||||
*/
|
||||
|
||||
my_string directory_file_name (my_string dst, const char *src)
|
||||
{
|
||||
#ifndef VMS
|
||||
|
||||
/* Process as Unix format: just remove test the final slash. */
|
||||
|
||||
my_string end;
|
||||
|
||||
if (src[0] == 0)
|
||||
src= (char*) "."; /* Use empty as current */
|
||||
end=strmov(dst, src);
|
||||
if (end[-1] != FN_LIBCHAR)
|
||||
{
|
||||
end[0]=FN_LIBCHAR; /* Add last '/' */
|
||||
end[1]='\0';
|
||||
}
|
||||
return dst;
|
||||
|
||||
#else /* VMS */
|
||||
|
||||
long slen;
|
||||
long rlen;
|
||||
my_string ptr, rptr;
|
||||
char bracket;
|
||||
struct FAB fab = cc$rms_fab;
|
||||
struct NAM nam = cc$rms_nam;
|
||||
char esa[NAM$C_MAXRSS];
|
||||
|
||||
if (! src[0])
|
||||
src="[.]"; /* Empty is == current dir */
|
||||
|
||||
slen = strlen (src) - 1;
|
||||
if (src[slen] == FN_C_AFTER_DIR || src[slen] == FN_C_AFTER_DIR_2 ||
|
||||
src[slen] == FN_DEVCHAR)
|
||||
{
|
||||
/* VMS style - convert [x.y.z] to [x.y]z, [x] to [000000]x */
|
||||
fab.fab$l_fna = src;
|
||||
fab.fab$b_fns = slen + 1;
|
||||
fab.fab$l_nam = &nam;
|
||||
fab.fab$l_fop = FAB$M_NAM;
|
||||
|
||||
nam.nam$l_esa = esa;
|
||||
nam.nam$b_ess = sizeof esa;
|
||||
nam.nam$b_nop |= NAM$M_SYNCHK;
|
||||
|
||||
/* We call SYS$PARSE to handle such things as [--] for us. */
|
||||
if (SYS$PARSE(&fab, 0, 0) == RMS$_NORMAL)
|
||||
{
|
||||
slen = nam.nam$b_esl - 1;
|
||||
if (esa[slen] == ';' && esa[slen - 1] == '.')
|
||||
slen -= 2;
|
||||
esa[slen + 1] = '\0';
|
||||
src = esa;
|
||||
}
|
||||
if (src[slen] != FN_C_AFTER_DIR && src[slen] != FN_C_AFTER_DIR_2)
|
||||
{
|
||||
/* what about when we have logical_name:???? */
|
||||
if (src[slen] == FN_DEVCHAR)
|
||||
{ /* Xlate logical name and see what we get */
|
||||
VOID(strmov(dst,src));
|
||||
dst[slen] = 0; /* remove colon */
|
||||
if (!(src = getenv (dst)))
|
||||
return dst; /* Can't translate */
|
||||
|
||||
/* should we jump to the beginning of this procedure?
|
||||
Good points: allows us to use logical names that xlate
|
||||
to Unix names,
|
||||
Bad points: can be a problem if we just translated to a device
|
||||
name...
|
||||
For now, I'll punt and always expect VMS names, and hope for
|
||||
the best! */
|
||||
|
||||
slen = strlen (src) - 1;
|
||||
if (src[slen] != FN_C_AFTER_DIR && src[slen] != FN_C_AFTER_DIR_2)
|
||||
{ /* no recursion here! */
|
||||
VOID(strmov(dst, src));
|
||||
return(dst);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /* not a directory spec */
|
||||
VOID(strmov(dst, src));
|
||||
return(dst);
|
||||
}
|
||||
}
|
||||
|
||||
bracket = src[slen]; /* End char */
|
||||
if (!(ptr = strchr (src, bracket - 2)))
|
||||
{ /* no opening bracket */
|
||||
VOID(strmov (dst, src));
|
||||
return dst;
|
||||
}
|
||||
if (!(rptr = strrchr (src, '.')))
|
||||
rptr = ptr;
|
||||
slen = rptr - src;
|
||||
VOID(strmake (dst, src, slen));
|
||||
|
||||
if (*rptr == '.')
|
||||
{ /* Put bracket and add */
|
||||
dst[slen++] = bracket; /* (rptr+1) after this */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If we have the top-level of a rooted directory (i.e. xx:[000000]),
|
||||
then translate the device and recurse. */
|
||||
|
||||
if (dst[slen - 1] == ':'
|
||||
&& dst[slen - 2] != ':' /* skip decnet nodes */
|
||||
&& strcmp(src + slen, "[000000]") == 0)
|
||||
{
|
||||
dst[slen - 1] = '\0';
|
||||
if ((ptr = getenv (dst))
|
||||
&& (rlen = strlen (ptr) - 1) > 0
|
||||
&& (ptr[rlen] == FN_C_AFTER_DIR || ptr[rlen] == FN_C_AFTER_DIR_2)
|
||||
&& ptr[rlen - 1] == '.')
|
||||
{
|
||||
VOID(strmov(esa,ptr));
|
||||
esa[rlen - 1] = FN_C_AFTER_DIR;
|
||||
esa[rlen] = '\0';
|
||||
return (directory_file_name (dst, esa));
|
||||
}
|
||||
else
|
||||
dst[slen - 1] = ':';
|
||||
}
|
||||
VOID(strmov(dst+slen,"[000000]"));
|
||||
slen += 8;
|
||||
}
|
||||
VOID(strmov(strmov(dst+slen,rptr+1)-1,".DIR.1"));
|
||||
return dst;
|
||||
}
|
||||
VOID(strmov(dst, src));
|
||||
if (dst[slen] == '/' && slen > 1)
|
||||
dst[slen] = 0;
|
||||
return dst;
|
||||
#endif /* VMS */
|
||||
} /* directory_file_name */
|
||||
|
||||
#elif defined(_WIN32)
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
** Read long filename using windows rutines
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
MY_DIR *my_dir(const char *path, myf MyFlags)
|
||||
{
|
||||
struct fileinfo *fnames;
|
||||
char *buffer, *obuffer, *tempptr;
|
||||
int eof,i,fcnt,firstfcnt,length,maxfcnt;
|
||||
uint size;
|
||||
#ifdef __BORLANDC__
|
||||
struct ffblk find;
|
||||
#else
|
||||
struct _finddata_t find;
|
||||
#endif
|
||||
ushort mode;
|
||||
char tmp_path[FN_REFLEN],*tmp_file,attrib;
|
||||
my_ptrdiff_t diff;
|
||||
#ifdef _WIN64
|
||||
__int64 handle;
|
||||
#else
|
||||
long handle;
|
||||
#endif
|
||||
DBUG_ENTER("my_dir");
|
||||
DBUG_PRINT("my",("path: '%s' stat: %d MyFlags: %d",path,MyFlags));
|
||||
|
||||
/* Put LIB-CHAR as last path-character if not there */
|
||||
|
||||
tmp_file=tmp_path;
|
||||
if (!*path)
|
||||
*tmp_file++ ='.'; /* From current dir */
|
||||
tmp_file= strmov(tmp_file,path);
|
||||
if (tmp_file[-1] == FN_DEVCHAR)
|
||||
*tmp_file++= '.'; /* From current dev-dir */
|
||||
if (tmp_file[-1] != FN_LIBCHAR)
|
||||
*tmp_file++ =FN_LIBCHAR;
|
||||
tmp_file[0]='*'; /* MSDOS needs this !??? */
|
||||
tmp_file[1]='.';
|
||||
tmp_file[2]='*';
|
||||
tmp_file[3]='\0';
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
if ((handle= findfirst(tmp_path,&find,0)) == -1L)
|
||||
goto error;
|
||||
#else
|
||||
if ((handle=_findfirst(tmp_path,&find)) == -1L)
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
size = STARTSIZE;
|
||||
firstfcnt = maxfcnt = (size - sizeof(MY_DIR)) /
|
||||
(sizeof(struct fileinfo) + FN_LEN);
|
||||
if ((buffer = (char *) my_malloc(size, MyFlags)) == 0)
|
||||
goto error;
|
||||
fnames= (struct fileinfo *) (buffer + sizeof(MY_DIR));
|
||||
tempptr = (char *) (fnames + maxfcnt);
|
||||
|
||||
fcnt = 0;
|
||||
for (;;)
|
||||
{
|
||||
do
|
||||
{
|
||||
fnames[fcnt].name = tempptr;
|
||||
#ifdef __BORLANDC__
|
||||
tempptr = strmov(tempptr,find.ff_name) + 1;
|
||||
fnames[fcnt].mystat.st_size=find.ff_fsize;
|
||||
fnames[fcnt].mystat.st_uid=fnames[fcnt].mystat.st_gid=0;
|
||||
mode=MY_S_IREAD; attrib=find.ff_attrib;
|
||||
#else
|
||||
tempptr = strmov(tempptr,find.name) + 1;
|
||||
fnames[fcnt].mystat.st_size=find.size;
|
||||
fnames[fcnt].mystat.st_uid=fnames[fcnt].mystat.st_gid=0;
|
||||
mode=MY_S_IREAD; attrib=find.attrib;
|
||||
#endif
|
||||
if (!(attrib & _A_RDONLY))
|
||||
mode|=MY_S_IWRITE;
|
||||
if (attrib & _A_SUBDIR)
|
||||
mode|=MY_S_IFDIR;
|
||||
fnames[fcnt].mystat.st_mode=mode;
|
||||
#ifdef __BORLANDC__
|
||||
fnames[fcnt].mystat.st_mtime=((uint32) find.ff_ftime);
|
||||
#else
|
||||
fnames[fcnt].mystat.st_mtime=((uint32) find.time_write);
|
||||
#endif
|
||||
++fcnt;
|
||||
#ifdef __BORLANDC__
|
||||
} while ((eof= findnext(&find)) == 0 && fcnt < maxfcnt);
|
||||
#else
|
||||
} while ((eof= _findnext(handle,&find)) == 0 && fcnt < maxfcnt);
|
||||
#endif
|
||||
|
||||
DBUG_PRINT("test",("eof: %d errno: %d",eof,errno));
|
||||
if (eof)
|
||||
break;
|
||||
size += STARTSIZE; obuffer = buffer;
|
||||
if (!(buffer = (char *) my_realloc((gptr) buffer, size,
|
||||
MyFlags | MY_FREE_ON_ERROR)))
|
||||
goto error;
|
||||
length= sizeof(struct fileinfo ) * firstfcnt;
|
||||
diff= PTR_BYTE_DIFF(buffer , obuffer) +length;
|
||||
fnames= (struct fileinfo *) (buffer + sizeof(MY_DIR));
|
||||
tempptr= ADD_TO_PTR(tempptr,diff,char*);
|
||||
for (i = 0; i < maxfcnt; i++)
|
||||
fnames[i].name = ADD_TO_PTR(fnames[i].name,diff,char*);
|
||||
|
||||
/* move filenames upp a bit */
|
||||
maxfcnt += firstfcnt;
|
||||
bmove_upp(tempptr,ADD_TO_PTR(tempptr,-length,char*),
|
||||
(int) PTR_BYTE_DIFF(tempptr,fnames+maxfcnt));
|
||||
}
|
||||
{
|
||||
MY_DIR * s = (MY_DIR *) buffer;
|
||||
s->number_off_files = (uint) fcnt;
|
||||
s->dir_entry = fnames;
|
||||
}
|
||||
if (!(MyFlags & MY_DONT_SORT))
|
||||
qsort(fnames,fcnt,sizeof(struct fileinfo),(qsort_cmp) comp_names);
|
||||
#ifndef __BORLANDC__
|
||||
_findclose(handle);
|
||||
#endif
|
||||
DBUG_RETURN((MY_DIR *) buffer);
|
||||
|
||||
error:
|
||||
my_errno=errno;
|
||||
#ifndef __BORLANDC__
|
||||
if (handle != -1)
|
||||
_findclose(handle);
|
||||
#endif
|
||||
if (MyFlags & MY_FAE+MY_WME)
|
||||
my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,errno);
|
||||
DBUG_RETURN((MY_DIR *) NULL);
|
||||
} /* my_dir */
|
||||
|
||||
#else /* MSDOS and not WIN32 */
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
** At MSDOS you always get stat of files, but time is in packed MSDOS-format
|
||||
******************************************************************************/
|
||||
|
||||
MY_DIR *my_dir(const char* path, myf MyFlags)
|
||||
{
|
||||
struct fileinfo *fnames;
|
||||
char *buffer, *obuffer, *tempptr;
|
||||
int eof,i,fcnt,firstfcnt,length,maxfcnt;
|
||||
uint size;
|
||||
struct find_t find;
|
||||
ushort mode;
|
||||
char tmp_path[FN_REFLEN],*tmp_file,attrib;
|
||||
my_ptrdiff_t diff;
|
||||
DBUG_ENTER("my_dir");
|
||||
DBUG_PRINT("my",("path: '%s' stat: %d MyFlags: %d",path,MyFlags));
|
||||
|
||||
/* Put LIB-CHAR as last path-character if not there */
|
||||
|
||||
tmp_file=tmp_path;
|
||||
if (!*path)
|
||||
*tmp_file++ ='.'; /* From current dir */
|
||||
tmp_file= strmov(tmp_file,path);
|
||||
if (tmp_file[-1] == FN_DEVCHAR)
|
||||
*tmp_file++= '.'; /* From current dev-dir */
|
||||
if (tmp_file[-1] != FN_LIBCHAR)
|
||||
*tmp_file++ =FN_LIBCHAR;
|
||||
tmp_file[0]='*'; /* MSDOS needs this !??? */
|
||||
tmp_file[1]='.';
|
||||
tmp_file[2]='*';
|
||||
tmp_file[3]='\0';
|
||||
|
||||
if (_dos_findfirst(tmp_path,_A_NORMAL | _A_SUBDIR, &find))
|
||||
goto error;
|
||||
|
||||
size = STARTSIZE;
|
||||
firstfcnt = maxfcnt = (size - sizeof(MY_DIR)) /
|
||||
(sizeof(struct fileinfo) + FN_LEN);
|
||||
if ((buffer = (char *) my_malloc(size, MyFlags)) == 0)
|
||||
goto error;
|
||||
fnames= (struct fileinfo *) (buffer + sizeof(MY_DIR));
|
||||
tempptr = (char *) (fnames + maxfcnt);
|
||||
|
||||
fcnt = 0;
|
||||
for (;;)
|
||||
{
|
||||
do
|
||||
{
|
||||
fnames[fcnt].name = tempptr;
|
||||
tempptr = strmov(tempptr,find.name) + 1;
|
||||
fnames[fcnt].mystat.st_size=find.size;
|
||||
fnames[fcnt].mystat.st_uid=fnames[fcnt].mystat.st_gid=0;
|
||||
mode=MY_S_IREAD; attrib=find.attrib;
|
||||
if (!(attrib & _A_RDONLY))
|
||||
mode|=MY_S_IWRITE;
|
||||
if (attrib & _A_SUBDIR)
|
||||
mode|=MY_S_IFDIR;
|
||||
fnames[fcnt].mystat.st_mode=mode;
|
||||
fnames[fcnt].mystat.st_mtime=((uint32) find.wr_date << 16) +
|
||||
find.wr_time;
|
||||
++fcnt;
|
||||
} while ((eof= _dos_findnext(&find)) == 0 && fcnt < maxfcnt);
|
||||
|
||||
DBUG_PRINT("test",("eof: %d errno: %d",eof,errno));
|
||||
if (eof)
|
||||
break;
|
||||
size += STARTSIZE; obuffer = buffer;
|
||||
if (!(buffer = (char *) my_realloc((gptr) buffer, size,
|
||||
MyFlags | MY_FREE_ON_ERROR)))
|
||||
goto error;
|
||||
length= sizeof(struct fileinfo ) * firstfcnt;
|
||||
diff= PTR_BYTE_DIFF(buffer , obuffer) +length;
|
||||
fnames= (struct fileinfo *) (buffer + sizeof(MY_DIR));
|
||||
tempptr= ADD_TO_PTR(tempptr,diff,char*);
|
||||
for (i = 0; i < maxfcnt; i++)
|
||||
fnames[i].name = ADD_TO_PTR(fnames[i].name,diff,char*);
|
||||
|
||||
/* move filenames upp a bit */
|
||||
maxfcnt += firstfcnt;
|
||||
bmove_upp(tempptr,ADD_TO_PTR(tempptr,-length,char*),
|
||||
(int) PTR_BYTE_DIFF(tempptr,fnames+maxfcnt));
|
||||
}
|
||||
{
|
||||
MY_DIR * s = (MY_DIR *) buffer;
|
||||
s->number_off_files = (uint) fcnt;
|
||||
s->dir_entry = fnames;
|
||||
}
|
||||
if (!(MyFlags & MY_DONT_SORT))
|
||||
qsort(fnames,fcnt,sizeof(struct fileinfo),(qsort_cmp) comp_names);
|
||||
DBUG_RETURN((MY_DIR *) buffer);
|
||||
|
||||
error:
|
||||
if (MyFlags & MY_FAE+MY_WME)
|
||||
my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,errno);
|
||||
DBUG_RETURN((MY_DIR *) NULL);
|
||||
} /* my_dir */
|
||||
|
||||
#endif /* WIN32 && MSDOS */
|
||||
|
||||
/****************************************************************************
|
||||
** File status
|
||||
** Note that MY_STAT is assumed to be same as struct stat
|
||||
****************************************************************************/
|
||||
|
||||
int my_fstat(int Filedes, MY_STAT *stat_area, myf MyFlags )
|
||||
{
|
||||
DBUG_ENTER("my_fstat");
|
||||
DBUG_PRINT("my",("fd: %d MyFlags: %d",Filedes,MyFlags));
|
||||
DBUG_RETURN(fstat(Filedes, (struct stat *) stat_area));
|
||||
}
|
||||
|
||||
MY_STAT *my_stat(const char *path, MY_STAT *stat_area, myf my_flags)
|
||||
{
|
||||
int m_used;
|
||||
DBUG_ENTER("my_stat");
|
||||
DBUG_PRINT("my", ("path: '%s', stat_area: %lx, MyFlags: %d", path,
|
||||
(unsigned char *) stat_area, my_flags));
|
||||
|
||||
if ((m_used= (stat_area == NULL)))
|
||||
if (!(stat_area = (MY_STAT *) my_malloc(sizeof(MY_STAT), my_flags)))
|
||||
goto error;
|
||||
if ( ! stat((my_string) path, (struct stat *) stat_area) )
|
||||
DBUG_RETURN(stat_area);
|
||||
my_errno=errno;
|
||||
if (m_used) /* Free if new area */
|
||||
my_free(stat_area);
|
||||
|
||||
error:
|
||||
if (my_flags & (MY_FAE+MY_WME))
|
||||
{
|
||||
my_error(EE_STAT, MYF(ME_BELL+ME_WAITTANG),path,my_errno);
|
||||
DBUG_RETURN((MY_STAT *) NULL);
|
||||
}
|
||||
DBUG_RETURN((MY_STAT *) NULL);
|
||||
} /* my_stat */
|
||||
|
304
module/Vendor/MDBC/libmariadb/my_loaddata.c
vendored
Normal file
304
module/Vendor/MDBC/libmariadb/my_loaddata.c
vendored
Normal file
@ -0,0 +1,304 @@
|
||||
/************************************************************************************
|
||||
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>
|
||||
#ifdef _WIN32
|
||||
#include <share.h>
|
||||
#endif
|
||||
|
||||
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;
|
||||
int CodePage= -1;
|
||||
#ifdef _WIN32
|
||||
MYSQL *mysql= (MYSQL *)userdata;
|
||||
wchar_t *w_filename= NULL;
|
||||
int Length;
|
||||
#endif
|
||||
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;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (mysql)
|
||||
CodePage= madb_get_windows_cp(mysql->charset->csname);
|
||||
#endif
|
||||
if (CodePage == -1)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
info->fd= sopen(info->filename, _O_RDONLY | _O_BINARY, _SH_DENYNO , _S_IREAD | _S_IWRITE);
|
||||
#else
|
||||
info->fd = open(info->filename, O_RDONLY | O_BINARY, my_umask);
|
||||
#endif
|
||||
my_errno= errno;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
else
|
||||
{
|
||||
if ((Length= MultiByteToWideChar(CodePage, 0, info->filename, (int)strlen(info->filename), NULL, 0)))
|
||||
{
|
||||
if (!(w_filename= (wchar_t *)my_malloc((Length + 1) * sizeof(wchar_t), MYF(MY_ZEROFILL))))
|
||||
{
|
||||
info->error_no= CR_OUT_OF_MEMORY;
|
||||
my_snprintf((char *)info->error_msg, sizeof(info->error_msg),
|
||||
ER(CR_OUT_OF_MEMORY));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
Length= MultiByteToWideChar(CodePage, 0, info->filename, (int)strlen(info->filename), w_filename, (int)Length);
|
||||
}
|
||||
if (Length == 0)
|
||||
{
|
||||
my_free(w_filename);
|
||||
info->error_no= CR_UNKNOWN_ERROR;
|
||||
my_snprintf((char *)info->error_msg, sizeof(info->error_msg),
|
||||
"Character conversion error: %d", GetLastError());
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
info->fd= _wsopen(w_filename, _O_RDONLY | _O_BINARY, _SH_DENYNO , _S_IREAD | _S_IWRITE);
|
||||
my_errno= errno;
|
||||
my_free(w_filename);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (info->fd < 0)
|
||||
{
|
||||
info->error_no = my_errno;
|
||||
my_snprintf((char *)info->error_msg, sizeof(info->error_msg),
|
||||
EE(EE_FILENOTFOUND), filename, info->error_no);
|
||||
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= read(info->fd, (void *)buf, (size_t)buf_len);
|
||||
|
||||
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 >= 0)
|
||||
close(info->fd);
|
||||
my_free(ptr);
|
||||
}
|
||||
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[0] = userdata;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mysql_handle_local_infile */
|
||||
my_bool mysql_handle_local_infile(MYSQL *conn, const char *filename)
|
||||
{
|
||||
unsigned int buflen= 4096;
|
||||
int bufread;
|
||||
unsigned char *buf= NULL;
|
||||
void *info= NULL;
|
||||
my_bool result= 1;
|
||||
|
||||
DBUG_ENTER("mysql_handle_local_infile");
|
||||
|
||||
/* 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)
|
||||
{
|
||||
conn->options.local_infile_userdata[0]= conn;
|
||||
mysql_set_local_infile_default(conn);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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[0]))
|
||||
{
|
||||
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(buf);
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
/* }}} */
|
||||
|
101
module/Vendor/MDBC/libmariadb/my_malloc.c
vendored
Normal file
101
module/Vendor/MDBC/libmariadb/my_malloc.c
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
#ifdef SAFEMALLOC /* We don't need SAFEMALLOC here */
|
||||
#undef SAFEMALLOC
|
||||
#endif
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include "mysys_err.h"
|
||||
#include <m_string.h>
|
||||
|
||||
/* My memory allocator */
|
||||
|
||||
gptr my_malloc(size_t Size, myf MyFlags)
|
||||
{
|
||||
gptr point;
|
||||
DBUG_ENTER("my_malloc");
|
||||
DBUG_PRINT("my",("Size: %u MyFlags: %d",Size, MyFlags));
|
||||
|
||||
if (!Size)
|
||||
Size=1; /* Safety */
|
||||
if ((point = (char*)malloc(Size)) == NULL)
|
||||
{
|
||||
my_errno=errno;
|
||||
if (MyFlags & MY_FAE)
|
||||
error_handler_hook=fatal_error_handler_hook;
|
||||
if (MyFlags & (MY_FAE+MY_WME))
|
||||
my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG),Size);
|
||||
if (MyFlags & MY_FAE)
|
||||
exit(1);
|
||||
}
|
||||
else if (MyFlags & MY_ZEROFILL)
|
||||
bzero(point,Size);
|
||||
DBUG_PRINT("exit",("ptr: %lx",point));
|
||||
DBUG_RETURN(point);
|
||||
} /* my_malloc */
|
||||
|
||||
|
||||
/* Free memory allocated with my_malloc */
|
||||
/*ARGSUSED*/
|
||||
|
||||
void my_no_flags_free(void *ptr)
|
||||
{
|
||||
DBUG_ENTER("my_free");
|
||||
DBUG_PRINT("my",("ptr: %lx",ptr));
|
||||
if (ptr)
|
||||
free(ptr);
|
||||
DBUG_VOID_RETURN;
|
||||
} /* my_free */
|
||||
|
||||
|
||||
/* malloc and copy */
|
||||
|
||||
gptr my_memdup(const unsigned char *from, size_t length, myf MyFlags)
|
||||
{
|
||||
gptr ptr;
|
||||
if ((ptr=my_malloc(length,MyFlags)) != 0)
|
||||
memcpy((unsigned char*) ptr, (unsigned char*) from,(size_t) length);
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
|
||||
my_string my_strdup(const char *from, myf MyFlags)
|
||||
{
|
||||
gptr ptr;
|
||||
uint length;
|
||||
|
||||
if ((MyFlags & MY_ALLOW_ZERO_PTR) && !from)
|
||||
return NULL;
|
||||
|
||||
length=(uint) strlen(from)+1;
|
||||
if ((ptr=my_malloc(length,MyFlags)) != 0)
|
||||
memcpy((unsigned char*) ptr, (unsigned char*) from,(size_t) length);
|
||||
return((my_string) ptr);
|
||||
}
|
||||
|
||||
my_string my_strndup(const char *src, size_t length, myf MyFlags)
|
||||
{
|
||||
gptr ptr;
|
||||
|
||||
if ((ptr= my_malloc(length+1, MyFlags))) {
|
||||
memcpy(ptr, src, length);
|
||||
ptr[length] = 0;
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
/* }}} */
|
36
module/Vendor/MDBC/libmariadb/my_messnc.c
vendored
Normal file
36
module/Vendor/MDBC/libmariadb/my_messnc.c
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
|
||||
int my_message_no_curses(uint error __attribute__((unused)),
|
||||
const char *str, myf MyFlags)
|
||||
{
|
||||
DBUG_ENTER("my_message_no_curses");
|
||||
DBUG_PRINT("enter",("message: %s",str));
|
||||
(void) fflush(stdout);
|
||||
if (MyFlags & ME_BELL)
|
||||
(void) fputc('\007',stderr); /* Bell */
|
||||
if (my_progname)
|
||||
{
|
||||
(void)fputs(my_progname,stderr); (void)fputs(": ",stderr);
|
||||
}
|
||||
(void)fputs(str,stderr);
|
||||
(void)fputc('\n',stderr);
|
||||
(void)fflush(stderr);
|
||||
DBUG_RETURN(0);
|
||||
}
|
44
module/Vendor/MDBC/libmariadb/my_net.c
vendored
Normal file
44
module/Vendor/MDBC/libmariadb/my_net.c
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* thread safe version of some common functions */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include <m_string.h>
|
||||
|
||||
/* for thread safe my_inet_ntoa */
|
||||
#if !defined(MSDOS) && !defined(_WIN32)
|
||||
#include <netdb.h>
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#endif /* !defined(MSDOS) && !defined(_WIN32) */
|
||||
|
||||
void my_inet_ntoa(struct in_addr in, char *buf)
|
||||
{
|
||||
char *ptr;
|
||||
pthread_mutex_lock(&THR_LOCK_net);
|
||||
ptr=inet_ntoa(in);
|
||||
strmov(buf,ptr);
|
||||
pthread_mutex_unlock(&THR_LOCK_net);
|
||||
}
|
88
module/Vendor/MDBC/libmariadb/my_once.c
vendored
Normal file
88
module/Vendor/MDBC/libmariadb/my_once.c
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* Not MT-SAFE */
|
||||
|
||||
#ifdef SAFEMALLOC /* We don't need SAFEMALLOC here */
|
||||
#undef SAFEMALLOC
|
||||
#endif
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include "my_static.h"
|
||||
#include "mysys_err.h"
|
||||
|
||||
/* alloc for things we don't nead to free */
|
||||
/* No DBUG_ENTER... here to get smaller dbug-startup */
|
||||
|
||||
gptr my_once_alloc(unsigned int Size, myf MyFlags)
|
||||
{
|
||||
size_t get_size,max_left;
|
||||
gptr point;
|
||||
reg1 USED_MEM *next;
|
||||
reg2 USED_MEM **prev;
|
||||
|
||||
Size= ALIGN_SIZE(Size);
|
||||
prev= &my_once_root_block;
|
||||
max_left=0;
|
||||
for (next=my_once_root_block ; next && next->left < Size ; next= next->next)
|
||||
{
|
||||
if (next->left > max_left)
|
||||
max_left=next->left;
|
||||
prev= &next->next;
|
||||
}
|
||||
if (! next)
|
||||
{ /* Time to alloc new block */
|
||||
get_size= Size+ALIGN_SIZE(sizeof(USED_MEM));
|
||||
if (max_left*4 < my_once_extra && get_size < my_once_extra)
|
||||
get_size=my_once_extra; /* Normal alloc */
|
||||
|
||||
if ((next = (USED_MEM*) malloc(get_size)) == 0)
|
||||
{
|
||||
my_errno=errno;
|
||||
if (MyFlags & (MY_FAE+MY_WME))
|
||||
my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG),get_size);
|
||||
return((gptr) 0);
|
||||
}
|
||||
DBUG_PRINT("test",("my_once_malloc %u byte malloced",get_size));
|
||||
next->next= 0;
|
||||
next->size= get_size;
|
||||
next->left= get_size-ALIGN_SIZE(sizeof(USED_MEM));
|
||||
*prev=next;
|
||||
}
|
||||
point= (gptr) ((char*) next+ (next->size-next->left));
|
||||
next->left-= Size;
|
||||
|
||||
return(point);
|
||||
} /* my_once_alloc */
|
||||
|
||||
|
||||
/* deallocate everything used by my_once_alloc */
|
||||
|
||||
void my_once_free(void)
|
||||
{
|
||||
reg1 USED_MEM *next,*old;
|
||||
DBUG_ENTER("my_once_free");
|
||||
|
||||
for (next=my_once_root_block ; next ; )
|
||||
{
|
||||
old=next; next= next->next ;
|
||||
free((gptr) old);
|
||||
}
|
||||
my_once_root_block=0;
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
} /* my_once_free */
|
126
module/Vendor/MDBC/libmariadb/my_open.c
vendored
Normal file
126
module/Vendor/MDBC/libmariadb/my_open.c
vendored
Normal file
@ -0,0 +1,126 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
#define USES_TYPES
|
||||
#include "mysys_priv.h"
|
||||
#include "mysys_err.h"
|
||||
#include <my_dir.h>
|
||||
#include <errno.h>
|
||||
#if defined(MSDOS) || defined(_WIN32) || defined(__EMX__) || defined(OS2)
|
||||
#include <share.h>
|
||||
#endif
|
||||
|
||||
/* Open a file */
|
||||
|
||||
File my_open(const char *FileName, int Flags, myf MyFlags)
|
||||
/* Path-name of file */
|
||||
/* Read | write .. */
|
||||
/* Special flags */
|
||||
{
|
||||
File fd;
|
||||
DBUG_ENTER("my_open");
|
||||
DBUG_PRINT("my",("Name: '%s' Flags: %d MyFlags: %d",
|
||||
FileName, Flags, MyFlags));
|
||||
#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);
|
||||
else
|
||||
fd = open((my_string) FileName, Flags | O_BINARY,
|
||||
MY_S_IREAD | MY_S_IWRITE);
|
||||
#elif !defined(NO_OPEN_3)
|
||||
fd = open(FileName, Flags, my_umask); /* Normal unix */
|
||||
#else
|
||||
fd = open((my_string) FileName, Flags);
|
||||
#endif
|
||||
DBUG_RETURN(my_register_filename(fd, FileName, FILE_BY_OPEN,
|
||||
EE_FILENOTFOUND, MyFlags));
|
||||
} /* my_open */
|
||||
|
||||
|
||||
/* Close a file */
|
||||
|
||||
int my_close(File fd, myf MyFlags)
|
||||
{
|
||||
int err;
|
||||
DBUG_ENTER("my_close");
|
||||
DBUG_PRINT("my",("fd: %d MyFlags: %d",fd, MyFlags));
|
||||
|
||||
pthread_mutex_lock(&THR_LOCK_open);
|
||||
if ((err = close(fd)))
|
||||
{
|
||||
DBUG_PRINT("error",("Got error %d on close",err));
|
||||
my_errno=errno;
|
||||
if (MyFlags & (MY_FAE | MY_WME))
|
||||
my_error(EE_BADCLOSE, MYF(ME_BELL+ME_WAITTANG),my_filename(fd),errno);
|
||||
}
|
||||
if ((uint) fd < MY_NFILE && my_file_info[fd].type != UNOPEN)
|
||||
{
|
||||
my_free(my_file_info[fd].name);
|
||||
#if defined(THREAD) && !defined(HAVE_PREAD)
|
||||
pthread_mutex_destroy(&my_file_info[fd].mutex);
|
||||
#endif
|
||||
my_file_info[fd].type = UNOPEN;
|
||||
}
|
||||
my_file_opened--;
|
||||
pthread_mutex_unlock(&THR_LOCK_open);
|
||||
DBUG_RETURN(err);
|
||||
} /* my_close */
|
||||
|
||||
|
||||
File my_register_filename(File fd, const char *FileName, enum file_type
|
||||
type_of_file, uint error_message_number, myf MyFlags)
|
||||
{
|
||||
if ((int) fd >= 0)
|
||||
{
|
||||
if ((int) fd >= MY_NFILE)
|
||||
{
|
||||
#if defined(THREAD) && !defined(HAVE_PREAD)
|
||||
(void) my_close(fd,MyFlags);
|
||||
my_errno=EMFILE;
|
||||
if (MyFlags & (MY_FFNF | MY_FAE | MY_WME))
|
||||
my_error(EE_OUT_OF_FILERESOURCES, MYF(ME_BELL+ME_WAITTANG),
|
||||
FileName, my_errno);
|
||||
return(-1);
|
||||
#endif
|
||||
thread_safe_increment(my_file_opened,&THR_LOCK_open);
|
||||
return(fd); /* safeguard */
|
||||
}
|
||||
pthread_mutex_lock(&THR_LOCK_open);
|
||||
if ((my_file_info[fd].name = (char*) my_strdup(FileName,MyFlags)))
|
||||
{
|
||||
my_file_opened++;
|
||||
my_file_info[fd].type = type_of_file;
|
||||
#if defined(THREAD) && !defined(HAVE_PREAD)
|
||||
pthread_mutex_init(&my_file_info[fd].mutex,MY_MUTEX_INIT_FAST);
|
||||
#endif
|
||||
pthread_mutex_unlock(&THR_LOCK_open);
|
||||
DBUG_PRINT("exit",("fd: %d",fd));
|
||||
return(fd);
|
||||
}
|
||||
pthread_mutex_unlock(&THR_LOCK_open);
|
||||
(void) my_close(fd, MyFlags);
|
||||
my_errno=ENOMEM;
|
||||
}
|
||||
else
|
||||
my_errno=errno;
|
||||
DBUG_PRINT("error",("Got error %d on open",my_errno));
|
||||
if (MyFlags & (MY_FFNF | MY_FAE | MY_WME))
|
||||
my_error(error_message_number, MYF(ME_BELL+ME_WAITTANG),
|
||||
FileName, my_errno);
|
||||
return(fd);
|
||||
}
|
40
module/Vendor/MDBC/libmariadb/my_port.c
vendored
Normal file
40
module/Vendor/MDBC/libmariadb/my_port.c
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/*
|
||||
Small functions to make code portable
|
||||
*/
|
||||
|
||||
#include "mysys_priv.h"
|
||||
|
||||
#ifdef _AIX
|
||||
|
||||
/*
|
||||
On AIX, at least with gcc 3.1, the expression
|
||||
'(double) (ulonglong) var' doesn't always work for big unsigned
|
||||
integers like '18446744073709551615'. The end result is that the
|
||||
high bit is simply dropped. (probably bug in gcc optimizations)
|
||||
Handling the conversion in a sub function seems to work.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
double my_ulonglong2double(unsigned long long nr)
|
||||
{
|
||||
return (double) nr;
|
||||
}
|
||||
#endif /* _AIX */
|
555
module/Vendor/MDBC/libmariadb/my_pthread.c
vendored
Normal file
555
module/Vendor/MDBC/libmariadb/my_pthread.c
vendored
Normal file
@ -0,0 +1,555 @@
|
||||
/* Copyright (C) 2000 MySQL 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* Functions to get threads more portable */
|
||||
|
||||
#define DONT_REMAP_PTHREAD_FUNCTIONS
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#ifdef THREAD
|
||||
#include <signal.h>
|
||||
#include <m_string.h>
|
||||
#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 */
|
||||
InitializeCriticalSection(&cv->waiters_count_lock);
|
||||
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
|
||||
#define SCHED_POLICY SCHED_OTHER
|
||||
#endif
|
||||
|
||||
#ifndef my_pthread_setprio
|
||||
void my_pthread_setprio(pthread_t thread_id,int prior)
|
||||
{
|
||||
#ifdef HAVE_PTHREAD_SETSCHEDPARAM
|
||||
struct sched_param tmp_sched_param;
|
||||
bzero((char*) &tmp_sched_param,sizeof(tmp_sched_param));
|
||||
tmp_sched_param.sched_priority=prior;
|
||||
VOID(pthread_setschedparam(thread_id,SCHED_POLICY,&tmp_sched_param));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef my_pthread_getprio
|
||||
int my_pthread_getprio(pthread_t thread_id)
|
||||
{
|
||||
#ifdef HAVE_PTHREAD_SETSCHEDPARAM
|
||||
struct sched_param tmp_sched_param;
|
||||
int policy;
|
||||
if (!pthread_getschedparam(thread_id,&policy,&tmp_sched_param))
|
||||
{
|
||||
DBUG_PRINT("thread",("policy: %d priority: %d",
|
||||
policy,tmp_sched_param.sched_priority));
|
||||
return tmp_sched_param.sched_priority;
|
||||
}
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef my_pthread_attr_setprio
|
||||
void my_pthread_attr_setprio(pthread_attr_t *attr, int priority)
|
||||
{
|
||||
#ifdef HAVE_PTHREAD_SETSCHEDPARAM
|
||||
struct sched_param tmp_sched_param;
|
||||
bzero((char*) &tmp_sched_param,sizeof(tmp_sched_param));
|
||||
tmp_sched_param.sched_priority=priority;
|
||||
VOID(pthread_attr_setschedparam(attr,&tmp_sched_param));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* To allow use of pthread_getspecific with two arguments */
|
||||
|
||||
#ifdef HAVE_NONPOSIX_PTHREAD_GETSPECIFIC
|
||||
#undef pthread_getspecific
|
||||
#ifdef HAVE_UNIXWARE7_THREADS
|
||||
#define pthread_getspecific thr_getspecific
|
||||
#endif
|
||||
|
||||
void *my_pthread_getspecific_imp(pthread_key_t key)
|
||||
{
|
||||
void *value;
|
||||
if (pthread_getspecific(key,(void *) &value))
|
||||
return 0;
|
||||
return value;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Some functions for RTS threads, AIX, Siemens Unix and UnixWare 7
|
||||
(and DEC OSF/1 3.2 too) */
|
||||
|
||||
int my_pthread_create_detached=1;
|
||||
|
||||
#if defined(HAVE_NONPOSIX_SIGWAIT) || defined(HAVE_DEC_3_2_THREADS)
|
||||
|
||||
int my_sigwait(const sigset_t *set,int *sig)
|
||||
{
|
||||
int signal=sigwait((sigset_t*) set);
|
||||
if (signal < 0)
|
||||
return errno;
|
||||
*sig=signal;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* localtime_r for SCO 3.2V4.2 */
|
||||
|
||||
#ifndef HAVE_LOCALTIME_R
|
||||
|
||||
extern pthread_mutex_t LOCK_localtime_r;
|
||||
|
||||
struct tm *localtime_r(const time_t *clock, struct tm *res)
|
||||
{
|
||||
struct tm *tmp;
|
||||
pthread_mutex_lock(&LOCK_localtime_r);
|
||||
tmp=localtime(clock);
|
||||
*res= *tmp;
|
||||
pthread_mutex_unlock(&LOCK_localtime_r);
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
** Replacement of sigwait if the system doesn't have one (like BSDI 3.0)
|
||||
**
|
||||
** Note:
|
||||
** This version of sigwait() is assumed to called in a loop so the signalmask
|
||||
** is permanently modified to reflect the signal set. This is done to get
|
||||
** a much faster implementation.
|
||||
**
|
||||
** This implementation isn't thread safe: It assumes that only one
|
||||
** thread is using sigwait.
|
||||
**
|
||||
** If one later supplies a different signal mask, all old signals that
|
||||
** was used before are unblocked and set to SIGDFL.
|
||||
**
|
||||
** Author: Gary Wisniewski <garyw@spidereye.com.au>, much modified by Monty
|
||||
****************************************************************************/
|
||||
|
||||
#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)
|
||||
|
||||
static sigset_t sigwait_set,rev_sigwait_set,px_recd;
|
||||
|
||||
void px_handle_sig(int sig)
|
||||
{
|
||||
sigaddset(&px_recd, sig);
|
||||
}
|
||||
|
||||
|
||||
void sigwait_setup(sigset_t *set)
|
||||
{
|
||||
int i;
|
||||
struct sigaction sact,sact1;
|
||||
sigset_t unblock_mask;
|
||||
|
||||
sact.sa_flags = 0;
|
||||
sact.sa_handler = px_handle_sig;
|
||||
memcpy_fixed(&sact.sa_mask,set,sizeof(*set)); /* handler isn't thread_safe */
|
||||
sigemptyset(&unblock_mask);
|
||||
pthread_sigmask(SIG_UNBLOCK,(sigset_t*) 0,&rev_sigwait_set);
|
||||
|
||||
for (i = 1; i <= sizeof(sigwait_set)*8; i++)
|
||||
{
|
||||
if (sigismember(set,i))
|
||||
{
|
||||
sigdelset(&rev_sigwait_set,i);
|
||||
if (!sigismember(&sigwait_set,i))
|
||||
sigaction(i, &sact, (struct sigaction*) 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
sigdelset(&px_recd,i); /* Don't handle this */
|
||||
if (sigismember(&sigwait_set,i))
|
||||
{ /* Remove the old handler */
|
||||
sigaddset(&unblock_mask,i);
|
||||
sigdelset(&rev_sigwait_set,i);
|
||||
sact1.sa_flags = 0;
|
||||
sact1.sa_handler = SIG_DFL;
|
||||
sigemptyset(&sact1.sa_mask);
|
||||
sigaction(i, &sact1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
memcpy_fixed(&sigwait_set,set,sizeof(*set));
|
||||
pthread_sigmask(SIG_BLOCK,(sigset_t*) set,(sigset_t*) 0);
|
||||
pthread_sigmask(SIG_UNBLOCK,&unblock_mask,(sigset_t*) 0);
|
||||
}
|
||||
|
||||
|
||||
int sigwait(sigset_t *setp, int *sigp)
|
||||
{
|
||||
if (memcmp(setp,&sigwait_set,sizeof(sigwait_set)))
|
||||
sigwait_setup(setp); /* Init or change of set */
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/*
|
||||
This is a fast, not 100% portable implementation to find the signal.
|
||||
Because the handler is blocked there should be at most 1 bit set, but
|
||||
the specification on this is somewhat shady so we use a set instead a
|
||||
single variable.
|
||||
*/
|
||||
|
||||
ulong *ptr= (ulong*) &px_recd;
|
||||
ulong *end=ptr+sizeof(px_recd)/sizeof(ulong);
|
||||
|
||||
for ( ; ptr != end ; ptr++)
|
||||
{
|
||||
if (*ptr)
|
||||
{
|
||||
ulong set= *ptr;
|
||||
int found= (int) ((char*) ptr - (char*) &px_recd)*8+1;
|
||||
while (!(set & 1))
|
||||
{
|
||||
found++;
|
||||
set>>=1;
|
||||
}
|
||||
*sigp=found;
|
||||
sigdelset(&px_recd,found);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
sigsuspend(&rev_sigwait_set);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else /* !DONT_USE_SIGSUSPEND */
|
||||
|
||||
/****************************************************************************
|
||||
** Replacement of sigwait if the system doesn't have one (like BSDI 3.0)
|
||||
**
|
||||
** Note:
|
||||
** This version of sigwait() is assumed to called in a loop so the signalmask
|
||||
** is permanently modified to reflect the signal set. This is done to get
|
||||
** a much faster implementation.
|
||||
**
|
||||
** This implementation uses a extra thread to handle the signals and one
|
||||
** must always call sigwait() with the same signal mask!
|
||||
**
|
||||
** BSDI 3.0 NOTE:
|
||||
**
|
||||
** pthread_kill() doesn't work on a thread in a select() or sleep() loop?
|
||||
** After adding the sleep to sigwait_thread, all signals are checked and
|
||||
** delivered every second. This isn't that terrible performance vice, but
|
||||
** someone should report this to BSDI and ask for a fix!
|
||||
** Another problem is that when the sleep() ends, every select() in other
|
||||
** threads are interrupted!
|
||||
****************************************************************************/
|
||||
|
||||
static sigset_t pending_set;
|
||||
static bool inited=0;
|
||||
static pthread_cond_t COND_sigwait;
|
||||
static pthread_mutex_t LOCK_sigwait;
|
||||
|
||||
|
||||
void sigwait_handle_sig(int sig)
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_sigwait);
|
||||
sigaddset(&pending_set, sig);
|
||||
VOID(pthread_cond_signal(&COND_sigwait)); /* inform sigwait() about signal */
|
||||
pthread_mutex_unlock(&LOCK_sigwait);
|
||||
}
|
||||
|
||||
extern pthread_t alarm_thread;
|
||||
|
||||
void *sigwait_thread(void *set_arg)
|
||||
{
|
||||
sigset_t *set=(sigset_t*) set_arg;
|
||||
|
||||
int i;
|
||||
struct sigaction sact;
|
||||
sact.sa_flags = 0;
|
||||
sact.sa_handler = sigwait_handle_sig;
|
||||
memcpy_fixed(&sact.sa_mask,set,sizeof(*set)); /* handler isn't thread_safe */
|
||||
sigemptyset(&pending_set);
|
||||
|
||||
for (i = 1; i <= sizeof(pending_set)*8; i++)
|
||||
{
|
||||
if (sigismember(set,i))
|
||||
{
|
||||
sigaction(i, &sact, (struct sigaction*) 0);
|
||||
}
|
||||
}
|
||||
sigaddset(set,THR_CLIENT_ALARM);
|
||||
pthread_sigmask(SIG_UNBLOCK,(sigset_t*) set,(sigset_t*) 0);
|
||||
alarm_thread=pthread_self(); /* For thr_alarm */
|
||||
|
||||
for (;;)
|
||||
{ /* Wait for signals */
|
||||
#ifdef HAVE_NOT_BROKEN_SELECT
|
||||
fd_set fd;
|
||||
FD_ZERO(&fd);
|
||||
select(0,&fd,0,0,0);
|
||||
#else
|
||||
sleep(1); /* Because of broken BSDI */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int sigwait(sigset_t *setp, int *sigp)
|
||||
{
|
||||
if (!inited)
|
||||
{
|
||||
pthread_attr_t thr_attr;
|
||||
pthread_t sigwait_thread_id;
|
||||
inited=1;
|
||||
sigemptyset(&pending_set);
|
||||
pthread_mutex_init(&LOCK_sigwait,MY_MUTEX_INIT_FAST);
|
||||
pthread_cond_init(&COND_sigwait,NULL);
|
||||
|
||||
pthread_attr_init(&thr_attr);
|
||||
pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS);
|
||||
pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
|
||||
pthread_attr_setstacksize(&thr_attr,8196);
|
||||
my_pthread_attr_setprio(&thr_attr,100); /* Very high priority */
|
||||
VOID(pthread_create(&sigwait_thread_id,&thr_attr,sigwait_thread,setp));
|
||||
VOID(pthread_attr_destroy(&thr_attr));
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&LOCK_sigwait);
|
||||
for (;;)
|
||||
{
|
||||
ulong *ptr= (ulong*) &pending_set;
|
||||
ulong *end=ptr+sizeof(pending_set)/sizeof(ulong);
|
||||
|
||||
for ( ; ptr != end ; ptr++)
|
||||
{
|
||||
if (*ptr)
|
||||
{
|
||||
ulong set= *ptr;
|
||||
int found= (int) ((char*) ptr - (char*) &pending_set)*8+1;
|
||||
while (!(set & 1))
|
||||
{
|
||||
found++;
|
||||
set>>=1;
|
||||
}
|
||||
*sigp=found;
|
||||
sigdelset(&pending_set,found);
|
||||
pthread_mutex_unlock(&LOCK_sigwait);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
VOID(pthread_cond_wait(&COND_sigwait,&LOCK_sigwait));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* DONT_USE_SIGSUSPEND */
|
||||
#endif /* HAVE_SIGWAIT */
|
||||
|
||||
/*****************************************************************************
|
||||
** Implement pthread_signal for systems that can't use signal() with threads
|
||||
** Currently this is only used with BSDI 3.0
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef USE_PTHREAD_SIGNAL
|
||||
|
||||
int pthread_signal(int sig, void (*func)())
|
||||
{
|
||||
struct sigaction sact;
|
||||
sact.sa_flags= 0;
|
||||
sact.sa_handler= func;
|
||||
sigemptyset(&sact.sa_mask);
|
||||
sigaction(sig, &sact, (struct sigaction*) 0);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
The following functions fixes that all pthread functions should work
|
||||
according to latest posix standard
|
||||
****************************************************************************/
|
||||
|
||||
/* Undefined wrappers set my_pthread.h so that we call os functions */
|
||||
#undef pthread_mutex_init
|
||||
#undef pthread_mutex_lock
|
||||
#undef pthread_mutex_unlock
|
||||
#undef pthread_mutex_destroy
|
||||
#undef pthread_mutex_wait
|
||||
#undef pthread_mutex_timedwait
|
||||
#undef pthread_mutex_trylock
|
||||
#undef pthread_mutex_t
|
||||
#undef pthread_cond_init
|
||||
#undef pthread_cond_wait
|
||||
#undef pthread_cond_timedwait
|
||||
#undef pthread_cond_t
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Patches for AIX and DEC OSF/1 3.2
|
||||
*****************************************************************************/
|
||||
|
||||
#if (defined(HAVE_NONPOSIX_PTHREAD_MUTEX_INIT) && !defined(HAVE_UNIXWARE7_THREADS)) || defined(HAVE_DEC_3_2_THREADS)
|
||||
|
||||
#include <netdb.h>
|
||||
|
||||
int my_pthread_mutex_init(pthread_mutex_t *mp, const pthread_mutexattr_t *attr)
|
||||
{
|
||||
int error;
|
||||
if (!attr)
|
||||
error=pthread_mutex_init(mp,pthread_mutexattr_default);
|
||||
else
|
||||
error=pthread_mutex_init(mp,*attr);
|
||||
return error;
|
||||
}
|
||||
|
||||
int my_pthread_cond_init(pthread_cond_t *mp, const pthread_condattr_t *attr)
|
||||
{
|
||||
int error;
|
||||
if (!attr)
|
||||
error=pthread_cond_init(mp,pthread_condattr_default);
|
||||
else
|
||||
error=pthread_cond_init(mp,*attr);
|
||||
return error;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
Patches for HPUX
|
||||
We need these because the pthread_mutex.. code returns -1 on error,
|
||||
instead of the error code.
|
||||
|
||||
Note that currently we only remap pthread_ functions used by MySQL.
|
||||
If we are depending on the value for some other pthread_xxx functions,
|
||||
this has to be added here.
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(HPUX) || defined(HAVE_BROKEN_PTHREAD_COND_TIMEDWAIT)
|
||||
|
||||
int my_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
struct timespec *abstime)
|
||||
{
|
||||
int error=pthread_cond_timedwait(cond, mutex, abstime);
|
||||
if (error == -1) /* Safety if the lib is fixed */
|
||||
{
|
||||
if (!(error=errno))
|
||||
error= ETIMEDOUT; /* Can happen on HPUX */
|
||||
}
|
||||
if (error == EAGAIN) /* Correct errno to Posix */
|
||||
error= ETIMEDOUT;
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_POSIX1003_4a_MUTEX
|
||||
/*
|
||||
In HP-UX-10.20 and other old Posix 1003.4a Draft 4 implementations
|
||||
pthread_mutex_trylock returns 1 on success, not 0 like
|
||||
pthread_mutex_lock
|
||||
|
||||
From the HP-UX-10.20 man page:
|
||||
RETURN VALUES
|
||||
If the function fails, errno may be set to one of the following
|
||||
values:
|
||||
Return | Error | Description
|
||||
_______|__________|_________________________________________
|
||||
1 | | Successful completion.
|
||||
0 | | The mutex is locked; therefore, it was
|
||||
| | not acquired.
|
||||
-1 | [EINVAL] | The value specified by mutex is invalid.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
Convert pthread_mutex_trylock to return values according to latest POSIX
|
||||
|
||||
RETURN VALUES
|
||||
0 If we are able successfully lock the mutex.
|
||||
EBUSY Mutex was locked by another thread
|
||||
# Other error number returned by pthread_mutex_trylock()
|
||||
(Not likely)
|
||||
*/
|
||||
|
||||
int my_pthread_mutex_trylock(pthread_mutex_t *mutex)
|
||||
{
|
||||
int error= pthread_mutex_trylock(mutex);
|
||||
if (error == 1)
|
||||
return 0; /* Got lock on mutex */
|
||||
if (error == 0) /* Someon else is locking mutex */
|
||||
return EBUSY;
|
||||
if (error == -1) /* Safety if the lib is fixed */
|
||||
error= errno; /* Probably invalid parameter */
|
||||
return error;
|
||||
}
|
||||
#endif /* HAVE_POSIX1003_4a_MUTEX */
|
||||
|
||||
/* Some help functions */
|
||||
|
||||
int pthread_no_free(void *not_used __attribute__((unused)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_dummy(int ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
#endif /* THREAD */
|
66
module/Vendor/MDBC/libmariadb/my_read.c
vendored
Normal file
66
module/Vendor/MDBC/libmariadb/my_read.c
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include "mysys_err.h"
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
/* Read a chunk of bytes from a file */
|
||||
|
||||
uint my_read(File Filedes, unsigned char *Buffer, uint Count, myf MyFlags)
|
||||
/* File descriptor */
|
||||
/* Buffer must be at least count bytes */
|
||||
/* Max number of bytes returnd */
|
||||
/* Flags on what to do on error */
|
||||
{
|
||||
uint readbytes;
|
||||
DBUG_ENTER("my_read");
|
||||
DBUG_PRINT("my",("Fd: %d Buffer: %lx Count: %u MyFlags: %d",
|
||||
Filedes, Buffer, Count, MyFlags));
|
||||
|
||||
for (;;)
|
||||
{
|
||||
errno=0; /* Linux doesn't reset this */
|
||||
if ((readbytes = (uint) read(Filedes, Buffer, Count)) != Count)
|
||||
{
|
||||
my_errno=errno ? errno : -1;
|
||||
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))
|
||||
readbytes=0; /* Ok on read */
|
||||
break;
|
||||
}
|
||||
DBUG_RETURN(readbytes);
|
||||
} /* my_read */
|
65
module/Vendor/MDBC/libmariadb/my_realloc.c
vendored
Normal file
65
module/Vendor/MDBC/libmariadb/my_realloc.c
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
#ifdef SAFEMALLOC /* We don't need SAFEMALLOC here */
|
||||
#undef SAFEMALLOC
|
||||
#endif
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include "mysys_err.h"
|
||||
|
||||
/* My memory re allocator */
|
||||
|
||||
gptr my_realloc(gptr oldpoint, size_t Size, myf MyFlags)
|
||||
{
|
||||
gptr point;
|
||||
DBUG_ENTER("my_realloc");
|
||||
DBUG_PRINT("my",("ptr: %lx Size: %u MyFlags: %d",oldpoint, Size, MyFlags));
|
||||
|
||||
if (!oldpoint && (MyFlags & MY_ALLOW_ZERO_PTR))
|
||||
DBUG_RETURN(my_malloc(Size,MyFlags));
|
||||
#ifdef USE_HALLOC
|
||||
if (!(point = malloc(Size)))
|
||||
{
|
||||
if (MyFlags & MY_FREE_ON_ERROR)
|
||||
my_free(oldpoint);
|
||||
if (MyFlags & MY_HOLD_ON_ERROR)
|
||||
DBUG_RETURN(oldpoint);
|
||||
my_errno=errno;
|
||||
if (MyFlags & MY_FAE+MY_WME)
|
||||
my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG),Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(point,oldpoint,Size);
|
||||
free(oldpoint);
|
||||
}
|
||||
#else
|
||||
if ((point = (char*)realloc(oldpoint,Size)) == NULL)
|
||||
{
|
||||
if (MyFlags & MY_FREE_ON_ERROR)
|
||||
my_free(oldpoint);
|
||||
if (MyFlags & MY_HOLD_ON_ERROR)
|
||||
DBUG_RETURN(oldpoint);
|
||||
my_errno=errno;
|
||||
if (MyFlags & (MY_FAE+MY_WME))
|
||||
my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG), Size);
|
||||
}
|
||||
#endif
|
||||
DBUG_PRINT("exit",("ptr: %lx",point));
|
||||
DBUG_RETURN(point);
|
||||
} /* my_realloc */
|
58
module/Vendor/MDBC/libmariadb/my_seek.c
vendored
Normal file
58
module/Vendor/MDBC/libmariadb/my_seek.c
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
|
||||
/* Seek to position in file */
|
||||
/*ARGSUSED*/
|
||||
|
||||
my_off_t my_seek(File fd, my_off_t pos, int whence,
|
||||
myf MyFlags __attribute__((unused)))
|
||||
{
|
||||
reg1 os_off_t newpos;
|
||||
DBUG_ENTER("my_seek");
|
||||
DBUG_PRINT("my",("Fd: %d Hpos: %lu Pos: %lu Whence: %d MyFlags: %d",
|
||||
fd, ((ulonglong) pos) >> 32, (ulong) pos, whence, MyFlags));
|
||||
newpos=lseek(fd, pos, whence);
|
||||
if (newpos == (os_off_t) -1)
|
||||
{
|
||||
my_errno=errno;
|
||||
DBUG_PRINT("error",("lseek: %lu, errno: %d",newpos,errno));
|
||||
DBUG_RETURN(MY_FILEPOS_ERROR);
|
||||
}
|
||||
DBUG_RETURN((my_off_t) newpos);
|
||||
} /* my_seek */
|
||||
|
||||
|
||||
/* Tell current position of file */
|
||||
/* ARGSUSED */
|
||||
|
||||
my_off_t my_tell(File fd, myf MyFlags __attribute__((unused)))
|
||||
{
|
||||
os_off_t pos;
|
||||
DBUG_ENTER("my_tell");
|
||||
DBUG_PRINT("my",("Fd: %d MyFlags: %d",fd, MyFlags));
|
||||
#ifdef HAVE_TELL
|
||||
pos=tell(fd);
|
||||
#else
|
||||
pos=lseek(fd, 0L, MY_SEEK_CUR);
|
||||
#endif
|
||||
if (pos == (os_off_t) -1)
|
||||
my_errno=errno;
|
||||
DBUG_PRINT("exit",("pos: %lu",pos));
|
||||
DBUG_RETURN((my_off_t) pos);
|
||||
} /* my_tell */
|
101
module/Vendor/MDBC/libmariadb/my_static.c
vendored
Normal file
101
module/Vendor/MDBC/libmariadb/my_static.c
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/*
|
||||
Static variables for mysys library. All definied here for easy making of
|
||||
a shared library
|
||||
*/
|
||||
|
||||
#if !defined(stdin) || defined(OS2)
|
||||
#include "mysys_priv.h"
|
||||
#include "my_static.h"
|
||||
#include "my_alarm.h"
|
||||
#endif
|
||||
|
||||
/* from my_init */
|
||||
my_string home_dir=0,my_progname=0;
|
||||
char NEAR curr_dir[FN_REFLEN]= {0},
|
||||
NEAR home_dir_buff[FN_REFLEN]= {0};
|
||||
ulong my_stream_opened=0,my_file_opened=0, my_tmp_file_created=0;
|
||||
int NEAR my_umask=0664, NEAR my_umask_dir=0777;
|
||||
#ifndef THREAD
|
||||
int NEAR my_errno=0;
|
||||
#endif
|
||||
struct my_file_info my_file_info[MY_NFILE]= {{0,UNOPEN}};
|
||||
|
||||
/* From mf_brkhant */
|
||||
int NEAR my_dont_interrupt=0;
|
||||
volatile int _my_signals=0;
|
||||
struct st_remember _my_sig_remember[MAX_SIGNALS]={{0,0}};
|
||||
#ifdef THREAD
|
||||
sigset_t my_signals; /* signals blocked by mf_brkhant */
|
||||
#endif
|
||||
|
||||
/* from mf_keycache.c */
|
||||
my_bool key_cache_inited=0;
|
||||
|
||||
/* from mf_reccache.c */
|
||||
ulong my_default_record_cache_size=RECORD_CACHE_SIZE;
|
||||
|
||||
/* from soundex.c */
|
||||
/* ABCDEFGHIJKLMNOPQRSTUVWXYZ */
|
||||
/* :::::::::::::::::::::::::: */
|
||||
const char *soundex_map= "01230120022455012623010202";
|
||||
|
||||
/* from my_malloc */
|
||||
USED_MEM* my_once_root_block=0; /* pointer to first block */
|
||||
uint my_once_extra=ONCE_ALLOC_INIT; /* Memory to alloc / block */
|
||||
|
||||
/* from my_tempnam */
|
||||
#if !defined(HAVE_TEMPNAM) || defined(HPUX11)
|
||||
int _my_tempnam_used=0;
|
||||
#endif
|
||||
|
||||
/* from safe_malloc */
|
||||
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 */
|
||||
size_t lCurMemory = 0L; /* Current memory usage */
|
||||
size_t lMaxMemory = 0L; /* Maximum memory usage */
|
||||
uint cNewCount = 0; /* Number of times NEW() was called */
|
||||
unsigned char *sf_min_adress= (unsigned char*) ~(unsigned long) 0L,
|
||||
*sf_max_adress= (unsigned char*) 0L;
|
||||
|
||||
/* Root of the linked list of remembers */
|
||||
struct remember *pRememberRoot = NULL;
|
||||
|
||||
/* from my_alarm */
|
||||
int volatile my_have_got_alarm=0; /* declare variable to reset */
|
||||
ulong my_time_to_wait_for_lock=2; /* In seconds */
|
||||
|
||||
/* from errors.c */
|
||||
#ifdef SHARED_LIBRARY
|
||||
char * NEAR globerrs[GLOBERRS]; /* my_error_messages is here */
|
||||
#endif
|
||||
void (*my_abort_hook)(int) = (void(*)(int)) exit;
|
||||
int (*error_handler_hook)(uint error,const char *str,myf MyFlags)=
|
||||
my_message_no_curses;
|
||||
int (*fatal_error_handler_hook)(uint error,const char *str,myf MyFlags)=
|
||||
my_message_no_curses;
|
||||
|
||||
/* How to disable options */
|
||||
my_bool NEAR my_disable_locking=0;
|
||||
my_bool NEAR my_disable_async_io=0;
|
||||
my_bool NEAR my_disable_flush_key_blocks=0;
|
||||
my_bool NEAR my_disable_symlinks=0;
|
||||
my_bool NEAR mysys_uses_curses=0;
|
70
module/Vendor/MDBC/libmariadb/my_static.h
vendored
Normal file
70
module/Vendor/MDBC/libmariadb/my_static.h
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/*
|
||||
Static variables for mysys library. All definied here for easy making of
|
||||
a shared library
|
||||
*/
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include <signal.h>
|
||||
|
||||
#define MAX_SIGNALS 10 /* Max signals under a dont-allow */
|
||||
#define MIN_KEYBLOCK (min(IO_SIZE,1024))
|
||||
#define MAX_KEYBLOCK 8192 /* Max keyblocklength == 8*IO_SIZE */
|
||||
#define MAX_BLOCK_TYPES MAX_KEYBLOCK/MIN_KEYBLOCK
|
||||
|
||||
struct st_remember {
|
||||
int number;
|
||||
sig_handler (*func)(int number);
|
||||
};
|
||||
|
||||
struct irem {
|
||||
struct remember *_pNext; /* Linked list of structures */
|
||||
struct remember *_pPrev; /* Other link */
|
||||
my_string _sFileName; /* File in which memory was new'ed */
|
||||
uint _uLineNum; /* Line number in above file */
|
||||
uint _uDataSize; /* Size requested */
|
||||
long _lSpecialValue; /* Underrun marker value */
|
||||
};
|
||||
|
||||
struct remember {
|
||||
struct irem tInt;
|
||||
char aData[1];
|
||||
};
|
||||
|
||||
extern char NEAR curr_dir[FN_REFLEN],NEAR home_dir_buff[FN_REFLEN];
|
||||
|
||||
extern volatile int _my_signals;
|
||||
extern struct st_remember _my_sig_remember[MAX_SIGNALS];
|
||||
|
||||
extern const char *soundex_map;
|
||||
|
||||
extern USED_MEM* my_once_root_block;
|
||||
extern uint my_once_extra;
|
||||
|
||||
#if !defined(HAVE_TEMPNAM) || defined(HPUX11)
|
||||
extern int _my_tempnam_used;
|
||||
#endif
|
||||
|
||||
extern unsigned char *sf_min_adress,*sf_max_adress;
|
||||
extern uint cNewCount;
|
||||
extern struct remember *pRememberRoot;
|
||||
|
||||
#if defined(THREAD) && !defined(__WIN__)
|
||||
extern sigset_t my_signals; /* signals blocked by mf_brkhant */
|
||||
#endif
|
1921
module/Vendor/MDBC/libmariadb/my_stmt.c
vendored
Normal file
1921
module/Vendor/MDBC/libmariadb/my_stmt.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1117
module/Vendor/MDBC/libmariadb/my_stmt_codec.c
vendored
Normal file
1117
module/Vendor/MDBC/libmariadb/my_stmt_codec.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
138
module/Vendor/MDBC/libmariadb/my_symlink.c
vendored
Normal file
138
module/Vendor/MDBC/libmariadb/my_symlink.c
vendored
Normal file
@ -0,0 +1,138 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include "mysys_err.h"
|
||||
#include <m_string.h>
|
||||
#include <errno.h>
|
||||
#ifdef HAVE_REALPATH
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
Reads the content of a symbolic link
|
||||
If the file is not a symbolic link, return the original file name in to.
|
||||
Returns: 0 if table was a symlink,
|
||||
1 if table was a normal file
|
||||
-1 on error.
|
||||
*/
|
||||
|
||||
int my_readlink(char *to, const char *filename, myf MyFlags)
|
||||
{
|
||||
#ifndef HAVE_READLINK
|
||||
strmov(to,filename);
|
||||
return 1;
|
||||
#else
|
||||
int result=0;
|
||||
int length;
|
||||
DBUG_ENTER("my_readlink");
|
||||
|
||||
if ((length=readlink(filename, to, FN_REFLEN-1)) < 0)
|
||||
{
|
||||
/* Don't give an error if this wasn't a symlink */
|
||||
if ((my_errno=errno) == EINVAL)
|
||||
{
|
||||
result= 1;
|
||||
strmov(to,filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MyFlags & MY_WME)
|
||||
my_error(EE_CANT_READLINK, MYF(0), filename, errno);
|
||||
result= -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
to[length]=0;
|
||||
DBUG_RETURN(result);
|
||||
#endif /* HAVE_READLINK */
|
||||
}
|
||||
|
||||
|
||||
/* Create a symbolic link */
|
||||
|
||||
int my_symlink(const char *content, const char *linkname, myf MyFlags)
|
||||
{
|
||||
#ifndef HAVE_READLINK
|
||||
return 0;
|
||||
#else
|
||||
int result;
|
||||
DBUG_ENTER("my_symlink");
|
||||
|
||||
result= 0;
|
||||
if (symlink(content, linkname))
|
||||
{
|
||||
result= -1;
|
||||
my_errno=errno;
|
||||
if (MyFlags & MY_WME)
|
||||
my_error(EE_CANT_SYMLINK, MYF(0), linkname, content, errno);
|
||||
}
|
||||
DBUG_RETURN(result);
|
||||
#endif /* HAVE_READLINK */
|
||||
}
|
||||
|
||||
/*
|
||||
Resolve all symbolic links in path
|
||||
'to' may be equal to 'filename'
|
||||
|
||||
Because purify gives a lot of UMR errors when using realpath(),
|
||||
this code is disabled when using purify.
|
||||
|
||||
If MY_RESOLVE_LINK is given, only do realpath if the file is a link.
|
||||
*/
|
||||
|
||||
#if defined(SCO)
|
||||
#define BUFF_LEN 4097
|
||||
#elif defined(MAXPATHLEN)
|
||||
#define BUFF_LEN MAXPATHLEN
|
||||
#else
|
||||
#define BUFF_LEN FN_LEN
|
||||
#endif
|
||||
|
||||
int my_realpath(char *to, const char *filename, myf MyFlags)
|
||||
{
|
||||
#if defined(HAVE_REALPATH) && !defined(HAVE_purify) && !defined(HAVE_BROKEN_REALPATH)
|
||||
int result=0;
|
||||
char buff[BUFF_LEN];
|
||||
struct stat stat_buff;
|
||||
DBUG_ENTER("my_realpath");
|
||||
|
||||
if (!(MyFlags & MY_RESOLVE_LINK) ||
|
||||
(!lstat(filename,&stat_buff) && S_ISLNK(stat_buff.st_mode)))
|
||||
{
|
||||
char *ptr;
|
||||
if ((ptr=realpath(filename,buff)))
|
||||
strmake(to,ptr,FN_REFLEN-1);
|
||||
else
|
||||
{
|
||||
/* Realpath didn't work; Use original name */
|
||||
my_errno=errno;
|
||||
if (MyFlags & MY_WME)
|
||||
my_error(EE_REALPATH, MYF(0), filename, my_errno);
|
||||
if (to != filename)
|
||||
strmov(to,filename);
|
||||
result= -1;
|
||||
}
|
||||
}
|
||||
DBUG_RETURN(result);
|
||||
#else
|
||||
if (to != filename)
|
||||
strmov(to,filename);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
246
module/Vendor/MDBC/libmariadb/my_thr_init.c
vendored
Normal file
246
module/Vendor/MDBC/libmariadb/my_thr_init.c
vendored
Normal file
@ -0,0 +1,246 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/*
|
||||
** Functions to handle initializating and allocationg of all mysys & debug
|
||||
** thread variables.
|
||||
*/
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include <m_string.h>
|
||||
#include <dbug.h>
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
|
||||
#ifdef THREAD
|
||||
#ifdef USE_TLS
|
||||
pthread_key(struct st_my_thread_var*, THR_KEY_mysys);
|
||||
#else
|
||||
pthread_key(struct st_my_thread_var, THR_KEY_mysys);
|
||||
#endif /* USE_TLS */
|
||||
pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,
|
||||
THR_LOCK_lock, THR_LOCK_net, THR_LOCK_mysys;
|
||||
#ifdef HAVE_OPENSSL
|
||||
pthread_mutex_t LOCK_ssl_config;
|
||||
#endif
|
||||
#ifndef HAVE_LOCALTIME_R
|
||||
pthread_mutex_t LOCK_localtime_r;
|
||||
#endif
|
||||
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
|
||||
pthread_mutexattr_t my_fast_mutexattr;
|
||||
#endif
|
||||
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
|
||||
pthread_mutexattr_t my_errchk_mutexattr;
|
||||
#endif
|
||||
my_bool THR_KEY_mysys_initialized= FALSE;
|
||||
|
||||
/* FIXME Note. TlsAlloc does not set an auto destructor, so
|
||||
the function my_thread_global_free must be called from
|
||||
somewhere before final exit of the library */
|
||||
|
||||
my_bool my_thread_global_init(void)
|
||||
{
|
||||
if (pthread_key_create(&THR_KEY_mysys,free))
|
||||
{
|
||||
fprintf(stderr,"Can't initialize threads: error %d\n",errno);
|
||||
exit(1);
|
||||
}
|
||||
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
|
||||
pthread_mutexattr_init(&my_fast_mutexattr);
|
||||
pthread_mutexattr_setkind_np(&my_fast_mutexattr,PTHREAD_MUTEX_ADAPTIVE_NP);
|
||||
#endif
|
||||
#ifdef PPTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
|
||||
pthread_mutexattr_init(&my_errchk_mutexattr);
|
||||
pthread_mutexattr_setkind_np(&my_errchk_mutexattr,
|
||||
PTHREAD_MUTEX_ERRORCHECK_NP);
|
||||
#endif
|
||||
THR_KEY_mysys_initialized= TRUE;
|
||||
#ifdef HAVE_OPENSSL
|
||||
pthread_mutex_init(&LOCK_ssl_config,MY_MUTEX_INIT_FAST);
|
||||
#endif
|
||||
pthread_mutex_init(&THR_LOCK_malloc,MY_MUTEX_INIT_FAST);
|
||||
pthread_mutex_init(&THR_LOCK_open,MY_MUTEX_INIT_FAST);
|
||||
pthread_mutex_init(&THR_LOCK_lock,MY_MUTEX_INIT_FAST);
|
||||
pthread_mutex_init(&THR_LOCK_net,MY_MUTEX_INIT_FAST);
|
||||
#ifdef _WIN32
|
||||
/* win_pthread_init(); */
|
||||
#endif
|
||||
#ifndef HAVE_LOCALTIME_R
|
||||
pthread_mutex_init(&LOCK_localtime_r,MY_MUTEX_INIT_SLOW);
|
||||
#endif
|
||||
return my_thread_init();
|
||||
}
|
||||
|
||||
void my_thread_global_end(void)
|
||||
{
|
||||
#if defined(USE_TLS)
|
||||
(void) TlsFree(THR_KEY_mysys);
|
||||
#endif
|
||||
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
|
||||
pthread_mutexattr_destroy(&my_fast_mutexattr);
|
||||
#endif
|
||||
#ifdef PPTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
|
||||
pthread_mutexattr_destroy(&my_errchk_mutexattr);
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL
|
||||
pthread_mutex_destroy(&LOCK_ssl_config);
|
||||
#endif
|
||||
}
|
||||
|
||||
static long thread_id=0;
|
||||
|
||||
/*
|
||||
We can't use mutex_locks here if we are using windows as
|
||||
we may have compiled the program with SAFE_MUTEX, in which
|
||||
case the checking of mutex_locks will not work until
|
||||
the pthread_self thread specific variable is initialized.
|
||||
*/
|
||||
|
||||
my_bool my_thread_init(void)
|
||||
{
|
||||
struct st_my_thread_var *tmp;
|
||||
if (my_pthread_getspecific(struct st_my_thread_var *,THR_KEY_mysys))
|
||||
{
|
||||
DBUG_PRINT("info", ("my_thread_init was already called. Thread id: %lu",
|
||||
pthread_self()));
|
||||
return 0; /* Safequard */
|
||||
}
|
||||
/* We must have many calloc() here because these are freed on
|
||||
pthread_exit */
|
||||
if (!(tmp=(struct st_my_thread_var *)
|
||||
calloc(1,sizeof(struct st_my_thread_var))))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
pthread_setspecific(THR_KEY_mysys,tmp);
|
||||
|
||||
if (tmp->initialized) /* Already initialized */
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST);
|
||||
pthread_cond_init(&tmp->suspend, NULL);
|
||||
pthread_mutex_lock(&THR_LOCK_lock);
|
||||
tmp->id= ++thread_id;
|
||||
pthread_mutex_unlock(&THR_LOCK_lock);
|
||||
tmp->initialized= TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void my_thread_end(void)
|
||||
{
|
||||
struct st_my_thread_var *tmp=
|
||||
my_pthread_getspecific(struct st_my_thread_var *, THR_KEY_mysys);
|
||||
|
||||
if (tmp && tmp->initialized)
|
||||
{
|
||||
#if defined(HAVE_OPENSSL) && OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
ERR_remove_thread_state(NULL);
|
||||
#endif
|
||||
#if !defined(DBUG_OFF)
|
||||
if (tmp->dbug)
|
||||
{
|
||||
DBUG_POP();
|
||||
free(tmp->dbug);
|
||||
tmp->dbug=0;
|
||||
}
|
||||
#endif
|
||||
#if !defined(__bsdi__) || defined(HAVE_mit_thread) /* bsdi dumps core here */
|
||||
pthread_cond_destroy(&tmp->suspend);
|
||||
#endif
|
||||
pthread_mutex_destroy(&tmp->mutex);
|
||||
free(tmp);
|
||||
pthread_setspecific(THR_KEY_mysys,0);
|
||||
}
|
||||
else
|
||||
pthread_setspecific(THR_KEY_mysys,0);
|
||||
}
|
||||
|
||||
struct st_my_thread_var *_my_thread_var(void)
|
||||
{
|
||||
struct st_my_thread_var *tmp=
|
||||
my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
|
||||
#if defined(USE_TLS)
|
||||
if (!tmp)
|
||||
{
|
||||
my_thread_init();
|
||||
tmp=my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
|
||||
}
|
||||
#endif
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
** Get name of current thread.
|
||||
****************************************************************************/
|
||||
|
||||
#define UNKNOWN_THREAD -1
|
||||
|
||||
long my_thread_id()
|
||||
{
|
||||
#if defined(HAVE_PTHREAD_GETSEQUENCE_NP)
|
||||
return pthread_getsequence_np(pthread_self());
|
||||
#elif (defined(__sun) || defined(__sgi) || defined(__linux__)) && !defined(HAVE_mit_thread)
|
||||
return pthread_self();
|
||||
#else
|
||||
return my_thread_var->id;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DBUG_OFF
|
||||
const char *my_thread_name(void)
|
||||
{
|
||||
return "no_name";
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
const char *my_thread_name(void)
|
||||
{
|
||||
char name_buff[100];
|
||||
struct st_my_thread_var *tmp=my_thread_var;
|
||||
if (!tmp->name[0])
|
||||
{
|
||||
long id=my_thread_id();
|
||||
sprintf(name_buff,"T@%ld", id);
|
||||
strmake(tmp->name,name_buff,THREAD_NAME_SIZE);
|
||||
}
|
||||
return tmp->name;
|
||||
}
|
||||
|
||||
extern void **my_thread_var_dbug()
|
||||
{
|
||||
struct st_my_thread_var *tmp;
|
||||
/*
|
||||
Instead of enforcing DBUG_ASSERT(THR_KEY_mysys_initialized) here,
|
||||
which causes any DBUG_ENTER and related traces to fail when
|
||||
used in init / cleanup code, we are more tolerant:
|
||||
using DBUG_ENTER / DBUG_PRINT / DBUG_RETURN
|
||||
when the dbug instrumentation is not in place will do nothing.
|
||||
*/
|
||||
if (! THR_KEY_mysys_initialized)
|
||||
return NULL;
|
||||
tmp= _my_thread_var();
|
||||
return tmp && tmp->initialized ? (void **)&tmp->dbug : 0;
|
||||
}
|
||||
#endif /* DBUG_OFF */
|
||||
|
||||
#endif /* THREAD */
|
119
module/Vendor/MDBC/libmariadb/my_vsnprintf.c
vendored
Normal file
119
module/Vendor/MDBC/libmariadb/my_vsnprintf.c
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, 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
|
||||
|
90
module/Vendor/MDBC/libmariadb/my_write.c
vendored
Normal file
90
module/Vendor/MDBC/libmariadb/my_write.c
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include "mysys_err.h"
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
/* Write a chunk of bytes to a file */
|
||||
|
||||
uint my_write(int Filedes, const unsigned char *Buffer, uint Count, myf MyFlags)
|
||||
{
|
||||
uint writenbytes,errors;
|
||||
ulong written;
|
||||
DBUG_ENTER("my_write");
|
||||
DBUG_PRINT("my",("Fd: %d Buffer: %lx Count: %d MyFlags: %d",
|
||||
Filedes, Buffer, Count, MyFlags));
|
||||
errors=0; written=0L;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if ((writenbytes = (uint) write(Filedes, Buffer, Count)) == Count)
|
||||
break;
|
||||
if ((int) writenbytes != -1)
|
||||
{ /* Safeguard */
|
||||
written+=writenbytes;
|
||||
Buffer+=writenbytes;
|
||||
Count-=writenbytes;
|
||||
}
|
||||
my_errno=errno;
|
||||
DBUG_PRINT("error",("Write only %d bytes, error: %d",
|
||||
writenbytes,my_errno));
|
||||
#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) &&
|
||||
(uint) writenbytes != (uint) -1)
|
||||
{
|
||||
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)
|
||||
{
|
||||
/* We may come here on an interrupt or if the file quote is exeeded */
|
||||
if (my_errno == EINTR)
|
||||
continue;
|
||||
if (!errors++) /* Retry once */
|
||||
{
|
||||
errno=EFBIG; /* Assume this is the error */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if ((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);
|
||||
} /* my_write */
|
2000
module/Vendor/MDBC/libmariadb/mysql_async.c
vendored
Normal file
2000
module/Vendor/MDBC/libmariadb/mysql_async.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
32
module/Vendor/MDBC/libmariadb/mysys_priv.h
vendored
Normal file
32
module/Vendor/MDBC/libmariadb/mysys_priv.h
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
#include <my_global.h>
|
||||
#include <my_sys.h>
|
||||
|
||||
#ifdef USE_SYSTEM_WRAPPERS
|
||||
#include "system_wrappers.h"
|
||||
#endif
|
||||
|
||||
#ifdef THREAD
|
||||
#include <my_pthread.h>
|
||||
extern pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,THR_LOCK_keycache,
|
||||
THR_LOCK_lock,THR_LOCK_isam,THR_LOCK_net,THR_LOCK_charset;
|
||||
extern pthread_mutex_t LOCK_bitmap;
|
||||
#else
|
||||
#include <my_no_pthread.h>
|
||||
#endif
|
868
module/Vendor/MDBC/libmariadb/net.c
vendored
Normal file
868
module/Vendor/MDBC/libmariadb/net.c
vendored
Normal file
@ -0,0 +1,868 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* Write and read of logical packets to/from socket
|
||||
** Writes are cached into net_buffer_length big packets.
|
||||
** Read packets are reallocated dynamicly when reading big packets.
|
||||
** Each logical packet has the following pre-info:
|
||||
** 3 byte length & 1 byte package-number.
|
||||
*/
|
||||
|
||||
#include <my_global.h>
|
||||
#include <violite.h>
|
||||
#include <my_sys.h>
|
||||
#include <m_string.h>
|
||||
#include "mysql.h"
|
||||
#include "mysqld_error.h"
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#ifndef _WIN32
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
#define MAX_PACKET_LENGTH (256L*256L*256L-1)
|
||||
|
||||
/* net_buffer_length and max_allowed_packet are defined in mysql.h
|
||||
See bug conc-57
|
||||
*/
|
||||
#undef net_buffer_length
|
||||
|
||||
#undef max_allowed_packet
|
||||
ulong max_allowed_packet=1024L * 1024L * 1024L;
|
||||
ulong net_read_timeout= NET_READ_TIMEOUT;
|
||||
ulong net_write_timeout= NET_WRITE_TIMEOUT;
|
||||
ulong net_buffer_length=8192; /* Default length. Enlarged if necessary */
|
||||
|
||||
#if !defined(_WIN32) && !defined(MSDOS)
|
||||
#include <sys/socket.h>
|
||||
#else
|
||||
#undef MYSQL_SERVER /* Win32 can't handle interrupts */
|
||||
#endif
|
||||
#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>
|
||||
#if !defined(alpha_linux_port)
|
||||
#include <netinet/tcp.h>
|
||||
#endif
|
||||
#endif
|
||||
#include "mysqld_error.h"
|
||||
#ifdef MYSQL_SERVER
|
||||
#include "my_pthread.h"
|
||||
#include "thr_alarm.h"
|
||||
void sql_print_error(const char *format,...);
|
||||
#define RETRY_COUNT mysqld_net_retry_count
|
||||
extern ulong mysqld_net_retry_count;
|
||||
#else
|
||||
|
||||
#ifdef OS2 /* avoid name conflict */
|
||||
#define thr_alarm_t thr_alarm_t_net
|
||||
#define ALARM ALARM_net
|
||||
#endif
|
||||
|
||||
typedef my_bool thr_alarm_t;
|
||||
typedef my_bool ALARM;
|
||||
#define thr_alarm_init(A) (*(A))=0
|
||||
#define thr_alarm_in_use(A) (*(A))
|
||||
#define thr_end_alarm(A)
|
||||
#define thr_alarm(A,B,C) local_thr_alarm((A),(B),(C))
|
||||
static inline int local_thr_alarm(my_bool *A,int B __attribute__((unused)),ALARM *C __attribute__((unused)))
|
||||
{
|
||||
*A=1;
|
||||
return 0;
|
||||
}
|
||||
#define thr_got_alarm(A) 0
|
||||
#define RETRY_COUNT 1
|
||||
#endif
|
||||
|
||||
#ifdef MYSQL_SERVER
|
||||
extern ulong bytes_sent, bytes_received;
|
||||
extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received;
|
||||
#else
|
||||
#undef statistic_add
|
||||
#define statistic_add(A,B,C)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Give error if a too big packet is found
|
||||
** The server can change this with the -O switch, but because the client
|
||||
** can't normally do this the client should have a bigger max-buffer.
|
||||
*/
|
||||
|
||||
#define TEST_BLOCKING 8
|
||||
static int net_write_buff(NET *net,const char *packet, size_t len);
|
||||
|
||||
|
||||
/* Init with packet info */
|
||||
|
||||
int my_net_init(NET *net, Vio* vio)
|
||||
{
|
||||
if (!(net->buff=(uchar*) my_malloc(net_buffer_length,MYF(MY_WME | MY_ZEROFILL))))
|
||||
return 1;
|
||||
max_allowed_packet= net->max_packet_size= MAX(net_buffer_length, max_allowed_packet);
|
||||
net->buff_end=net->buff+(net->max_packet=net_buffer_length);
|
||||
net->vio = vio;
|
||||
net->error=0; net->return_status=0;
|
||||
net->read_timeout=(uint) net_read_timeout; /* Timeout for read */
|
||||
net->compress_pkt_nr= net->pkt_nr= 0;
|
||||
net->write_pos=net->read_pos = net->buff;
|
||||
net->last_error[0]= net->sqlstate[0] =0;
|
||||
|
||||
net->compress=0; net->reading_or_writing=0;
|
||||
net->where_b = net->remain_in_buf=0;
|
||||
net->last_errno=0;
|
||||
|
||||
if (vio != 0) /* If real connection */
|
||||
{
|
||||
net->fd = vio_fd(vio); /* For perl DBI/DBD */
|
||||
#if defined(MYSQL_SERVER) && !defined(__WIN32) && !defined(__EMX__) && !defined(OS2)
|
||||
if (!(test_flags & TEST_BLOCKING))
|
||||
vio_blocking(vio, FALSE, 0);
|
||||
#endif
|
||||
vio_fastsend(vio);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void net_end(NET *net)
|
||||
{
|
||||
my_free(net->buff);
|
||||
net->buff=0;
|
||||
}
|
||||
|
||||
/* Realloc the packet buffer */
|
||||
|
||||
static my_bool net_realloc(NET *net, size_t length)
|
||||
{
|
||||
uchar *buff;
|
||||
size_t pkt_length;
|
||||
|
||||
DBUG_ENTER("net_realloc");
|
||||
DBUG_PRINT("info", ("length: %lu max_allowed_packet: %lu",
|
||||
(ulong)length, max_allowed_packet));
|
||||
|
||||
if (length >= net->max_packet_size)
|
||||
{
|
||||
DBUG_PRINT("error",("Packet too large (%lu)", length));
|
||||
net->error=1;
|
||||
net->last_errno=ER_NET_PACKET_TOO_LARGE;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
|
||||
/* reallocate buffer:
|
||||
size= pkt_length + NET_HEADER_SIZE + COMP_HEADER_SIZE */
|
||||
if (!(buff=(uchar*) my_realloc((char*) net->buff,
|
||||
pkt_length + NET_HEADER_SIZE + COMP_HEADER_SIZE,
|
||||
MYF(MY_WME))))
|
||||
{
|
||||
DBUG_PRINT("info", ("Out of memory"));
|
||||
net->error=1;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
net->buff=net->write_pos=buff;
|
||||
net->buff_end=buff+(net->max_packet=pkt_length);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
/* check if the socket is still alive */
|
||||
static my_bool net_check_socket_status(my_socket sock)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
struct pollfd poll_fd;
|
||||
#else
|
||||
FD_SET sfds;
|
||||
struct timeval tv= {0,0};
|
||||
#endif
|
||||
int res;
|
||||
#ifndef _WIN32
|
||||
memset(&poll_fd, 0, sizeof(struct pollfd));
|
||||
poll_fd.events= POLLPRI | POLLIN;
|
||||
poll_fd.fd= sock;
|
||||
|
||||
res= poll(&poll_fd, 1, 0);
|
||||
if (res <= 0) /* timeout or error */
|
||||
return FALSE;
|
||||
if (!(poll_fd.revents & (POLLIN | POLLPRI)))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
#else
|
||||
/* We can't use the WSAPoll function, it's broken :-(
|
||||
(see Windows 8 Bugs 309411 - WSAPoll does not report failed connections)
|
||||
Instead we need to use select function:
|
||||
If TIMEVAL is initialized to {0, 0}, select will return immediately;
|
||||
this is used to poll the state of the selected sockets.
|
||||
*/
|
||||
FD_ZERO(&sfds);
|
||||
FD_SET(sock, &sfds);
|
||||
|
||||
res= select(sock + 1, &sfds, NULL, NULL, &tv);
|
||||
if (res > 0 && FD_ISSET(sock, &sfds))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* Remove unwanted characters from connection */
|
||||
|
||||
void net_clear(NET *net)
|
||||
{
|
||||
DBUG_ENTER("net_clear");
|
||||
|
||||
/* see conc-71: we need to check the socket status first:
|
||||
if the socket is dead we set net->error, so net_flush
|
||||
will report an error */
|
||||
while (net_check_socket_status(net->vio->sd))
|
||||
{
|
||||
/* vio_read returns size_t. so casting to long is required to check for -1 */
|
||||
if ((long)vio_read(net->vio, (gptr)net->buff, (size_t) net->max_packet) <= 0)
|
||||
{
|
||||
net->error= 2;
|
||||
DBUG_PRINT("info", ("socket disconnected"));
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
}
|
||||
net->compress_pkt_nr= net->pkt_nr=0; /* Ready for new command */
|
||||
net->write_pos=net->buff;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
/* Flush write_buffer if not empty. */
|
||||
|
||||
int net_flush(NET *net)
|
||||
{
|
||||
int error=0;
|
||||
DBUG_ENTER("net_flush");
|
||||
if (net->buff != net->write_pos)
|
||||
{
|
||||
error=net_real_write(net,(char*) net->buff,
|
||||
(size_t) (net->write_pos - net->buff));
|
||||
net->write_pos=net->buff;
|
||||
}
|
||||
if (net->compress)
|
||||
net->pkt_nr= net->compress_pkt_nr;
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Write something to server/client buffer
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
** Write a logical packet with packet header
|
||||
** Format: Packet length (3 bytes), packet number(1 byte)
|
||||
** When compression is used a 3 byte compression length is added
|
||||
** NOTE: If compression is used the original package is destroyed!
|
||||
*/
|
||||
|
||||
int
|
||||
my_net_write(NET *net, const char *packet, size_t len)
|
||||
{
|
||||
uchar buff[NET_HEADER_SIZE];
|
||||
while (len >= MAX_PACKET_LENGTH)
|
||||
{
|
||||
const ulong max_len= MAX_PACKET_LENGTH;
|
||||
int3store(buff,max_len);
|
||||
buff[3]= (uchar)net->pkt_nr++;
|
||||
if (net_write_buff(net,(char*) buff,NET_HEADER_SIZE) ||
|
||||
net_write_buff(net, packet, max_len))
|
||||
return 1;
|
||||
packet+= max_len;
|
||||
len-= max_len;
|
||||
}
|
||||
/* write last remaining packet, size can be zero */
|
||||
int3store(buff, len);
|
||||
buff[3]= (uchar)net->pkt_nr++;
|
||||
if (net_write_buff(net,(char*) buff,NET_HEADER_SIZE) ||
|
||||
net_write_buff(net, packet, len))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
net_write_command(NET *net, uchar command,
|
||||
const char *packet, size_t len)
|
||||
{
|
||||
uchar buff[NET_HEADER_SIZE+1];
|
||||
size_t buff_size= NET_HEADER_SIZE + 1;
|
||||
size_t length= 1 + len; /* 1 extra byte for command */
|
||||
int rc;
|
||||
|
||||
buff[NET_HEADER_SIZE]= 0;
|
||||
buff[4]=command;
|
||||
|
||||
if (length >= MAX_PACKET_LENGTH)
|
||||
{
|
||||
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++);
|
||||
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, size_t len)
|
||||
{
|
||||
size_t left_length;
|
||||
|
||||
if (net->max_packet > MAX_PACKET_LENGTH &&
|
||||
net->compress)
|
||||
left_length= (size_t)(MAX_PACKET_LENGTH - (net->write_pos - net->buff));
|
||||
else
|
||||
left_length=(size_t) (net->buff_end - net->write_pos);
|
||||
|
||||
if (len > left_length)
|
||||
{
|
||||
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 (net->compress)
|
||||
{
|
||||
/* uncompressed length is stored in 3 bytes,so
|
||||
packet can't be > 0xFFFFFF */
|
||||
left_length= MAX_PACKET_LENGTH;
|
||||
while (len > left_length)
|
||||
{
|
||||
if (net_real_write(net, packet, left_length))
|
||||
return 1;
|
||||
packet+= left_length;
|
||||
len-= left_length;
|
||||
}
|
||||
}
|
||||
if (len > net->max_packet)
|
||||
return(test(net_real_write(net, packet, len)));
|
||||
}
|
||||
memcpy((char*) net->write_pos,packet,len);
|
||||
net->write_pos+=len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read and write using timeouts */
|
||||
|
||||
int
|
||||
net_real_write(NET *net,const char *packet,size_t len)
|
||||
{
|
||||
size_t length;
|
||||
char *pos,*end;
|
||||
thr_alarm_t alarmed;
|
||||
#if !defined(_WIN32) && !defined(__EMX__) && !defined(OS2)
|
||||
ALARM alarm_buff;
|
||||
#endif
|
||||
uint retry_count=0;
|
||||
my_bool net_blocking = vio_is_blocking(net->vio);
|
||||
DBUG_ENTER("net_real_write");
|
||||
|
||||
if (net->error == 2)
|
||||
DBUG_RETURN(-1); /* socket can't be used */
|
||||
|
||||
net->reading_or_writing=2;
|
||||
#ifdef HAVE_COMPRESS
|
||||
if (net->compress)
|
||||
{
|
||||
size_t complen;
|
||||
uchar *b;
|
||||
uint header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE;
|
||||
if (!(b=(uchar*) my_malloc(len + NET_HEADER_SIZE + COMP_HEADER_SIZE + 1,
|
||||
MYF(MY_WME))))
|
||||
{
|
||||
net->last_errno=ER_OUT_OF_RESOURCES;
|
||||
net->error=2;
|
||||
net->reading_or_writing=0;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
memcpy(b+header_length,packet,len);
|
||||
|
||||
if (my_compress((unsigned char*) b+header_length,&len,&complen))
|
||||
{
|
||||
DBUG_PRINT("warning",
|
||||
("Compression error; Continuing without compression"));
|
||||
complen=0;
|
||||
}
|
||||
int3store(&b[NET_HEADER_SIZE],complen);
|
||||
int3store(b,len);
|
||||
b[3]=(uchar) (net->compress_pkt_nr++);
|
||||
len+= header_length;
|
||||
packet= (char*) b;
|
||||
}
|
||||
#endif /* HAVE_COMPRESS */
|
||||
|
||||
alarmed=0;
|
||||
|
||||
pos=(char*) packet; end=pos+len;
|
||||
while (pos != end)
|
||||
{
|
||||
if ((long) (length=vio_write(net->vio,pos,(size_t) (end-pos))) <= 0)
|
||||
{
|
||||
my_bool interrupted = vio_should_retry(net->vio);
|
||||
#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))
|
||||
{ /* Always true for client */
|
||||
if (!vio_is_blocking(net->vio))
|
||||
{
|
||||
while (vio_blocking(net->vio, TRUE, 0) < 0)
|
||||
{
|
||||
if (vio_should_retry(net->vio) && retry_count++ < RETRY_COUNT)
|
||||
continue;
|
||||
#ifdef EXTRA_DEBUG
|
||||
fprintf(stderr,
|
||||
"%s: my_net_write: fcntl returned error %d, aborting thread\n",
|
||||
my_progname,vio_errno(net->vio));
|
||||
#endif /* EXTRA_DEBUG */
|
||||
net->error=2; /* Close socket */
|
||||
net->last_errno= (interrupted ?
|
||||
ER_NET_WRITE_INTERRUPTED : ER_NET_ERROR_ON_WRITE);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
retry_count=0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* (!defined(_WIN32) && !defined(__EMX__)) */
|
||||
if (thr_alarm_in_use(&alarmed) && !thr_got_alarm(&alarmed) &&
|
||||
interrupted)
|
||||
{
|
||||
if (retry_count++ < RETRY_COUNT)
|
||||
continue;
|
||||
#ifdef EXTRA_DEBUG
|
||||
fprintf(stderr, "%s: write looped, aborting thread\n",
|
||||
my_progname);
|
||||
#endif /* EXTRA_DEBUG */
|
||||
}
|
||||
#if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER)
|
||||
if (vio_errno(net->vio) == SOCKET_EINTR)
|
||||
{
|
||||
DBUG_PRINT("warning",("Interrupted write. Retrying..."));
|
||||
continue;
|
||||
}
|
||||
#endif /* defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) */
|
||||
net->error=2; /* Close socket */
|
||||
net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED :
|
||||
ER_NET_ERROR_ON_WRITE);
|
||||
break;
|
||||
}
|
||||
pos+=length;
|
||||
statistic_add(bytes_sent,length,&LOCK_bytes_sent);
|
||||
}
|
||||
#ifndef _WIN32
|
||||
end:
|
||||
#endif
|
||||
#ifdef HAVE_COMPRESS
|
||||
if (net->compress)
|
||||
my_free((void *)packet);
|
||||
#endif
|
||||
if (thr_alarm_in_use(&alarmed))
|
||||
{
|
||||
thr_end_alarm(&alarmed);
|
||||
vio_blocking(net->vio, net_blocking, 0);
|
||||
}
|
||||
net->reading_or_writing=0;
|
||||
DBUG_RETURN(((int) (pos != end)));
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Read something from server/clinet
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef MYSQL_SERVER
|
||||
|
||||
/*
|
||||
Help function to clear the commuication buffer when we get a too
|
||||
big packet
|
||||
*/
|
||||
|
||||
static void my_net_skip_rest(NET *net, ulong remain, thr_alarm_t *alarmed,
|
||||
ALARM *alarm_buff)
|
||||
{
|
||||
uint retry_count=0;
|
||||
if (!thr_alarm_in_use(alarmed))
|
||||
{
|
||||
if (thr_alarm(alarmed,net->timeout,alarm_buff) ||
|
||||
(!vio_is_blocking(net->vio) && vio_blocking(net->vio,TRUE, 0) < 0))
|
||||
return; /* Can't setup, abort */
|
||||
}
|
||||
while (remain > 0)
|
||||
{
|
||||
ulong length;
|
||||
if ((int) (length=vio_read(net->vio,(char*) net->buff,remain)) <= 0L)
|
||||
{
|
||||
my_bool interrupted = vio_should_retry(net->vio);
|
||||
if (!thr_got_alarm(alarmed) && interrupted)
|
||||
{ /* Probably in MIT threads */
|
||||
if (retry_count++ < RETRY_COUNT)
|
||||
continue;
|
||||
}
|
||||
return;
|
||||
}
|
||||
remain -=(ulong) length;
|
||||
statistic_add(bytes_received,(ulong) length,&LOCK_bytes_received);
|
||||
}
|
||||
}
|
||||
#endif /* MYSQL_SERVER */
|
||||
|
||||
|
||||
static ulong
|
||||
my_real_read(NET *net, size_t *complen)
|
||||
{
|
||||
uchar *pos;
|
||||
size_t length;
|
||||
uint i,retry_count=0;
|
||||
ulong len=packet_error;
|
||||
thr_alarm_t alarmed;
|
||||
#if (!defined(_WIN32) && !defined(__EMX__) && !defined(OS2)) || defined(MYSQL_SERVER)
|
||||
ALARM alarm_buff;
|
||||
#endif
|
||||
my_bool net_blocking=vio_is_blocking(net->vio);
|
||||
size_t remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE :
|
||||
NET_HEADER_SIZE);
|
||||
*complen = 0;
|
||||
|
||||
net->reading_or_writing=1;
|
||||
thr_alarm_init(&alarmed);
|
||||
#ifdef MYSQL_SERVER
|
||||
if (net_blocking)
|
||||
thr_alarm(&alarmed,net->timeout,&alarm_buff);
|
||||
#endif /* MYSQL_SERVER */
|
||||
|
||||
pos = net->buff + net->where_b; /* net->packet -4 */
|
||||
for (i=0 ; i < 2 ; i++)
|
||||
{
|
||||
while (remain > 0)
|
||||
{
|
||||
/* First read is done with non blocking mode */
|
||||
if ((long) (length=vio_read(net->vio,(char*) pos,remain)) <= 0L)
|
||||
{
|
||||
my_bool interrupted = vio_should_retry(net->vio);
|
||||
|
||||
DBUG_PRINT("info",("vio_read returned %d, errno: %d",
|
||||
length, vio_errno(net->vio)));
|
||||
#if (!defined(_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
|
||||
mode and try again
|
||||
*/
|
||||
if ((interrupted || length == 0) && !thr_alarm_in_use(&alarmed))
|
||||
{
|
||||
if (!thr_alarm(&alarmed,net->read_timeout,&alarm_buff)) /* Don't wait too long */
|
||||
{
|
||||
if (!vio_is_blocking(net->vio))
|
||||
{
|
||||
while (vio_blocking(net->vio,TRUE, 0) < 0)
|
||||
{
|
||||
if (vio_should_retry(net->vio) &&
|
||||
retry_count++ < RETRY_COUNT)
|
||||
continue;
|
||||
DBUG_PRINT("error",
|
||||
("fcntl returned error %d, aborting thread",
|
||||
vio_errno(net->vio)));
|
||||
#ifdef EXTRA_DEBUG
|
||||
fprintf(stderr,
|
||||
"%s: read: fcntl returned error %d, aborting thread\n",
|
||||
my_progname,vio_errno(net->vio));
|
||||
#endif /* EXTRA_DEBUG */
|
||||
len= packet_error;
|
||||
net->error=2; /* Close socket */
|
||||
#ifdef MYSQL_SERVER
|
||||
net->last_errno=ER_NET_FCNTL_ERROR;
|
||||
#endif
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
retry_count=0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif /* (!defined(_WIN32) && !defined(__EMX__)) || defined(MYSQL_SERVER) */
|
||||
if (thr_alarm_in_use(&alarmed) && !thr_got_alarm(&alarmed) &&
|
||||
interrupted)
|
||||
{ /* Probably in MIT threads */
|
||||
if (retry_count++ < RETRY_COUNT)
|
||||
continue;
|
||||
#ifdef EXTRA_DEBUG
|
||||
fprintf(stderr, "%s: read looped with error %d, aborting thread\n",
|
||||
my_progname,vio_errno(net->vio));
|
||||
#endif /* EXTRA_DEBUG */
|
||||
}
|
||||
#if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER)
|
||||
if (vio_should_retry(net->vio))
|
||||
{
|
||||
DBUG_PRINT("warning",("Interrupted read. Retrying..."));
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
DBUG_PRINT("error",("Couldn't read packet: remain: %d errno: %d length: %d alarmed: %d", remain,vio_errno(net->vio),length,alarmed));
|
||||
len= packet_error;
|
||||
net->error=2; /* Close socket */
|
||||
goto end;
|
||||
}
|
||||
remain -= (ulong) length;
|
||||
pos+= (ulong) length;
|
||||
statistic_add(bytes_received,(ulong) length,&LOCK_bytes_received);
|
||||
}
|
||||
if (i == 0)
|
||||
{ /* First parts is packet length */
|
||||
ulong helping;
|
||||
if (net->buff[net->where_b + 3] != (uchar) net->pkt_nr)
|
||||
{
|
||||
if (net->buff[net->where_b] != (uchar) 255)
|
||||
{
|
||||
DBUG_PRINT("error",
|
||||
("Packets out of order (Found: %d, expected %d)",
|
||||
(int) net->buff[net->where_b + 3],
|
||||
(uint) (uchar) net->pkt_nr));
|
||||
#ifdef EXTRA_DEBUG
|
||||
fprintf(stderr,"Packets out of order (Found: %d, expected %d)\n",
|
||||
(int) net->buff[net->where_b + 3],
|
||||
(uint) (uchar) net->pkt_nr);
|
||||
#endif
|
||||
}
|
||||
len= packet_error;
|
||||
#ifdef MYSQL_SERVER
|
||||
net->last_errno=ER_NET_PACKETS_OUT_OF_ORDER;
|
||||
#endif
|
||||
goto end;
|
||||
}
|
||||
net->compress_pkt_nr= ++net->pkt_nr;
|
||||
#ifdef HAVE_COMPRESS
|
||||
if (net->compress)
|
||||
{
|
||||
/* complen is > 0 if package is really compressed */
|
||||
*complen=uint3korr(&(net->buff[net->where_b + NET_HEADER_SIZE]));
|
||||
}
|
||||
#endif
|
||||
|
||||
len=uint3korr(net->buff+net->where_b);
|
||||
if (!len)
|
||||
goto end;
|
||||
helping = max(len,(ulong)*complen) + net->where_b;
|
||||
/* The necessary size of net->buff */
|
||||
if (helping >= net->max_packet)
|
||||
{
|
||||
if (net_realloc(net,helping))
|
||||
{
|
||||
#ifdef MYSQL_SERVER
|
||||
if (i == 1)
|
||||
my_net_skip_rest(net, len, &alarmed, &alarm_buff);
|
||||
#endif
|
||||
len= packet_error; /* Return error */
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
pos=net->buff + net->where_b;
|
||||
remain = len;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
if (thr_alarm_in_use(&alarmed))
|
||||
{
|
||||
thr_end_alarm(&alarmed);
|
||||
vio_blocking(net->vio, net_blocking, 0);
|
||||
}
|
||||
net->reading_or_writing=0;
|
||||
return(len);
|
||||
}
|
||||
|
||||
ulong my_net_read(NET *net)
|
||||
{
|
||||
size_t len,complen;
|
||||
|
||||
#ifdef HAVE_COMPRESS
|
||||
if (!net->compress)
|
||||
{
|
||||
#endif
|
||||
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+= (unsigned long)len;
|
||||
len= my_real_read(net, &complen);
|
||||
} 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 */
|
||||
return (ulong)len;
|
||||
#ifdef HAVE_COMPRESS
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
compressed protocol:
|
||||
|
||||
--------------------------------------
|
||||
packet_lengt h 3
|
||||
sequence_id 1
|
||||
uncompressed_length 3
|
||||
--------------------------------------
|
||||
compressed data packet_length - 7
|
||||
--------------------------------------
|
||||
|
||||
Another packet will follow if:
|
||||
packet_length == MAX_PACKET_LENGTH
|
||||
|
||||
Last package will be identified by
|
||||
- packet_length is zero (special case)
|
||||
- packet_length < MAX_PACKET_LENGTH
|
||||
*/
|
||||
|
||||
size_t packet_length,
|
||||
buffer_length;
|
||||
size_t current= 0, start= 0;
|
||||
my_bool is_multi_packet= 0;
|
||||
|
||||
/* check if buffer is empty */
|
||||
if (!net->remain_in_buf)
|
||||
{
|
||||
buffer_length= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* save position and restore \0 character */
|
||||
buffer_length= net->buf_length;
|
||||
current= net->buf_length - net->remain_in_buf;
|
||||
start= current;
|
||||
net->buff[net->buf_length - net->remain_in_buf]=net->save_char;
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
if (buffer_length - current >= 4)
|
||||
{
|
||||
uchar *pos= net->buff + current;
|
||||
packet_length= uint3korr(pos);
|
||||
|
||||
/* check if we have last package (special case: zero length) */
|
||||
if (!packet_length)
|
||||
{
|
||||
current+= 4; /* length + sequence_id,
|
||||
no more data will follow */
|
||||
break;
|
||||
}
|
||||
if (packet_length + 4 <= buffer_length - current)
|
||||
{
|
||||
if (!is_multi_packet)
|
||||
{
|
||||
current= current + packet_length + 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* remove packet_header */
|
||||
memmove(net->buff + current,
|
||||
net->buff + current + 4,
|
||||
buffer_length - current);
|
||||
buffer_length-= 4;
|
||||
current+= packet_length;
|
||||
}
|
||||
/* do we have last packet ? */
|
||||
if (packet_length != MAX_PACKET_LENGTH)
|
||||
{
|
||||
is_multi_packet= 0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
is_multi_packet= 1;
|
||||
if (start)
|
||||
{
|
||||
memmove(net->buff, net->buff + start,
|
||||
buffer_length - start);
|
||||
/* decrease buflen*/
|
||||
buffer_length-= start;
|
||||
start= 0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (start)
|
||||
{
|
||||
memmove(net->buff, net->buff + start, buffer_length - start);
|
||||
/* decrease buflen and current */
|
||||
current -= start;
|
||||
buffer_length-= start;
|
||||
start= 0;
|
||||
}
|
||||
|
||||
net->where_b=buffer_length;
|
||||
|
||||
if ((packet_length = my_real_read(net,(size_t *)&complen)) == packet_error)
|
||||
return packet_error;
|
||||
if (my_uncompress((unsigned char*) net->buff + net->where_b, &packet_length, &complen))
|
||||
{
|
||||
len= packet_error;
|
||||
net->error=2; /* caller will close socket */
|
||||
net->last_errno=ER_NET_UNCOMPRESS_ERROR;
|
||||
break;
|
||||
return packet_error;
|
||||
}
|
||||
buffer_length+= complen;
|
||||
}
|
||||
/* set values */
|
||||
net->buf_length= buffer_length;
|
||||
net->remain_in_buf= buffer_length - current;
|
||||
net->read_pos= net->buff + start + 4;
|
||||
len= current - start - 4;
|
||||
if (is_multi_packet)
|
||||
len-= 4;
|
||||
net->save_char= net->read_pos[len]; /* Must be saved */
|
||||
net->read_pos[len]=0; /* Safeguard for mysql_use_result */
|
||||
}
|
||||
#endif
|
||||
return (ulong)len;
|
||||
}
|
234
module/Vendor/MDBC/libmariadb/password.c
vendored
Normal file
234
module/Vendor/MDBC/libmariadb/password.c
vendored
Normal file
@ -0,0 +1,234 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* password checking routines */
|
||||
/*****************************************************************************
|
||||
The main idea is that no password are sent between client & server on
|
||||
connection and that no password are saved in mysql in a decodable form.
|
||||
|
||||
On connection a random string is generated and sent to the client.
|
||||
The client generates a new string with a random generator inited with
|
||||
the hash values from the password and the sent string.
|
||||
This 'check' string is sent to the server where it is compared with
|
||||
a string generated from the stored hash_value of the password and the
|
||||
random string.
|
||||
|
||||
The password is saved (in user.password) by using the PASSWORD() function in
|
||||
mysql.
|
||||
|
||||
Example:
|
||||
update user set password=PASSWORD("hello") where user="test"
|
||||
This saves a hashed number as a string in the password field.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <my_global.h>
|
||||
#include <my_sys.h>
|
||||
#include <m_string.h>
|
||||
#include <sha1.h>
|
||||
#include "mysql.h"
|
||||
|
||||
|
||||
void randominit(struct rand_struct *rand_st,ulong seed1, ulong seed2)
|
||||
{ /* For mysql 3.21.# */
|
||||
#ifdef HAVE_purify
|
||||
bzero((char*) rand_st,sizeof(*rand_st)); /* Avoid UMC varnings */
|
||||
#endif
|
||||
rand_st->max_value= 0x3FFFFFFFL;
|
||||
rand_st->max_value_dbl=(double) rand_st->max_value;
|
||||
rand_st->seed1=seed1%rand_st->max_value ;
|
||||
rand_st->seed2=seed2%rand_st->max_value;
|
||||
}
|
||||
|
||||
static void old_randominit(struct rand_struct *rand_st,ulong seed1)
|
||||
{ /* For mysql 3.20.# */
|
||||
rand_st->max_value= 0x01FFFFFFL;
|
||||
rand_st->max_value_dbl=(double) rand_st->max_value;
|
||||
seed1%=rand_st->max_value;
|
||||
rand_st->seed1=seed1 ; rand_st->seed2=seed1/2;
|
||||
}
|
||||
|
||||
double rnd(struct rand_struct *rand_st)
|
||||
{
|
||||
rand_st->seed1=(rand_st->seed1*3+rand_st->seed2) % rand_st->max_value;
|
||||
rand_st->seed2=(rand_st->seed1+rand_st->seed2+33) % rand_st->max_value;
|
||||
return (((double) rand_st->seed1)/rand_st->max_value_dbl);
|
||||
}
|
||||
|
||||
void hash_password(ulong *result, const char *password, size_t len)
|
||||
{
|
||||
register ulong nr=1345345333L, add=7, nr2=0x12345671L;
|
||||
ulong tmp;
|
||||
const char *password_end= password + len;
|
||||
for (; password < password_end; password++)
|
||||
{
|
||||
if (*password == ' ' || *password == '\t')
|
||||
continue; /* skipp space in password */
|
||||
tmp= (ulong) (uchar) *password;
|
||||
nr^= (((nr & 63)+add)*tmp)+ (nr << 8);
|
||||
nr2+=(nr2 << 8) ^ nr;
|
||||
add+=tmp;
|
||||
}
|
||||
result[0]=nr & (((ulong) 1L << 31) -1L); /* Don't use sign bit (str2int) */;
|
||||
result[1]=nr2 & (((ulong) 1L << 31) -1L);
|
||||
return;
|
||||
}
|
||||
|
||||
static inline unsigned int char_val(char X)
|
||||
{
|
||||
return (uint) (X >= '0' && X <= '9' ? X-'0' :
|
||||
X >= 'A' && X <= 'Z' ? X-'A'+10 :
|
||||
X-'a'+10);
|
||||
}
|
||||
|
||||
/*
|
||||
* Genererate a new message based on message and password
|
||||
* The same thing is done in client and server and the results are checked.
|
||||
*/
|
||||
|
||||
/* scramble for 4.1 servers
|
||||
* Code based on php_nysqlnd_scramble function from PHP's mysqlnd extension,
|
||||
* written by Andrey Hristov (andrey@php.net)
|
||||
* License: PHP License 3.0
|
||||
*/
|
||||
void my_crypt(unsigned char *buffer, const unsigned char *s1, const unsigned char *s2, size_t len)
|
||||
{
|
||||
const unsigned char *s1_end= s1 + len;
|
||||
while (s1 < s1_end) {
|
||||
*buffer++= *s1++ ^ *s2++;
|
||||
}
|
||||
}
|
||||
|
||||
void my_scramble_41(const unsigned char *buffer, const char *scramble, const char *password)
|
||||
{
|
||||
MYSQL_SHA1_CTX context;
|
||||
unsigned char sha1[SHA1_MAX_LENGTH];
|
||||
unsigned char sha2[SHA1_MAX_LENGTH];
|
||||
|
||||
|
||||
/* Phase 1: hash password */
|
||||
MYSQL_SHA1Init(&context);
|
||||
MYSQL_SHA1Update(&context, (unsigned char *)password, strlen((char *)password));
|
||||
MYSQL_SHA1Final(sha1, &context);
|
||||
|
||||
/* Phase 2: hash sha1 */
|
||||
MYSQL_SHA1Init(&context);
|
||||
MYSQL_SHA1Update(&context, (unsigned char*)sha1, SHA1_MAX_LENGTH);
|
||||
MYSQL_SHA1Final(sha2, &context);
|
||||
|
||||
/* Phase 3: hash scramble + sha2 */
|
||||
MYSQL_SHA1Init(&context);
|
||||
MYSQL_SHA1Update(&context, (unsigned char *)scramble, SCRAMBLE_LENGTH);
|
||||
MYSQL_SHA1Update(&context, (unsigned char*)sha2, SHA1_MAX_LENGTH);
|
||||
MYSQL_SHA1Final((unsigned char *)buffer, &context);
|
||||
|
||||
/* let's crypt buffer now */
|
||||
my_crypt((uchar *)buffer, (const unsigned char *)buffer, (const unsigned char *)sha1, SHA1_MAX_LENGTH);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
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 extra, *to_start=to;
|
||||
const char *end_scramble323= message + SCRAMBLE_LENGTH_323;
|
||||
hash_password(hash_pass,password, (uint) strlen(password));
|
||||
/* Don't use strlen, could be > SCRAMBLE_LENGTH_323 ! */
|
||||
hash_password(hash_message, message, SCRAMBLE_LENGTH_323);
|
||||
randominit(&rand_st, hash_pass[0] ^ hash_message[0],
|
||||
hash_pass[1] ^ hash_message[1]);
|
||||
for (; message < end_scramble323; message++)
|
||||
*to++= (char) (floor(rnd(&rand_st) * 31) + 64);
|
||||
extra=(char) (floor(rnd(&rand_st) * 31));
|
||||
while (to_start != to)
|
||||
*(to_start++)^= extra;
|
||||
}
|
||||
*to= 0;
|
||||
return to;
|
||||
}
|
||||
|
||||
my_bool check_scramble(const char *scrambled, const char *message,
|
||||
ulong *hash_pass, my_bool old_ver)
|
||||
{
|
||||
struct rand_struct rand_st;
|
||||
ulong hash_message[2];
|
||||
char buff[16],*to,extra; /* Big enough for check */
|
||||
const char *pos;
|
||||
|
||||
hash_password(hash_message,message, strlen(message));
|
||||
if (old_ver)
|
||||
old_randominit(&rand_st,hash_pass[0] ^ hash_message[0]);
|
||||
else
|
||||
randominit(&rand_st,hash_pass[0] ^ hash_message[0],
|
||||
hash_pass[1] ^ hash_message[1]);
|
||||
to=buff;
|
||||
for (pos=scrambled ; *pos ; pos++)
|
||||
*to++=(char) (floor(rnd(&rand_st)*31)+64);
|
||||
if (old_ver)
|
||||
extra=0;
|
||||
else
|
||||
extra=(char) (floor(rnd(&rand_st)*31));
|
||||
to=buff;
|
||||
while (*scrambled)
|
||||
{
|
||||
if (*scrambled++ != (char) (*to++ ^ extra))
|
||||
return 1; /* Wrong password */
|
||||
}
|
||||
return 0;
|
||||
}
|
325
module/Vendor/MDBC/libmariadb/sha1.c
vendored
Normal file
325
module/Vendor/MDBC/libmariadb/sha1.c
vendored
Normal file
@ -0,0 +1,325 @@
|
||||
/****************************************************************************
|
||||
Copyright (C) 2012 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
|
||||
*****************************************************************************/
|
||||
|
||||
/* This code came from the PHP project, initially written by
|
||||
Stefan Esser */
|
||||
|
||||
|
||||
#include "my_global.h"
|
||||
#include "string.h"
|
||||
|
||||
/* This code is heavily based on the PHP md5 implementation */
|
||||
|
||||
#include "sha1.h"
|
||||
|
||||
|
||||
static void SHA1Transform(uint32[5], const unsigned char[64]);
|
||||
static void SHA1Encode(unsigned char *, uint32 *, unsigned int);
|
||||
static void SHA1Decode(uint32 *, const unsigned char *, unsigned int);
|
||||
|
||||
static unsigned char PADDING[64] =
|
||||
{
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/* F, G, H and I are basic SHA1 functions.
|
||||
*/
|
||||
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
|
||||
#define G(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define H(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
|
||||
#define I(x, y, z) ((x) ^ (y) ^ (z))
|
||||
|
||||
/* ROTATE_LEFT rotates x left n bits.
|
||||
*/
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||
|
||||
/* W[i]
|
||||
*/
|
||||
#define W(i) ( tmp=x[(i-3)&15]^x[(i-8)&15]^x[(i-14)&15]^x[i&15], \
|
||||
(x[i&15]=ROTATE_LEFT(tmp, 1)) )
|
||||
|
||||
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
|
||||
*/
|
||||
#define FF(a, b, c, d, e, w) { \
|
||||
(e) += F ((b), (c), (d)) + (w) + (uint32)(0x5A827999); \
|
||||
(e) += ROTATE_LEFT ((a), 5); \
|
||||
(b) = ROTATE_LEFT((b), 30); \
|
||||
}
|
||||
#define GG(a, b, c, d, e, w) { \
|
||||
(e) += G ((b), (c), (d)) + (w) + (uint32)(0x6ED9EBA1); \
|
||||
(e) += ROTATE_LEFT ((a), 5); \
|
||||
(b) = ROTATE_LEFT((b), 30); \
|
||||
}
|
||||
#define HH(a, b, c, d, e, w) { \
|
||||
(e) += H ((b), (c), (d)) + (w) + (uint32)(0x8F1BBCDC); \
|
||||
(e) += ROTATE_LEFT ((a), 5); \
|
||||
(b) = ROTATE_LEFT((b), 30); \
|
||||
}
|
||||
#define II(a, b, c, d, e, w) { \
|
||||
(e) += I ((b), (c), (d)) + (w) + (uint32)(0xCA62C1D6); \
|
||||
(e) += ROTATE_LEFT ((a), 5); \
|
||||
(b) = ROTATE_LEFT((b), 30); \
|
||||
}
|
||||
|
||||
|
||||
/* {{{ MYSQL_SHA1Init
|
||||
* SHA1 initialization. Begins an SHA1 operation, writing a new context.
|
||||
*/
|
||||
void MYSQL_SHA1Init(MYSQL_SHA1_CTX * context)
|
||||
{
|
||||
context->count[0] = context->count[1] = 0;
|
||||
/* Load magic initialization constants.
|
||||
*/
|
||||
context->state[0] = 0x67452301;
|
||||
context->state[1] = 0xefcdab89;
|
||||
context->state[2] = 0x98badcfe;
|
||||
context->state[3] = 0x10325476;
|
||||
context->state[4] = 0xc3d2e1f0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ MYSQL_SHA1Update
|
||||
SHA1 block update operation. Continues an SHA1 message-digest
|
||||
operation, processing another message block, and updating the
|
||||
context.
|
||||
*/
|
||||
void MYSQL_SHA1Update(MYSQL_SHA1_CTX * context, const unsigned char *input,
|
||||
size_t inputLen)
|
||||
{
|
||||
unsigned int i, index, partLen;
|
||||
|
||||
/* Compute number of bytes mod 64 */
|
||||
index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
|
||||
|
||||
/* Update number of bits */
|
||||
if ((context->count[0] += ((uint32) inputLen << 3))
|
||||
< ((uint32) inputLen << 3))
|
||||
context->count[1]++;
|
||||
context->count[1] += ((uint32) inputLen >> 29);
|
||||
|
||||
partLen = 64 - index;
|
||||
|
||||
/* Transform as many times as possible.
|
||||
*/
|
||||
if (inputLen >= partLen) {
|
||||
memcpy
|
||||
((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
|
||||
SHA1Transform(context->state, context->buffer);
|
||||
|
||||
for (i = partLen; i + 63 < inputLen; i += 64)
|
||||
SHA1Transform(context->state, &input[i]);
|
||||
|
||||
index = 0;
|
||||
} else
|
||||
i = 0;
|
||||
|
||||
/* Buffer remaining input */
|
||||
memcpy
|
||||
((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
|
||||
inputLen - i);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ MYSQL_SHA1Final
|
||||
SHA1 finalization. Ends an SHA1 message-digest operation, writing the
|
||||
the message digest and zeroizing the context.
|
||||
*/
|
||||
void MYSQL_SHA1Final(unsigned char digest[20], MYSQL_SHA1_CTX * context)
|
||||
{
|
||||
unsigned char bits[8];
|
||||
unsigned int index, padLen;
|
||||
|
||||
/* Save number of bits */
|
||||
bits[7] = context->count[0] & 0xFF;
|
||||
bits[6] = (context->count[0] >> 8) & 0xFF;
|
||||
bits[5] = (context->count[0] >> 16) & 0xFF;
|
||||
bits[4] = (context->count[0] >> 24) & 0xFF;
|
||||
bits[3] = context->count[1] & 0xFF;
|
||||
bits[2] = (context->count[1] >> 8) & 0xFF;
|
||||
bits[1] = (context->count[1] >> 16) & 0xFF;
|
||||
bits[0] = (context->count[1] >> 24) & 0xFF;
|
||||
|
||||
/* Pad out to 56 mod 64.
|
||||
*/
|
||||
index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
|
||||
padLen = (index < 56) ? (56 - index) : (120 - index);
|
||||
MYSQL_SHA1Update(context, PADDING, padLen);
|
||||
|
||||
/* Append length (before padding) */
|
||||
MYSQL_SHA1Update(context, bits, 8);
|
||||
|
||||
/* Store state in digest */
|
||||
SHA1Encode(digest, context->state, 20);
|
||||
|
||||
/* Zeroize sensitive information.
|
||||
*/
|
||||
memset((unsigned char*) context, 0, sizeof(*context));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ SHA1Transform
|
||||
* SHA1 basic transformation. Transforms state based on block.
|
||||
*/
|
||||
static void SHA1Transform(uint32 state[5], const unsigned char block[64])
|
||||
{
|
||||
uint32 a = state[0], b = state[1], c = state[2];
|
||||
uint32 d = state[3], e = state[4], x[16], tmp;
|
||||
|
||||
SHA1Decode(x, block, 64);
|
||||
|
||||
/* Round 1 */
|
||||
FF(a, b, c, d, e, x[0]); /* 1 */
|
||||
FF(e, a, b, c, d, x[1]); /* 2 */
|
||||
FF(d, e, a, b, c, x[2]); /* 3 */
|
||||
FF(c, d, e, a, b, x[3]); /* 4 */
|
||||
FF(b, c, d, e, a, x[4]); /* 5 */
|
||||
FF(a, b, c, d, e, x[5]); /* 6 */
|
||||
FF(e, a, b, c, d, x[6]); /* 7 */
|
||||
FF(d, e, a, b, c, x[7]); /* 8 */
|
||||
FF(c, d, e, a, b, x[8]); /* 9 */
|
||||
FF(b, c, d, e, a, x[9]); /* 10 */
|
||||
FF(a, b, c, d, e, x[10]); /* 11 */
|
||||
FF(e, a, b, c, d, x[11]); /* 12 */
|
||||
FF(d, e, a, b, c, x[12]); /* 13 */
|
||||
FF(c, d, e, a, b, x[13]); /* 14 */
|
||||
FF(b, c, d, e, a, x[14]); /* 15 */
|
||||
FF(a, b, c, d, e, x[15]); /* 16 */
|
||||
FF(e, a, b, c, d, W(16)); /* 17 */
|
||||
FF(d, e, a, b, c, W(17)); /* 18 */
|
||||
FF(c, d, e, a, b, W(18)); /* 19 */
|
||||
FF(b, c, d, e, a, W(19)); /* 20 */
|
||||
|
||||
/* Round 2 */
|
||||
GG(a, b, c, d, e, W(20)); /* 21 */
|
||||
GG(e, a, b, c, d, W(21)); /* 22 */
|
||||
GG(d, e, a, b, c, W(22)); /* 23 */
|
||||
GG(c, d, e, a, b, W(23)); /* 24 */
|
||||
GG(b, c, d, e, a, W(24)); /* 25 */
|
||||
GG(a, b, c, d, e, W(25)); /* 26 */
|
||||
GG(e, a, b, c, d, W(26)); /* 27 */
|
||||
GG(d, e, a, b, c, W(27)); /* 28 */
|
||||
GG(c, d, e, a, b, W(28)); /* 29 */
|
||||
GG(b, c, d, e, a, W(29)); /* 30 */
|
||||
GG(a, b, c, d, e, W(30)); /* 31 */
|
||||
GG(e, a, b, c, d, W(31)); /* 32 */
|
||||
GG(d, e, a, b, c, W(32)); /* 33 */
|
||||
GG(c, d, e, a, b, W(33)); /* 34 */
|
||||
GG(b, c, d, e, a, W(34)); /* 35 */
|
||||
GG(a, b, c, d, e, W(35)); /* 36 */
|
||||
GG(e, a, b, c, d, W(36)); /* 37 */
|
||||
GG(d, e, a, b, c, W(37)); /* 38 */
|
||||
GG(c, d, e, a, b, W(38)); /* 39 */
|
||||
GG(b, c, d, e, a, W(39)); /* 40 */
|
||||
|
||||
/* Round 3 */
|
||||
HH(a, b, c, d, e, W(40)); /* 41 */
|
||||
HH(e, a, b, c, d, W(41)); /* 42 */
|
||||
HH(d, e, a, b, c, W(42)); /* 43 */
|
||||
HH(c, d, e, a, b, W(43)); /* 44 */
|
||||
HH(b, c, d, e, a, W(44)); /* 45 */
|
||||
HH(a, b, c, d, e, W(45)); /* 46 */
|
||||
HH(e, a, b, c, d, W(46)); /* 47 */
|
||||
HH(d, e, a, b, c, W(47)); /* 48 */
|
||||
HH(c, d, e, a, b, W(48)); /* 49 */
|
||||
HH(b, c, d, e, a, W(49)); /* 50 */
|
||||
HH(a, b, c, d, e, W(50)); /* 51 */
|
||||
HH(e, a, b, c, d, W(51)); /* 52 */
|
||||
HH(d, e, a, b, c, W(52)); /* 53 */
|
||||
HH(c, d, e, a, b, W(53)); /* 54 */
|
||||
HH(b, c, d, e, a, W(54)); /* 55 */
|
||||
HH(a, b, c, d, e, W(55)); /* 56 */
|
||||
HH(e, a, b, c, d, W(56)); /* 57 */
|
||||
HH(d, e, a, b, c, W(57)); /* 58 */
|
||||
HH(c, d, e, a, b, W(58)); /* 59 */
|
||||
HH(b, c, d, e, a, W(59)); /* 60 */
|
||||
|
||||
/* Round 4 */
|
||||
II(a, b, c, d, e, W(60)); /* 61 */
|
||||
II(e, a, b, c, d, W(61)); /* 62 */
|
||||
II(d, e, a, b, c, W(62)); /* 63 */
|
||||
II(c, d, e, a, b, W(63)); /* 64 */
|
||||
II(b, c, d, e, a, W(64)); /* 65 */
|
||||
II(a, b, c, d, e, W(65)); /* 66 */
|
||||
II(e, a, b, c, d, W(66)); /* 67 */
|
||||
II(d, e, a, b, c, W(67)); /* 68 */
|
||||
II(c, d, e, a, b, W(68)); /* 69 */
|
||||
II(b, c, d, e, a, W(69)); /* 70 */
|
||||
II(a, b, c, d, e, W(70)); /* 71 */
|
||||
II(e, a, b, c, d, W(71)); /* 72 */
|
||||
II(d, e, a, b, c, W(72)); /* 73 */
|
||||
II(c, d, e, a, b, W(73)); /* 74 */
|
||||
II(b, c, d, e, a, W(74)); /* 75 */
|
||||
II(a, b, c, d, e, W(75)); /* 76 */
|
||||
II(e, a, b, c, d, W(76)); /* 77 */
|
||||
II(d, e, a, b, c, W(77)); /* 78 */
|
||||
II(c, d, e, a, b, W(78)); /* 79 */
|
||||
II(b, c, d, e, a, W(79)); /* 80 */
|
||||
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
state[4] += e;
|
||||
|
||||
/* Zeroize sensitive information. */
|
||||
memset((unsigned char*) x, 0, sizeof(x));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ SHA1Encode
|
||||
Encodes input (uint32) into output (unsigned char). Assumes len is
|
||||
a multiple of 4.
|
||||
*/
|
||||
static void SHA1Encode(unsigned char *output, uint32 *input, unsigned int len)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4) {
|
||||
output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
|
||||
output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
|
||||
output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
|
||||
output[j + 3] = (unsigned char) (input[i] & 0xff);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ SHA1Decode
|
||||
Decodes input (unsigned char) into output (uint32). Assumes len is
|
||||
a multiple of 4.
|
||||
*/
|
||||
static void SHA1Decode(uint32 *output, const unsigned char * input, unsigned int len)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||
output[i] = ((uint32) input[j + 3]) | (((uint32) input[j + 2]) << 8) |
|
||||
(((uint32) input[j + 1]) << 16) | (((uint32) input[j]) << 24);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: sw=4 ts=4 fdm=marker
|
||||
* vim<600: sw=4 ts=4
|
||||
*/
|
202
module/Vendor/MDBC/libmariadb/str2int.c
vendored
Normal file
202
module/Vendor/MDBC/libmariadb/str2int.c
vendored
Normal file
@ -0,0 +1,202 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/*
|
||||
str2int(src, radix, lower, upper, &val)
|
||||
converts the string pointed to by src to an integer and stores it in
|
||||
val. 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. The result should satisfy lower <= *val <= upper.
|
||||
The result is a pointer to the first character after the number;
|
||||
trailing spaces will NOT be skipped.
|
||||
|
||||
If an error is detected, the result will be NullS, the value put
|
||||
in val will be 0, and errno will be set to
|
||||
EDOM if there are no digits
|
||||
ERANGE if the result would overflow or otherwise fail to lie
|
||||
within the specified bounds.
|
||||
Check that the bounds are right for your machine.
|
||||
This looks amazingly complicated for what you probably thought was an
|
||||
easy task. Coping with integer overflow and the asymmetric range of
|
||||
twos complement machines is anything but easy.
|
||||
|
||||
So that users of atoi and atol can check whether an error occured,
|
||||
I have taken a wholly unprecedented step: errno is CLEARED if this
|
||||
call has no problems.
|
||||
*/
|
||||
|
||||
#include <my_global.h>
|
||||
#include "m_string.h"
|
||||
#include "m_ctype.h"
|
||||
#include "my_sys.h" /* defines errno */
|
||||
#include <errno.h>
|
||||
|
||||
#define char_val(X) (X >= '0' && X <= '9' ? X-'0' :\
|
||||
X >= 'A' && X <= 'Z' ? X-'A'+10 :\
|
||||
X >= 'a' && X <= 'z' ? X-'a'+10 :\
|
||||
'\177')
|
||||
|
||||
char *str2int(register const char *src, register int radix, long int lower, long int upper, long int *val)
|
||||
{
|
||||
int sign; /* is number negative (+1) or positive (-1) */
|
||||
int n; /* number of digits yet to be converted */
|
||||
long limit; /* "largest" possible valid input */
|
||||
long scale; /* the amount to multiply next digit by */
|
||||
long sofar; /* the running value */
|
||||
register int d; /* (negative of) next digit */
|
||||
char *start;
|
||||
int digits[32]; /* Room for numbers */
|
||||
|
||||
/* Make sure *val is sensible in case of error */
|
||||
|
||||
*val = 0;
|
||||
|
||||
/* Check that the radix is in the range 2..36 */
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
if (radix < 2 || radix > 36) {
|
||||
errno=EDOM;
|
||||
return NullS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The basic problem is: how do we handle the conversion of
|
||||
a number without resorting to machine-specific code to
|
||||
check for overflow? Obviously, we have to ensure that
|
||||
no calculation can overflow. We are guaranteed that the
|
||||
"lower" and "upper" arguments are valid machine integers.
|
||||
On sign-and-magnitude, twos-complement, and ones-complement
|
||||
machines all, if +|n| is representable, so is -|n|, but on
|
||||
twos complement machines the converse is not true. So the
|
||||
"maximum" representable number has a negative representative.
|
||||
Limit is set to min(-|lower|,-|upper|); this is the "largest"
|
||||
number we are concerned with. */
|
||||
|
||||
/* Calculate Limit using Scale as a scratch variable */
|
||||
|
||||
if ((limit = lower) > 0) limit = -limit;
|
||||
if ((scale = upper) > 0) scale = -scale;
|
||||
if (scale < limit) limit = scale;
|
||||
|
||||
/* Skip leading spaces and check for a sign.
|
||||
Note: because on a 2s complement machine MinLong is a valid
|
||||
integer but |MinLong| is not, we have to keep the current
|
||||
converted value (and the scale!) as *negative* numbers,
|
||||
so the sign is the opposite of what you might expect.
|
||||
*/
|
||||
while (isspace(*src)) src++;
|
||||
sign = -1;
|
||||
if (*src == '+') src++; else
|
||||
if (*src == '-') src++, sign = 1;
|
||||
|
||||
/* Skip leading zeros so that we never compute a power of radix
|
||||
in scale that we won't have a need for. Otherwise sticking
|
||||
enough 0s in front of a number could cause the multiplication
|
||||
to overflow when it neededn't.
|
||||
*/
|
||||
start=(char*) src;
|
||||
while (*src == '0') src++;
|
||||
|
||||
/* Move over the remaining digits. We have to convert from left
|
||||
to left in order to avoid overflow. Answer is after last digit.
|
||||
*/
|
||||
|
||||
for (n = 0; (digits[n]=char_val(*src)) < radix && n < 20; n++,src++) ;
|
||||
|
||||
/* Check that there is at least one digit */
|
||||
|
||||
if (start == src) {
|
||||
errno=EDOM;
|
||||
return NullS;
|
||||
}
|
||||
|
||||
/* The invariant we want to maintain is that src is just
|
||||
to the right of n digits, we've converted k digits to
|
||||
sofar, scale = -radix**k, and scale < sofar < 0. Now
|
||||
if the final number is to be within the original
|
||||
Limit, we must have (to the left)*scale+sofar >= Limit,
|
||||
or (to the left)*scale >= Limit-sofar, i.e. the digits
|
||||
to the left of src must form an integer <= (Limit-sofar)/(scale).
|
||||
In particular, this is true of the next digit. In our
|
||||
incremental calculation of Limit,
|
||||
|
||||
IT IS VITAL that (-|N|)/(-|D|) = |N|/|D|
|
||||
*/
|
||||
|
||||
for (sofar = 0, scale = -1; --n >= 1;)
|
||||
{
|
||||
if ((long) -(d=digits[n]) < limit) {
|
||||
errno=ERANGE;
|
||||
return NullS;
|
||||
}
|
||||
limit = (limit+d)/radix, sofar += d*scale; scale *= radix;
|
||||
}
|
||||
if (n == 0)
|
||||
{
|
||||
if ((long) -(d=digits[n]) < limit) /* get last digit */
|
||||
{
|
||||
errno=ERANGE;
|
||||
return NullS;
|
||||
}
|
||||
sofar+=d*scale;
|
||||
}
|
||||
|
||||
/* Now it might still happen that sofar = -32768 or its equivalent,
|
||||
so we can't just multiply by the sign and check that the result
|
||||
is in the range lower..upper. All of this caution is a right
|
||||
pain in the neck. If only there were a standard routine which
|
||||
says generate thus and such a signal on integer overflow...
|
||||
But not enough machines can do it *SIGH*.
|
||||
*/
|
||||
if (sign < 0)
|
||||
{
|
||||
if (sofar < -LONG_MAX || (sofar= -sofar) > upper)
|
||||
{
|
||||
errno=ERANGE;
|
||||
return NullS;
|
||||
}
|
||||
}
|
||||
else if (sofar < lower)
|
||||
{
|
||||
errno=ERANGE;
|
||||
return NullS;
|
||||
}
|
||||
*val = sofar;
|
||||
errno=0; /* indicate that all went well */
|
||||
return (char*) src;
|
||||
}
|
||||
|
||||
/* Theese are so slow compared with ordinary, optimized atoi */
|
||||
|
||||
#ifdef WANT_OUR_ATOI
|
||||
|
||||
int atoi(const char *src)
|
||||
{
|
||||
long val;
|
||||
str2int(src, 10, (long) INT_MIN, (long) INT_MAX, &val);
|
||||
return (int) val;
|
||||
}
|
||||
|
||||
|
||||
long atol(const char *src)
|
||||
{
|
||||
long val;
|
||||
str2int(src, 10, LONG_MIN, LONG_MAX, &val);
|
||||
return val;
|
||||
}
|
||||
|
||||
#endif /* WANT_OUR_ATOI */
|
48
module/Vendor/MDBC/libmariadb/strcend.c
vendored
Normal file
48
module/Vendor/MDBC/libmariadb/strcend.c
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* File : strcend.c
|
||||
Author : Michael Widenius: ifdef MC68000
|
||||
Updated: 20 April 1984
|
||||
Defines: strcend()
|
||||
|
||||
strcend(s, c) returns a pointer to the first place in s where c
|
||||
occurs, or a pointer to the end-null of s if c does not occur in s.
|
||||
*/
|
||||
|
||||
#include <my_global.h>
|
||||
#include "m_string.h"
|
||||
|
||||
/**
|
||||
\fn char *strcend
|
||||
\brief returns a pointer to the first occurence of specified stopchar
|
||||
\param str char *
|
||||
\param stopchar char
|
||||
|
||||
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 (*str == stopchar)
|
||||
return (char*) str;
|
||||
if (!*str++)
|
||||
return (char*) str-1;
|
||||
}
|
||||
}
|
46
module/Vendor/MDBC/libmariadb/strcont.c
vendored
Normal file
46
module/Vendor/MDBC/libmariadb/strcont.c
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* File : strcont.c
|
||||
Author : Monty
|
||||
Updated: 1988.07.27
|
||||
Defines: strcont()
|
||||
|
||||
strcont(str, set) if str contanies any character in the string set.
|
||||
The result is the position of the first found character in str, or NullS
|
||||
if there isn't anything found.
|
||||
|
||||
*/
|
||||
|
||||
#include <my_global.h>
|
||||
#include "m_string.h"
|
||||
|
||||
my_string strcont(reg1 const char *str,reg2 const char *set)
|
||||
{
|
||||
reg3 my_string start = (my_string) set;
|
||||
|
||||
while (*str)
|
||||
{
|
||||
while (*set)
|
||||
{
|
||||
if (*set++ == *str)
|
||||
return ((char*) str);
|
||||
}
|
||||
set=start; str++;
|
||||
}
|
||||
return (NullS);
|
||||
} /* strcont */
|
50
module/Vendor/MDBC/libmariadb/strend.c
vendored
Normal file
50
module/Vendor/MDBC/libmariadb/strend.c
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
/* Copyright (C) 2002 MySQL 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* File : strend.c
|
||||
Author : Richard A. O'Keefe.
|
||||
Updated: 23 April 1984
|
||||
Defines: strend()
|
||||
|
||||
strend(s) returns a character pointer to the NUL which ends s. That
|
||||
is, strend(s)-s == strlen(s). This is useful for adding things at
|
||||
the end of strings. It is redundant, because strchr(s,'\0') could
|
||||
be used instead, but this is clearer and faster.
|
||||
Beware: the asm version works only if strlen(s) < 65535.
|
||||
*/
|
||||
|
||||
#include <my_global.h>
|
||||
#include "m_string.h"
|
||||
|
||||
#if VaxAsm
|
||||
|
||||
char *strend(s)
|
||||
const char *s;
|
||||
{
|
||||
asm("locc $0,$65535,*4(ap)");
|
||||
asm("movl r1,r0");
|
||||
}
|
||||
|
||||
#else /* ~VaxAsm */
|
||||
|
||||
char *strend(register const char *s)
|
||||
{
|
||||
while (*s++);
|
||||
return (char*) (s-1);
|
||||
}
|
||||
|
||||
#endif /* VaxAsm */
|
36
module/Vendor/MDBC/libmariadb/strfill.c
vendored
Normal file
36
module/Vendor/MDBC/libmariadb/strfill.c
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* File : strfill.c
|
||||
Author : Monty
|
||||
Updated: 1987.04.16
|
||||
Defines: strfill()
|
||||
|
||||
strfill(dest, len, fill) makes a string of fill-characters. The result
|
||||
string is of length == len. The des+len character is allways set to NULL.
|
||||
strfill() returns pointer to dest+len;
|
||||
*/
|
||||
|
||||
#include <my_global.h>
|
||||
#include "m_string.h"
|
||||
|
||||
my_string strfill(my_string s, size_t len, pchar fill)
|
||||
{
|
||||
while (len--) *s++ = fill;
|
||||
*(s) = '\0';
|
||||
return(s);
|
||||
} /* strfill */
|
127
module/Vendor/MDBC/libmariadb/string.c
vendored
Normal file
127
module/Vendor/MDBC/libmariadb/string.c
vendored
Normal file
@ -0,0 +1,127 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/*
|
||||
Code for handling strings with can grow dynamicly.
|
||||
Copyright Monty Program KB.
|
||||
By monty.
|
||||
*/
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include <m_string.h>
|
||||
|
||||
my_bool init_dynamic_string(DYNAMIC_STRING *str, const char *init_str,
|
||||
size_t init_alloc, size_t alloc_increment)
|
||||
{
|
||||
uint length;
|
||||
DBUG_ENTER("init_dynamic_string");
|
||||
|
||||
if (!alloc_increment)
|
||||
alloc_increment=128;
|
||||
length=1;
|
||||
if (init_str && (length= (uint) strlen(init_str)+1) < init_alloc)
|
||||
init_alloc=((length+alloc_increment-1)/alloc_increment)*alloc_increment;
|
||||
if (!init_alloc)
|
||||
init_alloc=alloc_increment;
|
||||
|
||||
if (!(str->str=(char*) my_malloc(init_alloc,MYF(MY_WME))))
|
||||
DBUG_RETURN(TRUE);
|
||||
str->length=length-1;
|
||||
if (init_str)
|
||||
memcpy(str->str,init_str,length);
|
||||
str->max_length=init_alloc;
|
||||
str->alloc_increment=alloc_increment;
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
||||
my_bool dynstr_set(DYNAMIC_STRING *str, const char *init_str)
|
||||
{
|
||||
uint length;
|
||||
DBUG_ENTER("dynstr_set");
|
||||
|
||||
if (init_str && (length= (uint) strlen(init_str)+1) > str->max_length)
|
||||
{
|
||||
str->max_length=((length+str->alloc_increment-1)/str->alloc_increment)*
|
||||
str->alloc_increment;
|
||||
if (!str->max_length)
|
||||
str->max_length=str->alloc_increment;
|
||||
if (!(str->str=(char*) my_realloc(str->str,str->max_length,MYF(MY_WME))))
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
if (init_str)
|
||||
{
|
||||
str->length=length-1;
|
||||
memcpy(str->str,init_str,length);
|
||||
}
|
||||
else
|
||||
str->length=0;
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
||||
my_bool dynstr_realloc(DYNAMIC_STRING *str, size_t additional_size)
|
||||
{
|
||||
DBUG_ENTER("dynstr_realloc");
|
||||
|
||||
if (!additional_size) DBUG_RETURN(FALSE);
|
||||
if (str->length + additional_size > str->max_length)
|
||||
{
|
||||
str->max_length=((str->length + additional_size+str->alloc_increment-1)/
|
||||
str->alloc_increment)*str->alloc_increment;
|
||||
if (!(str->str=(char*) my_realloc(str->str,str->max_length,MYF(MY_WME))))
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
||||
my_bool dynstr_append(DYNAMIC_STRING *str, const char *append)
|
||||
{
|
||||
return dynstr_append_mem(str,append,strlen(append));
|
||||
}
|
||||
|
||||
|
||||
my_bool dynstr_append_mem(DYNAMIC_STRING *str, const char *append,
|
||||
size_t length)
|
||||
{
|
||||
char *new_ptr;
|
||||
if (str->length+length >= str->max_length)
|
||||
{
|
||||
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))))
|
||||
return TRUE;
|
||||
str->str=new_ptr;
|
||||
str->max_length=new_length;
|
||||
}
|
||||
memcpy(str->str + str->length,append,length);
|
||||
str->length+=length;
|
||||
str->str[str->length]=0; /* Safety for C programs */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
void dynstr_free(DYNAMIC_STRING *str)
|
||||
{
|
||||
if (str->str)
|
||||
{
|
||||
my_free(str->str);
|
||||
str->str=0;
|
||||
}
|
||||
}
|
50
module/Vendor/MDBC/libmariadb/strinstr.c
vendored
Normal file
50
module/Vendor/MDBC/libmariadb/strinstr.c
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* File : strinstr.c
|
||||
Author : Monty & David
|
||||
Updated: 1986.12.08
|
||||
Defines: strinstr()
|
||||
|
||||
strinstr(src, pat) looks for an instance of pat in src. pat is not a
|
||||
regex(3) pattern, it is a literal string which must be matched exactly.
|
||||
The result 0 if the pattern was not found else it is the start char of
|
||||
the pattern counted from the beginning of the string, where the first
|
||||
char is 1.
|
||||
*/
|
||||
|
||||
#include <my_global.h>
|
||||
#include "m_string.h"
|
||||
|
||||
uint strinstr(reg1 const char *str,reg4 const char *search)
|
||||
{
|
||||
reg2 my_string i,j;
|
||||
my_string start = (my_string) str;
|
||||
|
||||
skipp:
|
||||
while (*str != '\0')
|
||||
{
|
||||
if (*str++ == *search)
|
||||
{
|
||||
i=(my_string) str; j= (my_string) search+1;
|
||||
while (*j)
|
||||
if (*i++ != *j++) goto skipp;
|
||||
return ((uint) (str - start));
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
54
module/Vendor/MDBC/libmariadb/strmake.c
vendored
Normal file
54
module/Vendor/MDBC/libmariadb/strmake.c
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* File : strmake.c
|
||||
Author : Michael Widenius
|
||||
Updated: 20 Jul 1984
|
||||
Defines: strmake()
|
||||
|
||||
strmake(dst,src,length) moves length characters, or until end, of src to
|
||||
dst and appends a closing NUL to dst.
|
||||
Note that is strlen(src) >= length then dst[length] will be set to \0
|
||||
strmake() returns pointer to closing null
|
||||
*/
|
||||
|
||||
#include <my_global.h>
|
||||
#include "m_string.h"
|
||||
|
||||
#ifdef BAD_STRING_COMPILER
|
||||
|
||||
char *strmake(char *dst,const char *src, size_t length)
|
||||
{
|
||||
reg1 char *res;
|
||||
|
||||
if ((res=memccpy(dst,src,0,length)))
|
||||
return res-1;
|
||||
dst[length]=0;
|
||||
return dst+length;
|
||||
}
|
||||
|
||||
#define strmake strmake_overlapp /* Use orginal for overlapping str */
|
||||
#endif
|
||||
|
||||
char *strmake(register char *dst, register const char *src, size_t length)
|
||||
{
|
||||
while (length--)
|
||||
if (! (*dst++ = *src++))
|
||||
return dst-1;
|
||||
*dst=0;
|
||||
return dst;
|
||||
}
|
59
module/Vendor/MDBC/libmariadb/strmov.c
vendored
Normal file
59
module/Vendor/MDBC/libmariadb/strmov.c
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/*
|
||||
strmov(dst, src) moves all the characters of src (including the
|
||||
closing NUL) to dst, and returns a pointer to the new closing NUL in
|
||||
dst. The similar UNIX routine strcpy returns the old value of dst,
|
||||
which I have never found useful. strmov(strmov(dst,a),b) moves a//b
|
||||
into dst, which seems useful.
|
||||
*/
|
||||
|
||||
#include <my_global.h>
|
||||
#include "m_string.h"
|
||||
|
||||
#ifdef BAD_STRING_COMPILER
|
||||
#undef strmov
|
||||
#define strmov strmov_overlapp
|
||||
#endif
|
||||
|
||||
#ifndef strmov
|
||||
|
||||
#if !defined(MC68000) && !defined(DS90)
|
||||
|
||||
char *strmov(register char *dst, register const char *src)
|
||||
{
|
||||
while ((*dst++ = *src++)) ;
|
||||
return dst-1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
char *strmov(dst, src)
|
||||
char *dst, *src;
|
||||
{
|
||||
asm(" movl 4(a7),a1 ");
|
||||
asm(" movl 8(a7),a0 ");
|
||||
asm(".L4: movb (a0)+,(a1)+ ");
|
||||
asm(" jne .L4 ");
|
||||
asm(" movl a1,d0 ");
|
||||
asm(" subql #1,d0 ");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* strmov */
|
36
module/Vendor/MDBC/libmariadb/strnlen.c
vendored
Normal file
36
module/Vendor/MDBC/libmariadb/strnlen.c
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* File : strnlen.c
|
||||
Author : Michael Widenius
|
||||
Updated: 20 April 1984
|
||||
Defines: strnlen.
|
||||
strnlen(s, len) returns the length of s or len if s is longer than len.
|
||||
*/
|
||||
|
||||
#include <my_global.h>
|
||||
#include "m_string.h"
|
||||
|
||||
#ifndef HAVE_STRNLEN
|
||||
|
||||
uint strnlen(register const char *s, register uint maxlen)
|
||||
{
|
||||
const char *end= (const char *)memchr(s, '\0', maxlen);
|
||||
return end ? (uint) (end - s) : maxlen;
|
||||
}
|
||||
|
||||
#endif
|
36
module/Vendor/MDBC/libmariadb/strnmov.c
vendored
Normal file
36
module/Vendor/MDBC/libmariadb/strnmov.c
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/*
|
||||
strnmov(dst,src,length) moves length characters, or until end, of src to
|
||||
dst and appends a closing NUL to dst if src is shorter than length.
|
||||
The result is a pointer to the first NUL in dst, or is dst+n if dst was
|
||||
truncated.
|
||||
*/
|
||||
|
||||
#include <my_global.h>
|
||||
#include "m_string.h"
|
||||
|
||||
char *strnmov(register char *dst, register const char *src, uint n)
|
||||
{
|
||||
while (n-- != 0) {
|
||||
if (!(*dst++ = *src++)) {
|
||||
return (char*) dst-1;
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
}
|
209
module/Vendor/MDBC/libmariadb/strto.c
vendored
Normal file
209
module/Vendor/MDBC/libmariadb/strto.c
vendored
Normal file
@ -0,0 +1,209 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, 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 "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;
|
||||
}
|
198
module/Vendor/MDBC/libmariadb/strtoll.c
vendored
Normal file
198
module/Vendor/MDBC/libmariadb/strtoll.c
vendored
Normal file
@ -0,0 +1,198 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* This is defines strtoll() if neaded */
|
||||
|
||||
#include <my_global.h>
|
||||
#include <m_string.h>
|
||||
#if !defined(HAVE_STRTOLL) && defined(HAVE_LONG_LONG)
|
||||
#define USE_LONGLONG
|
||||
|
||||
#define strtoll glob_strtoll /* Fix for True64 */
|
||||
|
||||
#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
|
26
module/Vendor/MDBC/libmariadb/strtoull.c
vendored
Normal file
26
module/Vendor/MDBC/libmariadb/strtoull.c
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* This is defines strtoull() */
|
||||
|
||||
#include <my_global.h>
|
||||
#include <m_string.h>
|
||||
#if !defined(HAVE_STRTOULL) && defined(HAVE_LONG_LONG)
|
||||
#define USE_UNSIGNED
|
||||
#define USE_LONGLONG
|
||||
#include "strto.c"
|
||||
#endif
|
50
module/Vendor/MDBC/libmariadb/strxmov.c
vendored
Normal file
50
module/Vendor/MDBC/libmariadb/strxmov.c
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
/* Copyright (C) 2002 MySQL 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* File : strxmov.c
|
||||
Author : Richard A. O'Keefe.
|
||||
Updated: 25 may 1984
|
||||
Defines: strxmov()
|
||||
|
||||
strxmov(dst, src1, ..., srcn, NullS)
|
||||
moves the concatenation of src1,...,srcn to dst, terminates it
|
||||
with a NUL character, and returns a pointer to the terminating NUL.
|
||||
It is just like strmov 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.
|
||||
*/
|
||||
|
||||
#include <my_global.h>
|
||||
#include "m_string.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
char *strxmov(char *dst,const char *src, ...)
|
||||
{
|
||||
va_list pvar;
|
||||
|
||||
va_start(pvar,src);
|
||||
while (src != NullS) {
|
||||
while ((*dst++ = *src++)) ;
|
||||
dst--;
|
||||
src = va_arg(pvar, char *);
|
||||
}
|
||||
va_end(pvar);
|
||||
*dst = 0; /* there might have been no sources! */
|
||||
return dst;
|
||||
}
|
48
module/Vendor/MDBC/libmariadb/strxnmov.c
vendored
Normal file
48
module/Vendor/MDBC/libmariadb/strxnmov.c
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
/* File : strxnmov.c
|
||||
Author : Richard A. O'Keefe.
|
||||
Updated: 2 June 1984
|
||||
Defines: strxnmov()
|
||||
|
||||
strxnmov(dst, len, src1, ..., srcn, NullS)
|
||||
moves the first len characters of the concatenation of src1,...,srcn
|
||||
to dst. If there aren't that many characters, a NUL character will
|
||||
be added to the end of dst to terminate it properly. This gives the
|
||||
same effect as calling strxcpy(buff, src1, ..., srcn, NullS) with a
|
||||
large enough buffer, and then calling strnmov(dst, buff, len).
|
||||
It is just like strnmov except that it concatenates multiple sources.
|
||||
Beware: the last argument should be the null character pointer.
|
||||
Take VERY great care not to omit it! Also be careful to use NullS
|
||||
and NOT to use 0, as on some machines 0 is not the same size as a
|
||||
character pointer, or not the same bit pattern as NullS.
|
||||
|
||||
Note: strxnmov is like strnmov in that it moves up to len
|
||||
characters; dst will be padded on the right with one NUL characters if
|
||||
needed.
|
||||
*/
|
||||
|
||||
#include <my_global.h>
|
||||
#include "m_string.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
char *strxnmov(char *dst, size_t len, const char *src, ...)
|
||||
{
|
||||
va_list pvar;
|
||||
char *end_of_dst=dst+len;
|
||||
|
||||
va_start(pvar,src);
|
||||
while (src != NullS)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (dst == end_of_dst)
|
||||
goto end;
|
||||
}
|
||||
while ((*dst++ = *src++));
|
||||
dst--;
|
||||
src = va_arg(pvar, char *);
|
||||
}
|
||||
*dst=0;
|
||||
end:
|
||||
va_end(pvar);
|
||||
return dst;
|
||||
}
|
231
module/Vendor/MDBC/libmariadb/thr_mutex.c
vendored
Normal file
231
module/Vendor/MDBC/libmariadb/thr_mutex.c
vendored
Normal file
@ -0,0 +1,231 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* This makes a wrapper for mutex handling to make it easier to debug mutex */
|
||||
|
||||
#include <my_global.h>
|
||||
#if defined(HAVE_LINUXTHREADS) && !defined (__USE_UNIX98)
|
||||
#define __USE_UNIX98 /* To get rw locks under Linux */
|
||||
#endif
|
||||
#include <m_string.h>
|
||||
#if defined(THREAD) && defined(SAFE_MUTEX)
|
||||
#undef SAFE_MUTEX /* Avoid safe_mutex redefinitions */
|
||||
#include <my_pthread.h>
|
||||
|
||||
#ifndef DO_NOT_REMOVE_THREAD_WRAPPERS
|
||||
/* Remove wrappers */
|
||||
#undef pthread_mutex_init
|
||||
#undef pthread_mutex_lock
|
||||
#undef pthread_mutex_unlock
|
||||
#undef pthread_mutex_destroy
|
||||
#undef pthread_cond_wait
|
||||
#undef pthread_cond_timedwait
|
||||
#ifdef HAVE_NONPOSIX_PTHREAD_MUTEX_INIT
|
||||
#define pthread_mutex_init(a,b) my_pthread_mutex_init((a),(b))
|
||||
#endif
|
||||
#endif /* DO_NOT_REMOVE_THREAD_WRAPPERS */
|
||||
|
||||
int safe_mutex_init(safe_mutex_t *mp,
|
||||
const pthread_mutexattr_t *attr __attribute__((unused)))
|
||||
{
|
||||
bzero((char*) mp,sizeof(*mp));
|
||||
pthread_mutex_init(&mp->global,MY_MUTEX_INIT_ERRCHK);
|
||||
pthread_mutex_init(&mp->mutex,attr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line)
|
||||
{
|
||||
int error;
|
||||
pthread_mutex_lock(&mp->global);
|
||||
if (mp->count > 0 && pthread_equal(pthread_self(),mp->thread))
|
||||
{
|
||||
fprintf(stderr,"safe_mutex: Trying to lock mutex at %s, line %d, when the mutex was already locked at %s, line %d\n",
|
||||
file,line,mp->file,mp->line);
|
||||
fflush(stderr);
|
||||
abort();
|
||||
}
|
||||
pthread_mutex_unlock(&mp->global);
|
||||
error=pthread_mutex_lock(&mp->mutex);
|
||||
if (error || (error=pthread_mutex_lock(&mp->global)))
|
||||
{
|
||||
fprintf(stderr,"Got error %d when trying to lock mutex at %s, line %d\n",
|
||||
error, file, line);
|
||||
fflush(stderr);
|
||||
abort();
|
||||
}
|
||||
if (mp->count++)
|
||||
{
|
||||
fprintf(stderr,"safe_mutex: Error in thread libray: Got mutex at %s, line %d more than 1 time\n", file,line);
|
||||
fflush(stderr);
|
||||
abort();
|
||||
}
|
||||
mp->thread=pthread_self();
|
||||
mp->file= (char*) file;
|
||||
mp->line=line;
|
||||
pthread_mutex_unlock(&mp->global);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line)
|
||||
{
|
||||
int error;
|
||||
pthread_mutex_lock(&mp->global);
|
||||
if (mp->count == 0)
|
||||
{
|
||||
fprintf(stderr,"safe_mutex: Trying to unlock mutex that wasn't locked at %s, line %d\n Last used at %s, line: %d\n",
|
||||
file,line,mp->file ? mp->file : "",mp->line);
|
||||
fflush(stderr);
|
||||
abort();
|
||||
}
|
||||
if (!pthread_equal(pthread_self(),mp->thread))
|
||||
{
|
||||
fprintf(stderr,"safe_mutex: Trying to unlock mutex at %s, line %d that was locked by another thread at: %s, line: %d\n",
|
||||
file,line,mp->file,mp->line);
|
||||
fflush(stderr);
|
||||
abort();
|
||||
}
|
||||
mp->count--;
|
||||
#ifdef _WIN32
|
||||
pthread_mutex_unlock(&mp->mutex);
|
||||
error=0;
|
||||
#else
|
||||
error=pthread_mutex_unlock(&mp->mutex);
|
||||
if (error)
|
||||
{
|
||||
fprintf(stderr,"safe_mutex: Got error: %d when trying to unlock mutex at %s, line %d\n", error, file, line);
|
||||
fflush(stderr);
|
||||
abort();
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
pthread_mutex_unlock(&mp->global);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp, const char *file,
|
||||
uint line)
|
||||
{
|
||||
int error;
|
||||
pthread_mutex_lock(&mp->global);
|
||||
if (mp->count == 0)
|
||||
{
|
||||
fprintf(stderr,"safe_mutex: Trying to cond_wait on a unlocked mutex at %s, line %d\n",file,line);
|
||||
fflush(stderr);
|
||||
abort();
|
||||
}
|
||||
if (!pthread_equal(pthread_self(),mp->thread))
|
||||
{
|
||||
fprintf(stderr,"safe_mutex: Trying to cond_wait on a mutex at %s, line %d that was locked by another thread at: %s, line: %d\n",
|
||||
file,line,mp->file,mp->line);
|
||||
fflush(stderr);
|
||||
abort();
|
||||
}
|
||||
|
||||
if (mp->count-- != 1)
|
||||
{
|
||||
fprintf(stderr,"safe_mutex: Count was %d on locked mutex at %s, line %d\n",
|
||||
mp->count+1, file, line);
|
||||
fflush(stderr);
|
||||
abort();
|
||||
}
|
||||
pthread_mutex_unlock(&mp->global);
|
||||
error=pthread_cond_wait(cond,&mp->mutex);
|
||||
pthread_mutex_lock(&mp->global);
|
||||
if (error)
|
||||
{
|
||||
fprintf(stderr,"safe_mutex: Got error: %d when doing a safe_mutex_wait at %s, line %d\n", error, file, line);
|
||||
fflush(stderr);
|
||||
abort();
|
||||
}
|
||||
if (mp->count++)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"safe_mutex: Count was %d in thread %lx when locking mutex at %s, line %d\n",
|
||||
mp->count-1, my_thread_id(), file, line);
|
||||
fflush(stderr);
|
||||
abort();
|
||||
}
|
||||
mp->thread=pthread_self();
|
||||
mp->file= (char*) file;
|
||||
mp->line=line;
|
||||
pthread_mutex_unlock(&mp->global);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
|
||||
struct timespec *abstime,
|
||||
const char *file, uint line)
|
||||
{
|
||||
int error;
|
||||
pthread_mutex_lock(&mp->global);
|
||||
if (mp->count != 1 || !pthread_equal(pthread_self(),mp->thread))
|
||||
{
|
||||
fprintf(stderr,"safe_mutex: Trying to cond_wait at %s, line %d on a not hold mutex\n",file,line);
|
||||
fflush(stderr);
|
||||
abort();
|
||||
}
|
||||
mp->count--; /* Mutex will be released */
|
||||
pthread_mutex_unlock(&mp->global);
|
||||
error=pthread_cond_timedwait(cond,&mp->mutex,abstime);
|
||||
#ifdef EXTRA_DEBUG
|
||||
if (error && (error != EINTR && error != ETIMEDOUT))
|
||||
{
|
||||
fprintf(stderr,"safe_mutex: Got error: %d when doing a safe_mutex_timedwait at %s, line %d\n", error, file, line);
|
||||
}
|
||||
#endif
|
||||
pthread_mutex_lock(&mp->global);
|
||||
if (mp->count++)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"safe_mutex: Count was %d in thread %lx when locking mutex at %s, line %d (error: %d)\n",
|
||||
mp->count-1, my_thread_id(), file, line, error);
|
||||
fflush(stderr);
|
||||
abort();
|
||||
}
|
||||
mp->thread=pthread_self();
|
||||
mp->file= (char*) file;
|
||||
mp->line=line;
|
||||
pthread_mutex_unlock(&mp->global);
|
||||
return error;
|
||||
}
|
||||
|
||||
int safe_mutex_destroy(safe_mutex_t *mp, const char *file, uint line)
|
||||
{
|
||||
int error=0;
|
||||
if (mp->count != 0)
|
||||
{
|
||||
fprintf(stderr,"safe_mutex: Trying to destroy a mutex that was locked at %s, line %d at %s, line %d\n",
|
||||
mp->file,mp->line, file, line);
|
||||
fflush(stderr);
|
||||
abort();
|
||||
}
|
||||
#ifdef _WIN32
|
||||
pthread_mutex_destroy(&mp->global);
|
||||
pthread_mutex_destroy(&mp->mutex);
|
||||
#else
|
||||
if (pthread_mutex_destroy(&mp->global))
|
||||
error=1;
|
||||
if (pthread_mutex_destroy(&mp->mutex))
|
||||
error=1;
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
#endif /* THREAD && SAFE_MUTEX */
|
106
module/Vendor/MDBC/libmariadb/typelib.c
vendored
Normal file
106
module/Vendor/MDBC/libmariadb/typelib.c
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/* Functions to handle typelib */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include <m_string.h>
|
||||
#include <m_ctype.h>
|
||||
|
||||
/***************************************************************************
|
||||
** Search after a fieldtype. Endspace in x is not compared.
|
||||
** If part, uniq field is found and full_name == 0 then x is expanded
|
||||
** to full field.
|
||||
** full_name has the following bit values:
|
||||
** If & 1 accept only whole names
|
||||
** If & 2 don't expand if half field
|
||||
** If & 4 allow #number# as type
|
||||
****************************************************************************/
|
||||
|
||||
int find_type(my_string x, TYPELIB *typelib, uint full_name)
|
||||
{
|
||||
int find,pos,findpos= 0;
|
||||
reg1 my_string i;
|
||||
reg2 const char *j;
|
||||
DBUG_ENTER("find_type");
|
||||
DBUG_PRINT("enter",("x: '%s' lib: %lx",x,typelib));
|
||||
|
||||
if (!typelib->count)
|
||||
{
|
||||
DBUG_PRINT("exit",("no count"));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
LINT_INIT(findpos);
|
||||
find=0;
|
||||
for (pos=0 ; (j=typelib->type_names[pos]) ; pos++)
|
||||
{
|
||||
for (i=x ; *i && toupper(*i) == toupper(*j) ; i++, j++) ;
|
||||
if (! *j)
|
||||
{
|
||||
while (*i == ' ')
|
||||
i++; /* skipp_end_space */
|
||||
if (! *i)
|
||||
DBUG_RETURN(pos+1);
|
||||
}
|
||||
if (! *i && (!*j || !(full_name & 1)))
|
||||
{
|
||||
find++;
|
||||
findpos=pos;
|
||||
}
|
||||
}
|
||||
if (find == 0 && (full_name & 4) && x[0] == '#' && strend(x)[-1] == '#' &&
|
||||
(findpos=atoi(x+1)-1) >= 0 && (uint) findpos < typelib->count)
|
||||
find=1;
|
||||
else if (find == 0 || ! x[0])
|
||||
{
|
||||
DBUG_PRINT("exit",("Couldn't find type"));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
else if (find != 1 || (full_name & 1))
|
||||
{
|
||||
DBUG_PRINT("exit",("Too many possybilities"));
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
if (!(full_name & 2))
|
||||
(void) strmov(x,typelib->type_names[findpos]);
|
||||
DBUG_RETURN(findpos+1);
|
||||
} /* find_type */
|
||||
|
||||
|
||||
/* Get name of type nr 'nr' */
|
||||
/* Warning first type is 1, 0 = empty field */
|
||||
|
||||
void make_type(register my_string to, register uint nr, register TYPELIB *typelib)
|
||||
{
|
||||
DBUG_ENTER("make_type");
|
||||
if (!nr)
|
||||
to[0]=0;
|
||||
else
|
||||
(void) strmov(to,get_type(typelib,nr-1));
|
||||
DBUG_VOID_RETURN;
|
||||
} /* make_type */
|
||||
|
||||
|
||||
/* Get type */
|
||||
/* Warning first type is 0 */
|
||||
|
||||
const char *get_type(TYPELIB *typelib, uint nr)
|
||||
{
|
||||
if (nr < (uint) typelib->count && typelib->type_names)
|
||||
return(typelib->type_names[nr]);
|
||||
return "?";
|
||||
}
|
709
module/Vendor/MDBC/libmariadb/violite.c
vendored
Normal file
709
module/Vendor/MDBC/libmariadb/violite.c
vendored
Normal file
@ -0,0 +1,709 @@
|
||||
/* 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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02111-1301, USA */
|
||||
|
||||
/*
|
||||
Note that we can't have assertion on file descriptors; The reason for
|
||||
this is that during mysql shutdown, another thread can close a file
|
||||
we are working on. In this case we should just return read errors from
|
||||
the file descriptior.
|
||||
*/
|
||||
|
||||
#ifndef HAVE_VIO /* is Vio suppored by the Vio lib ? */
|
||||
|
||||
#include <my_global.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <violite.h>
|
||||
#include <my_sys.h>
|
||||
#include <my_net.h>
|
||||
#include <m_string.h>
|
||||
#ifdef HAVE_POLL
|
||||
#include <sys/poll.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
#include <ma_secure.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define socklen_t int
|
||||
#pragma comment (lib, "ws2_32")
|
||||
#endif
|
||||
|
||||
#if !defined(_WIN32) && !defined(HAVE_BROKEN_NETINET_INCLUDES)
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#if !defined(alpha_linux_port)
|
||||
#include <netinet/tcp.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__EMX__) || defined(OS2)
|
||||
#define ioctlsocket ioctl
|
||||
#endif /* defined(__EMX__) */
|
||||
|
||||
#if defined(MSDOS) || defined(_WIN32)
|
||||
#define O_NONBLOCK 1 /* For emulation of fcntl() */
|
||||
#endif
|
||||
#ifndef EWOULDBLOCK
|
||||
#define SOCKET_EWOULDBLOCK SOCKET_EAGAIN
|
||||
#endif
|
||||
|
||||
#include <mysql_async.h>
|
||||
#include <my_context.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define ma_get_error() WSAGetLastError()
|
||||
#else
|
||||
#define ma_get_error() errno
|
||||
#endif
|
||||
|
||||
typedef void *vio_ptr;
|
||||
typedef char *vio_cstring;
|
||||
|
||||
/*
|
||||
* Helper to fill most of the Vio* with defaults.
|
||||
*/
|
||||
|
||||
void vio_reset(Vio* vio, enum enum_vio_type type,
|
||||
my_socket sd, HANDLE hPipe,
|
||||
my_bool localhost)
|
||||
{
|
||||
uchar *save_cache= vio->cache;
|
||||
int save_timeouts[2]= {vio->read_timeout, vio->write_timeout};
|
||||
bzero((char*) vio, sizeof(*vio));
|
||||
vio->type= type;
|
||||
vio->sd= sd;
|
||||
vio->hPipe= hPipe;
|
||||
vio->localhost= localhost;
|
||||
/* do not clear cache */
|
||||
vio->cache= vio->cache_pos= save_cache;
|
||||
vio->cache_size= 0;
|
||||
vio->read_timeout= save_timeouts[0];
|
||||
vio->write_timeout= save_timeouts[1];
|
||||
}
|
||||
|
||||
void vio_timeout(Vio *vio, int type, uint timeval)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
uint timeout= timeval; /* milli secs */
|
||||
#else
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec= timeval / 1000;
|
||||
timeout.tv_usec= (timeval % 1000) * 1000;
|
||||
#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 timeout)
|
||||
{
|
||||
vio->read_timeout= timeout * 1000;
|
||||
vio_timeout(vio, SO_RCVTIMEO, vio->read_timeout);
|
||||
}
|
||||
|
||||
void vio_write_timeout(Vio *vio, uint timeout)
|
||||
{
|
||||
vio->write_timeout= timeout * 1000;
|
||||
vio_timeout(vio, SO_SNDTIMEO, vio->write_timeout);
|
||||
}
|
||||
|
||||
/* Open the socket or TCP/IP connection and read the fnctl() status */
|
||||
|
||||
Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost)
|
||||
{
|
||||
Vio *vio;
|
||||
DBUG_ENTER("vio_new");
|
||||
DBUG_PRINT("enter", ("sd=%d", sd));
|
||||
if ((vio = (Vio*) my_malloc(sizeof(*vio),MYF(MY_WME))))
|
||||
{
|
||||
vio_reset(vio, type, sd, 0, localhost);
|
||||
sprintf(vio->desc,
|
||||
(vio->type == VIO_TYPE_SOCKET ? "socket (%d)" : "TCP/IP (%d)"),
|
||||
vio->sd);
|
||||
#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(_WIN32) && !defined(__EMX__) */
|
||||
{
|
||||
/* set to blocking mode by default */
|
||||
ulong arg=0, r;
|
||||
r = ioctlsocket(vio->sd,FIONBIO,(void*) &arg/*, sizeof(arg)*/);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (!(vio->cache= my_malloc(VIO_CACHE_SIZE, MYF(MY_ZEROFILL))))
|
||||
{
|
||||
my_free(vio);
|
||||
vio= NULL;
|
||||
}
|
||||
vio->cache_size= 0;
|
||||
vio->cache_pos= vio->cache;
|
||||
DBUG_RETURN(vio);
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
Vio *vio_new_win32pipe(HANDLE hPipe)
|
||||
{
|
||||
Vio *vio;
|
||||
DBUG_ENTER("vio_new_handle");
|
||||
if ((vio = (Vio*) my_malloc(sizeof(Vio),MYF(MY_ZEROFILL))))
|
||||
{
|
||||
vio_reset(vio, VIO_TYPE_NAMEDPIPE, 0, hPipe, TRUE);
|
||||
strmov(vio->desc, "named pipe");
|
||||
}
|
||||
DBUG_RETURN(vio);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void vio_delete(Vio * vio)
|
||||
{
|
||||
/* It must be safe to delete null pointers. */
|
||||
/* This matches the semantics of C++'s delete operator. */
|
||||
if (vio)
|
||||
{
|
||||
if (vio->type != VIO_CLOSED)
|
||||
vio_close(vio);
|
||||
my_free(vio->cache);
|
||||
my_free(vio);
|
||||
}
|
||||
}
|
||||
|
||||
int vio_errno(Vio *vio __attribute__((unused)))
|
||||
{
|
||||
return socket_errno; /* On Win32 this mapped to WSAGetLastError() */
|
||||
}
|
||||
|
||||
int vio_wait_or_timeout(Vio *vio, my_bool is_read, int timeout)
|
||||
{
|
||||
int rc;
|
||||
#ifndef _WIN32
|
||||
struct pollfd p_fd;
|
||||
#else
|
||||
struct timeval tv= {0,0};
|
||||
fd_set fds, exc_fds;
|
||||
#endif
|
||||
|
||||
if (!timeout)
|
||||
timeout= -1;
|
||||
|
||||
/* we don't support it via named pipes yet.
|
||||
* maybe this could be handled via PeekNamedPipe somehow !? */
|
||||
if (vio->type == VIO_TYPE_NAMEDPIPE)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
Note that if zero timeout, then we will not block, so we do not need to
|
||||
yield to calling application in the async case.
|
||||
*/
|
||||
if (timeout != 0 && vio->async_context && vio->async_context->active)
|
||||
{
|
||||
rc= my_io_wait_async(vio->async_context,
|
||||
(is_read) ? VIO_IO_EVENT_READ : VIO_IO_EVENT_WRITE,
|
||||
timeout);
|
||||
return(rc);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef _WIN32
|
||||
memset(&p_fd, 0, sizeof(p_fd));
|
||||
p_fd.fd= vio->sd;
|
||||
p_fd.events= (is_read) ? POLLIN : POLLOUT;
|
||||
|
||||
do {
|
||||
rc= poll(&p_fd, 1, timeout);
|
||||
} while (rc == -1 && errno == EINTR);
|
||||
|
||||
if (rc == 0)
|
||||
errno= ETIMEDOUT;
|
||||
#else
|
||||
FD_ZERO(&fds);
|
||||
FD_ZERO(&exc_fds);
|
||||
|
||||
FD_SET(vio->sd, &fds);
|
||||
FD_SET(vio->sd, &exc_fds);
|
||||
|
||||
if (timeout >= 0)
|
||||
{
|
||||
tv.tv_sec= timeout / 1000;
|
||||
tv.tv_usec= (timeout % 1000) * 1000;
|
||||
}
|
||||
|
||||
rc= select(0, (is_read) ? &fds : NULL,
|
||||
(is_read) ? NULL : &fds,
|
||||
&exc_fds,
|
||||
(timeout >= 0) ? &tv : NULL);
|
||||
if (rc == SOCKET_ERROR)
|
||||
errno= WSAGetLastError();
|
||||
if (rc == 0)
|
||||
errno= ETIMEDOUT;
|
||||
#endif
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
size_t vio_real_read(Vio *vio, gptr buf, size_t size)
|
||||
{
|
||||
size_t r;
|
||||
|
||||
switch(vio->type) {
|
||||
#ifdef HAVE_OPENSSL
|
||||
case VIO_TYPE_SSL:
|
||||
return my_ssl_read(vio, (char *)buf, size);
|
||||
break;
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
case VIO_TYPE_NAMEDPIPE:
|
||||
{
|
||||
DWORD length= 0;
|
||||
if (!ReadFile(vio->hPipe, buf, (DWORD)size, &length, NULL))
|
||||
return -1;
|
||||
return length;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
if (vio->async_context && vio->async_context->active)
|
||||
r= my_recv_async(vio->async_context,
|
||||
vio->sd,
|
||||
buf, size, vio->read_timeout);
|
||||
else
|
||||
{
|
||||
if (vio->async_context)
|
||||
{
|
||||
/*
|
||||
If switching from non-blocking to blocking API usage, set the socket
|
||||
back to blocking mode.
|
||||
*/
|
||||
my_bool old_mode;
|
||||
vio_blocking(vio, TRUE, &old_mode);
|
||||
}
|
||||
#ifndef _WIN32
|
||||
if (vio_wait_or_timeout(vio, TRUE, vio->read_timeout) < 1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
do {
|
||||
r= recv(vio->sd, buf, size, 0);
|
||||
} while (r == -1 && errno == EINTR);
|
||||
#else
|
||||
{
|
||||
WSABUF wsaData;
|
||||
DWORD dwBytes = 0;
|
||||
DWORD flags = 0;
|
||||
|
||||
wsaData.len= size;
|
||||
wsaData.buf= buf;
|
||||
|
||||
if (WSARecv(vio->sd, &wsaData, 1, &dwBytes, &flags, NULL, NULL) == SOCKET_ERROR)
|
||||
{
|
||||
errno= WSAGetLastError();
|
||||
return 0;
|
||||
}
|
||||
r= (size_t)dwBytes;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
size_t vio_read(Vio * vio, gptr buf, size_t size)
|
||||
{
|
||||
size_t r;
|
||||
DBUG_ENTER("vio_read");
|
||||
DBUG_PRINT("enter", ("sd=%d size=%d", vio->sd, size));
|
||||
|
||||
if (!vio->cache)
|
||||
DBUG_RETURN(vio_real_read(vio, buf, size));
|
||||
|
||||
if (vio->cache + vio->cache_size > vio->cache_pos)
|
||||
{
|
||||
r= MIN(size, (size_t)(vio->cache + vio->cache_size - vio->cache_pos));
|
||||
memcpy(buf, vio->cache_pos, r);
|
||||
vio->cache_pos+= r;
|
||||
}
|
||||
else if (size >= VIO_CACHE_MIN_SIZE)
|
||||
{
|
||||
r= vio_real_read(vio, buf, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
r= vio_real_read(vio, vio->cache, VIO_CACHE_SIZE);
|
||||
if ((ssize_t)r > 0)
|
||||
{
|
||||
if (size < r)
|
||||
{
|
||||
vio->cache_size= r; /* might be < VIO_CACHE_SIZE */
|
||||
vio->cache_pos= vio->cache + size;
|
||||
r= size;
|
||||
}
|
||||
memcpy(buf, vio->cache, r);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
if ((ssize_t)r == -1)
|
||||
{
|
||||
DBUG_PRINT("vio_error", ("Got error %d during read",socket_errno));
|
||||
}
|
||||
#endif /* DBUG_OFF */
|
||||
DBUG_PRINT("exit", ("%u", (uint)r));
|
||||
DBUG_RETURN(r);
|
||||
}
|
||||
|
||||
/*
|
||||
Return data from the beginning of the receive queue without removing
|
||||
that data from the queue. A subsequent receive call will return the same data.
|
||||
*/
|
||||
my_bool vio_read_peek(Vio *vio, size_t *bytes)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (ioctlsocket(vio->sd, FIONREAD, (unsigned long*)bytes))
|
||||
return TRUE;
|
||||
#else
|
||||
char buffer[1024];
|
||||
ssize_t length;
|
||||
|
||||
vio_blocking(vio, 0, 0);
|
||||
length= recv(vio->sd, &buffer, sizeof(buffer), MSG_PEEK);
|
||||
if (length < 0)
|
||||
return TRUE;
|
||||
*bytes= length;
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
size_t vio_write(Vio * vio, const gptr buf, size_t size)
|
||||
{
|
||||
size_t r;
|
||||
DBUG_ENTER("vio_write");
|
||||
DBUG_PRINT("enter", ("sd=%d size=%d", vio->sd, size));
|
||||
#ifdef HAVE_OPENSSL
|
||||
if (vio->type == VIO_TYPE_SSL)
|
||||
{
|
||||
r= my_ssl_write(vio, (uchar *)buf, size);
|
||||
DBUG_RETURN(r);
|
||||
}
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
if ( vio->type == VIO_TYPE_NAMEDPIPE)
|
||||
{
|
||||
DWORD length;
|
||||
if (!WriteFile(vio->hPipe, (char*) buf, (DWORD)size, &length, NULL))
|
||||
DBUG_RETURN(-1);
|
||||
DBUG_RETURN(length);
|
||||
}
|
||||
#endif
|
||||
if (vio->async_context && vio->async_context->active)
|
||||
r= my_send_async(vio->async_context, vio->sd, buf, size,
|
||||
vio->write_timeout);
|
||||
else
|
||||
{
|
||||
if (vio->async_context)
|
||||
{
|
||||
/*
|
||||
If switching from non-blocking to blocking API usage, set the socket
|
||||
back to blocking mode.
|
||||
*/
|
||||
my_bool old_mode;
|
||||
vio_blocking(vio, TRUE, &old_mode);
|
||||
}
|
||||
#ifndef _WIN32
|
||||
do {
|
||||
r= send(vio->sd, buf, size, vio->write_timeout ? MSG_DONTWAIT : MSG_WAITALL);
|
||||
} while (r == -1 && errno == EINTR);
|
||||
|
||||
while (r == -1 && (errno == EAGAIN || errno == EWOULDBLOCK) &&
|
||||
vio->write_timeout > 0)
|
||||
{
|
||||
if (vio_wait_or_timeout(vio, FALSE, vio->write_timeout) < 1)
|
||||
return 0;
|
||||
do {
|
||||
r= send(vio->sd, buf, size, vio->write_timeout ? MSG_DONTWAIT : MSG_WAITALL);
|
||||
} while (r == -1 && errno == EINTR);
|
||||
}
|
||||
#else
|
||||
{
|
||||
WSABUF wsaData;
|
||||
DWORD dwBytes = 0;
|
||||
|
||||
wsaData.len= size;
|
||||
wsaData.buf= (char *)buf;
|
||||
|
||||
if (WSASend(vio->sd, &wsaData, 1, &dwBytes, 0, NULL, NULL) == SOCKET_ERROR)
|
||||
{
|
||||
errno= WSAGetLastError();
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
r= (size_t)dwBytes;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifndef DBUG_OFF
|
||||
if ((size_t)r == -1)
|
||||
{
|
||||
DBUG_PRINT("vio_error", ("Got error on write: %d",socket_errno));
|
||||
}
|
||||
#endif /* DBUG_OFF */
|
||||
DBUG_PRINT("exit", ("%u", (uint)r));
|
||||
DBUG_RETURN(r);
|
||||
}
|
||||
|
||||
|
||||
int vio_blocking(Vio *vio, my_bool block, my_bool *previous_mode)
|
||||
{
|
||||
int *sd_flags= &vio->fcntl_mode;
|
||||
int save_flags= vio->fcntl_mode;
|
||||
my_bool tmp;
|
||||
my_socket sock= vio->sd;
|
||||
|
||||
if (vio->type == VIO_TYPE_NAMEDPIPE)
|
||||
return 0;
|
||||
|
||||
if (!previous_mode)
|
||||
previous_mode= &tmp;
|
||||
|
||||
#ifdef _WIN32
|
||||
*previous_mode= (*sd_flags & O_NONBLOCK) != 0;
|
||||
*sd_flags = (block) ? *sd_flags & ~O_NONBLOCK : *sd_flags | O_NONBLOCK;
|
||||
{
|
||||
ulong arg= 1 - block;
|
||||
if (ioctlsocket(sock, FIONBIO, (void *)&arg))
|
||||
{
|
||||
vio->fcntl_mode= save_flags;
|
||||
return(WSAGetLastError());
|
||||
}
|
||||
}
|
||||
#else
|
||||
#if defined(O_NONBLOCK)
|
||||
*previous_mode= (*sd_flags & O_NONBLOCK) != 0;
|
||||
*sd_flags = (block) ? *sd_flags & ~O_NONBLOCK : *sd_flags | O_NONBLOCK;
|
||||
#elif defined(O_NDELAY)
|
||||
*previous_mode= (*sd_flags & O_NODELAY) != 0;
|
||||
*sd_flags = (block) ? *sd_flags & ~O_NODELAY : *sd_flags | O_NODELAY;
|
||||
#elif defined(FNDELAY)
|
||||
*previous_mode= (*sd_flags & O_FNDELAY) != 0;
|
||||
*sd_flags = (block) ? *sd_flags & ~O_FNDELAY : *sd_flags | O_FNDELAY;
|
||||
#else
|
||||
#error socket blocking is not supported on this platform
|
||||
#endif
|
||||
if (fcntl(sock, F_SETFL, *sd_flags) == -1)
|
||||
{
|
||||
vio->fcntl_mode= save_flags;
|
||||
return errno;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
my_bool
|
||||
vio_is_blocking(Vio * vio)
|
||||
{
|
||||
my_bool r;
|
||||
DBUG_ENTER("vio_is_blocking");
|
||||
r = !(vio->fcntl_mode & O_NONBLOCK);
|
||||
DBUG_PRINT("exit", ("%d", (int) r));
|
||||
DBUG_RETURN(r);
|
||||
}
|
||||
|
||||
|
||||
int vio_fastsend(Vio * vio __attribute__((unused)))
|
||||
{
|
||||
int r=0;
|
||||
DBUG_ENTER("vio_fastsend");
|
||||
|
||||
{
|
||||
#ifdef IPTOS_THROUGHPUT
|
||||
int tos = IPTOS_THROUGHPUT;
|
||||
if (!setsockopt(vio->sd, IPPROTO_IP, IP_TOS, (void *) &tos, sizeof(tos)))
|
||||
#endif /* IPTOS_THROUGHPUT */
|
||||
{
|
||||
int nodelay = 1;
|
||||
if (setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY, (void *) &nodelay,
|
||||
sizeof(nodelay))) {
|
||||
DBUG_PRINT("warning",
|
||||
("Couldn't set socket option for fast send"));
|
||||
r= -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
DBUG_PRINT("exit", ("%d", r));
|
||||
DBUG_RETURN(r);
|
||||
}
|
||||
|
||||
int vio_keepalive(Vio* vio, my_bool set_keep_alive)
|
||||
{
|
||||
int r=0;
|
||||
uint opt = 0;
|
||||
DBUG_ENTER("vio_keepalive");
|
||||
DBUG_PRINT("enter", ("sd=%d set_keep_alive=%d", vio->sd, (int)
|
||||
set_keep_alive));
|
||||
if (vio->type != VIO_TYPE_NAMEDPIPE)
|
||||
{
|
||||
if (set_keep_alive)
|
||||
opt = 1;
|
||||
r = setsockopt(vio->sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt,
|
||||
sizeof(opt));
|
||||
}
|
||||
DBUG_RETURN(r);
|
||||
}
|
||||
|
||||
|
||||
my_bool
|
||||
vio_should_retry(Vio * vio __attribute__((unused)))
|
||||
{
|
||||
int en = socket_errno;
|
||||
return en == SOCKET_EAGAIN || en == SOCKET_EINTR || en == SOCKET_EWOULDBLOCK;
|
||||
}
|
||||
|
||||
|
||||
int vio_close(Vio * vio)
|
||||
{
|
||||
int r;
|
||||
DBUG_ENTER("vio_close");
|
||||
#ifdef HAVE_OPENSSL
|
||||
if (vio->type == VIO_TYPE_SSL)
|
||||
{
|
||||
r = my_ssl_close(vio);
|
||||
}
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
if (vio->type == VIO_TYPE_NAMEDPIPE)
|
||||
{
|
||||
r=CloseHandle(vio->hPipe);
|
||||
}
|
||||
else if (vio->type != VIO_CLOSED)
|
||||
#endif /* _WIN32 */
|
||||
{
|
||||
r=0;
|
||||
if (shutdown(vio->sd,2))
|
||||
r= -1;
|
||||
if (closesocket(vio->sd))
|
||||
r= -1;
|
||||
}
|
||||
if (r)
|
||||
{
|
||||
DBUG_PRINT("vio_error", ("close() failed, error: %d",socket_errno));
|
||||
/* FIXME: error handling (not critical for MySQL) */
|
||||
}
|
||||
vio->type= VIO_CLOSED;
|
||||
vio->sd= -1;
|
||||
DBUG_RETURN(r);
|
||||
}
|
||||
|
||||
|
||||
const char *vio_description(Vio * vio)
|
||||
{
|
||||
return vio->desc;
|
||||
}
|
||||
|
||||
enum enum_vio_type vio_type(Vio* vio)
|
||||
{
|
||||
return vio->type;
|
||||
}
|
||||
|
||||
my_socket vio_fd(Vio* vio)
|
||||
{
|
||||
return vio->sd;
|
||||
}
|
||||
|
||||
|
||||
my_bool vio_peer_addr(Vio * vio, char *buf)
|
||||
{
|
||||
DBUG_ENTER("vio_peer_addr");
|
||||
DBUG_PRINT("enter", ("sd=%d", vio->sd));
|
||||
if (vio->localhost)
|
||||
{
|
||||
strmov(buf,"127.0.0.1");
|
||||
}
|
||||
else
|
||||
{
|
||||
socklen_t addrLen = sizeof(struct sockaddr);
|
||||
if (getpeername(vio->sd, (struct sockaddr *) (& (vio->remote)),
|
||||
&addrLen) != 0)
|
||||
{
|
||||
DBUG_PRINT("exit", ("getpeername, error: %d", socket_errno));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
my_inet_ntoa(vio->remote.sin_addr,buf);
|
||||
}
|
||||
DBUG_PRINT("exit", ("addr=%s", buf));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
void vio_in_addr(Vio *vio, struct in_addr *in)
|
||||
{
|
||||
DBUG_ENTER("vio_in_addr");
|
||||
if (vio->localhost)
|
||||
bzero((char*) in, sizeof(*in)); /* This should never be executed */
|
||||
else
|
||||
*in=vio->remote.sin_addr;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
/* Return 0 if there is data to be read */
|
||||
/*
|
||||
my_bool vio_poll_read(Vio *vio,uint timeout)
|
||||
{
|
||||
#ifndef HAVE_POLL
|
||||
return 0;
|
||||
#else
|
||||
struct pollfd fds;
|
||||
int res;
|
||||
DBUG_ENTER("vio_poll");
|
||||
fds.fd=vio->sd;
|
||||
fds.events=POLLIN;
|
||||
fds.revents=0;
|
||||
if ((res=poll(&fds,1,(int) timeout*1000)) <= 0)
|
||||
{
|
||||
DBUG_RETURN(res < 0 ? 0 : 1);
|
||||
}
|
||||
DBUG_RETURN(fds.revents & POLLIN ? 0 : 1);
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
|
||||
#endif /* HAVE_VIO */
|
Reference in New Issue
Block a user