1
0
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:
Sandu Liviu Catalin
2020-03-22 14:54:40 +02:00
parent 0d254ed90b
commit 2ee661ee65
438 changed files with 130907 additions and 0 deletions

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

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

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

View 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

File diff suppressed because it is too large Load Diff

433
module/Vendor/MDBC/libmariadb/default.c vendored Normal file
View 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
View 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
View 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

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

View 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

File diff suppressed because it is too large Load Diff

116
module/Vendor/MDBC/libmariadb/list.c vendored Normal file
View 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
View 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;
}

View 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

File diff suppressed because it is too large Load Diff

4401
module/Vendor/MDBC/libmariadb/ma_dyncol.c vendored Normal file

File diff suppressed because it is too large Load Diff

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

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

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

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

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

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

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

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

File diff suppressed because it is too large Load Diff

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

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

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

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

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

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

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

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

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

View 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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

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

View File

@ -0,0 +1,119 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 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

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

File diff suppressed because it is too large Load Diff

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

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

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

View File

@ -0,0 +1,48 @@
/* File : strxnmov.c
Author : Richard A. O'Keefe.
Updated: 2 June 1984
Defines: strxnmov()
strxnmov(dst, len, src1, ..., srcn, NullS)
moves the first len characters of the concatenation of src1,...,srcn
to dst. If there aren't that many characters, a NUL character will
be added to the end of dst to terminate it properly. This gives the
same effect as calling strxcpy(buff, src1, ..., srcn, NullS) with a
large enough buffer, and then calling strnmov(dst, buff, len).
It is just like strnmov except that it concatenates multiple sources.
Beware: the last argument should be the null character pointer.
Take VERY great care not to omit it! Also be careful to use NullS
and NOT to use 0, as on some machines 0 is not the same size as a
character pointer, or not the same bit pattern as NullS.
Note: strxnmov is like strnmov in that it moves up to len
characters; dst will be padded on the right with one NUL characters if
needed.
*/
#include <my_global.h>
#include "m_string.h"
#include <stdarg.h>
char *strxnmov(char *dst, size_t len, const char *src, ...)
{
va_list pvar;
char *end_of_dst=dst+len;
va_start(pvar,src);
while (src != NullS)
{
do
{
if (dst == end_of_dst)
goto end;
}
while ((*dst++ = *src++));
dst--;
src = va_arg(pvar, char *);
}
*dst=0;
end:
va_end(pvar);
return dst;
}

View File

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