diff options
author | Andi Gutmans <andi@php.net> | 2000-02-19 10:10:46 +0000 |
---|---|---|
committer | Andi Gutmans <andi@php.net> | 2000-02-19 10:10:46 +0000 |
commit | 0cda28f77bcea25a35b2d55ee1bb52c5fdb34f2a (patch) | |
tree | 11e6fbfcc15fe72ed98e6736d84b47ac9250fcc0 | |
parent | fe9abd3219b097e0c0f2c9106751d35b2bede2d6 (diff) | |
download | php-git-0cda28f77bcea25a35b2d55ee1bb52c5fdb34f2a.tar.gz |
- Add libmysql to the tree
83 files changed, 12485 insertions, 0 deletions
diff --git a/ext/mysql/libmysql/Makefile b/ext/mysql/libmysql/Makefile new file mode 100644 index 0000000000..943c978a0c --- /dev/null +++ b/ext/mysql/libmysql/Makefile @@ -0,0 +1,8 @@ +# A very minimal Makefile to compile +# the minimized libmysql library +# This file is autogenerated from Makefile.am +CFLAGS= -I. -DUNDEF_THREADS_HACK +obj=my_init.o my_static.o my_malloc.o my_realloc.o my_create.o my_delete.o my_tempnam.o my_open.o mf_casecnv.o my_read.o my_write.o errors.o my_error.o my_getwd.o my_div.o mf_pack.o my_messnc.o mf_dirname.o mf_fn_ext.o mf_wcomp.o typelib.o safemalloc.o my_alloc.o mf_format.o mf_path.o mf_unixpath.o my_fopen.o mf_loadpath.o my_pthread.o my_thr_init.o thr_mutex.o mulalloc.o string.o default.o my_compress.o array.o my_once.o list.o my_net.o dbug.o strmov.o strxmov.o strnmov.o strmake.o strend.o strfill.o ct_init.o is_prefix.o int2str.o str2int.o strinstr.o strcont.o strcend.o bchange.o bmove.o bmove_upp.o longlong2str.o strtoull.o strtoll.o ctype-latin1.o +all: libmysql.a +libmysql.a: $(obj) + $(AR) r $@ $? diff --git a/ext/mysql/libmysql/array.c b/ext/mysql/libmysql/array.c new file mode 100644 index 0000000000..f8ba10c253 --- /dev/null +++ b/ext/mysql/libmysql/array.c @@ -0,0 +1,163 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* Handling of arrays that can grow dynamicly. */ + +#if defined(WIN32) || defined(__WIN32__) +#undef SAFEMALLOC /* Problems with threads */ +#endif + +#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) +{ + 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(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 */ + +byte *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 */ + +byte *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,MYF(MY_WME)); + 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; + } +} diff --git a/ext/mysql/libmysql/bchange.c b/ext/mysql/libmysql/bchange.c new file mode 100644 index 0000000000..6cd4c41457 --- /dev/null +++ b/ext/mysql/libmysql/bchange.c @@ -0,0 +1,25 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* 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 <global.h> +#include "m_string.h" + +void bchange(register char *dst, uint old_length, register const char *src, uint new_length, uint tot_length) +{ + uint 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); +} diff --git a/ext/mysql/libmysql/bmove.c b/ext/mysql/libmysql/bmove.c new file mode 100644 index 0000000000..096a628260 --- /dev/null +++ b/ext/mysql/libmysql/bmove.c @@ -0,0 +1,63 @@ +/* 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 <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 byte *dst; +register const char *src; +register uint len; +{ + while (len-- != 0) *dst++ = *src++; +} +#endif +#endif +#endif diff --git a/ext/mysql/libmysql/bmove_upp.c b/ext/mysql/libmysql/bmove_upp.c new file mode 100644 index 0000000000..435abfb6d6 --- /dev/null +++ b/ext/mysql/libmysql/bmove_upp.c @@ -0,0 +1,37 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* 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 <global.h> +#include "m_string.h" + +#if defined(MC68000) && defined(DS90) + +/* 0 <= len <= 65535 */ +void bmove_upp(byte *dst, const byte *src,uint 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 uint len) +{ + while (len-- != 0) *--dst = *--src; +} + +#endif diff --git a/ext/mysql/libmysql/config-win32.h b/ext/mysql/libmysql/config-win32.h new file mode 100644 index 0000000000..eacd9829e1 --- /dev/null +++ b/ext/mysql/libmysql/config-win32.h @@ -0,0 +1,174 @@ +/* Defines for Win32 to make it compatible for MySQL */ + +#include <sys/locking.h> +#include <windows.h> +#include <math.h> /* Because of rint() */ +#include <fcntl.h> +#include <io.h> +#include <malloc.h> + +#define SYSTEM_TYPE "Win95" +#define MACHINE_TYPE "i586" /* Define to machine type name */ +#ifndef __WIN32__ +#define __WIN32__ /* To make it easier in VC++ */ +#endif + +/* File and lock constants */ +#define O_SHARE 0x1000 /* Open file in sharing mode */ +#ifdef __BORLANDC__ +#define F_RDLCK LK_NBLCK /* read lock */ +#define F_WRLCK LK_NBRLCK /* write lock */ +#define F_UNLCK LK_UNLCK /* remove lock(s) */ +#else +#define F_RDLCK _LK_NBLCK /* read lock */ +#define F_WRLCK _LK_NBRLCK /* write lock */ +#define F_UNLCK _LK_UNLCK /* remove lock(s) */ +#endif + +#define F_EXCLUSIVE 1 /* We have only exclusive locking */ +#define F_TO_EOF (INT_MAX32/2) /* size for lock of all file */ +#define F_OK 0 /* parameter to access() */ + +#define S_IROTH S_IREAD /* for my_lib */ + +#ifdef __BORLANDC__ +#define FILE_BINARY O_BINARY /* my_fopen in binary mode */ +#define O_TEMPORARY 0 +#define O_SHORT_LIVED 0 +#define SH_DENYNO _SH_DENYNO +#else +#define O_BINARY _O_BINARY /* compability with MSDOS */ +#define FILE_BINARY _O_BINARY /* my_fopen in binary mode */ +#define O_TEMPORARY _O_TEMPORARY +#define O_SHORT_LIVED _O_SHORT_LIVED +#define SH_DENYNO _SH_DENYNO +#endif +#define NO_OPEN_3 /* For my_create() */ + +#define SIGQUIT SIGTERM /* No SIGQUIT */ + +#undef _REENTRANT /* Crashes something for win32 */ + +#define LONGLONG_MIN ((__int64) 0x8000000000000000) +#define LONGLONG_MAX ((__int64) 0x7FFFFFFFFFFFFFFF) +#define LL(A) ((__int64) A) + +/* Type information */ + +typedef unsigned short ushort; +typedef unsigned int uint; +typedef long off_t ; +typedef unsigned int size_t; +typedef unsigned __int64 ulonglong; /* Microsofts 64 bit types */ +typedef __int64 longlong; +typedef int sigset_t; +#define longlong_defined + +#define Socket SOCKET +#define bool BOOL +#define SIGPIPE SIGINT +#define RETQSORTTYPE void +#define QSORT_TYPE_IS_VOID +#define RETSIGTYPE void +#define SOCKET_SIZE_TYPE int +#define Socket_defined +#define bool_defined +#define byte_defined +#define HUGE_PTR + +#define THREAD +#define VOID_SIGHANDLER +#define SIZEOF_CHAR 1 +#define SIZEOF_LONG 4 +#define SIZEOF_LONG_LONG 8 +#define HAVE_BROKEN_NETINET_INCLUDES + +/* Convert some simple functions to Posix */ + +#define sigset(A,B) signal((A),(B)) +#define finite(A) _finite(A) +#define sleep(A) Sleep((A)*1000) + +#ifndef __BORLANDC__ +#define access(A,B) _access(A,B) +#endif + +#if defined(__cplusplus) + +inline double rint(double nr) +{ + double f = floor(nr); + double c = ceil(nr); + return (((nr-c) >= (nr-f)) ? f :c); +} + +inline double ulonglong2double(longlong nr) +{ + if (nr >= 0) + return (double) nr; + return (18446744073709551616.0 + (double) nr); +} +#else +#define inline __inline +#endif + + +/* Optimized store functions for Intel x86 */ + +#define sint2korr(A) (*((int16 *) (A))) +#define sint3korr(A) ((int32) ((((uchar) (A)[2]) & 128) ? \ + (((uint32) 255L << 24) | \ + (((uint32) (uchar) (A)[2]) << 16) |\ + (((uint32) (uchar) (A)[1]) << 8) | \ + ((uint32) (uchar) (A)[0])) : \ + (((uint32) (uchar) (A)[2]) << 16) |\ + (((uint32) (uchar) (A)[1]) << 8) | \ + ((uint32) (uchar) (A)[0]))) +#define sint4korr(A) (*((long *) (A))) +#define uint2korr(A) (*((uint16 *) (A))) +#define uint3korr(A) (long) (*((unsigned long *) (A)) & 0xFFFFFF) +#define uint4korr(A) (*((unsigned long *) (A))) +#define int2store(T,A) *((uint16*) (T))= (uint16) (A) +#define int3store(T,A) { *(T)= (uchar) ((A));\ + *(T+1)=(uchar) (((uint) (A) >> 8));\ + *(T+2)=(uchar) (((A) >> 16)); } +#define int4store(T,A) *((long *) (T))= (long) (A) + +#define doubleget(V,M) { *((long *) &V) = *((long*) M); \ + *(((long *) &V)+1) = *(((long*) M)+1); } +#define doublestore(T,V) { *((long *) T) = *((long*) &V); \ + *(((long *) T)+1) = *(((long*) &V)+1); } + +#define HAVE_PERROR +#define HAVE_VFPRINT +#define HAVE_CHSIZE /* System has chsize() function */ +#define HAVE_RENAME /* Have rename() as function */ +#define HAVE_BINARY_STREAMS /* Have "b" flag in streams */ +#define HAVE_LONG_JMP /* Have long jump function */ +#define HAVE_LOCKING /* have locking() call */ +#define HAVE_ERRNO_AS_DEFINE /* errno is a define */ +#define HAVE_STDLIB /* everything is include in this file */ +#define HAVE_MEMCPY +#define HAVE_MEMMOVE +#define HAVE_GETCWD +#define HAVE_TELL +#define HAVE_PUTENV +#define HAVE_SELECT +#define HAVE_SETLOCALE +#define HAVE_SOCKET /* Giangi */ +#define HAVE_FLOAT_H +#define HAVE_LIMITS_H +#define HAVE_STDDEF_H + +#ifdef _MSC_VER +#define HAVE_LDIV /* The optimizer breaks in zortech for ldiv */ +#define HAVE_ANSI_INCLUDE +#define HAVE_SYS_UTIME_H +#define HAVE_STRTOUL +#endif + +/* MYSQL OPTIONS */ + +#define DEFAULT_MYSQL_HOME "c:\\mysql" +#define PACKAGE "mysql" +#define PROTOCOL_VERSION 10 diff --git a/ext/mysql/libmysql/configure.in b/ext/mysql/libmysql/configure.in new file mode 100644 index 0000000000..210dd70d95 --- /dev/null +++ b/ext/mysql/libmysql/configure.in @@ -0,0 +1,180 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(libmysql.c) + +dnl Checks for programs. +AC_PROG_AWK +AC_PROG_YACC +AC_PROG_CC +AC_PROG_INSTALL +AC_PROG_LN_S +AC_PROG_RANLIB + +dnl Checks for libraries. +AC_ARG_WITH(mysql,--with-mysql=DIR Where to look for mysql libraries/includes, \ +MYSQL_DIR="${withval}", MYSQL_DIR="/usr/local/mysql") + + + +dnl Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS(pwd.h sgtty.h sys/ioctl.h termio.h) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_INLINE +AC_CHECK_SIZEOF(long long, 8) +AC_TYPE_SIZE_T +AC_HEADER_TIME +AC_TYPE_UID_T + +dnl Checks for library functions. +AC_TYPE_SIGNAL +AC_CHECK_FUNCS( +bmove \ +getcwd \ +gethostbyname_r \ +getpwnam GETRUSAGE \ +getwd \ +longjmp \ +realpath \ +access \ +strtoull \ +tempnam \ +pthread_getsequence_np \ +pthread_setschedparamselect \ +socket \ +) + +#---START: Used in for client configure + +# Check definition of gethostbyname_r (glibc2.0.100 is different from Solaris) +ac_save_CXXFLAGS="$CXXFLAGS" +AC_CACHE_CHECK([style of gethostname_r routines], mysql_cv_gethostname_style, +AC_LANG_SAVE +AC_LANG_CPLUSPLUS +if test "$ac_cv_prog_gxx" = "yes" +then + CXXFLAGS="$CXXFLAGS -Werror" +fi +AC_TRY_COMPILE( +[#ifndef SCO +#define _REENTRANT +#endif +#include <pthread.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h>], +[int skr; + + int res = gethostbyname_r((const char *) 0, + (struct hostent*) 0, (char*) 0, 0, (struct hostent **) 0, &skr);], +mysql_cv_gethostname_style=glibc2, mysql_cv_gethostname_style=other)) +AC_LANG_RESTORE +CXXFLAGS="$ac_save_CXXFLAGS" +if test "$mysql_cv_gethostname_style" = "glibc2" +then + AC_DEFINE(HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R) +fi + +if test "$with_mit_threads" = "no" +then + # Check definition of pthread_getspecific + AC_CACHE_CHECK("args to pthread_getspecific", mysql_cv_getspecific_args, + AC_TRY_COMPILE( +[#ifndef SCO +#define _REENTRANT +#endif +#define _POSIX_PTHREAD_SEMANTICS +#include <pthread.h> ], +[ void *pthread_getspecific(pthread_key_t key); +pthread_getspecific((pthread_key_t) NULL); ], +mysql_cv_getspecific_args=POSIX, mysql_cv_getspecific_args=other)) + if test "$mysql_cv_getspecific_args" = "other" + then + AC_DEFINE(HAVE_NONPOSIX_PTHREAD_GETSPECIFIC) + fi + + # Check definition of pthread_mutex_init + AC_CACHE_CHECK("args to pthread_mutex_init", mysql_cv_mutex_init_args, + AC_TRY_COMPILE( +[#ifndef SCO +#define _REENTRANT +#endif +#define _POSIX_PTHREAD_SEMANTICS +#include <pthread.h> ], +[ + pthread_mutexattr_t attr; + pthread_mutex_t mp; + pthread_mutex_init(&mp,&attr); ], +mysql_cv_mutex_init_args=POSIX, mysql_cv_mutex_init_args=other)) + if test "$mysql_cv_mutex_init_args" = "other" + then + AC_DEFINE(HAVE_NONPOSIX_PTHREAD_MUTEX_INIT) + fi +fi +#---END: + +#---START: Used in for client configure +# Check definition of readdir_r +AC_CACHE_CHECK("args to readdir_r", mysql_cv_readdir_r, +AC_TRY_LINK( +[#ifndef SCO +#define _REENTRANT +#endif +#define _POSIX_PTHREAD_SEMANTICS +#include <pthread.h> +#include <dirent.h>], +[ int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result); +readdir_r((DIR *) NULL, (struct dirent *) NULL, (struct dirent **) NULL); ], +mysql_cv_readdir_r=POSIX, mysql_cv_readdir_r=other)) +if test "$mysql_cv_readdir_r" = "POSIX" +then + AC_DEFINE(HAVE_READDIR_R) +fi + +# Check definition av posix sigwait() +AC_CACHE_CHECK("style of sigwait", mysql_cv_sigwait, +AC_TRY_LINK( +[#ifndef SCO +#define _REENTRANT +#endif +#define _POSIX_PTHREAD_SEMANTICS +#include <pthread.h> +#include <signal.h>], +[#ifndef _AIX +sigset_t set; +int sig; +sigwait(&set,&sig); +#endif], +mysql_cv_sigwait=POSIX, mysql_cv_sigwait=other)) +if test "$mysql_cv_sigwait" = "POSIX" +then + AC_DEFINE(HAVE_SIGWAIT) +fi + +if test "$mysql_cv_sigwait" != "POSIX" +then +unset mysql_cv_sigwait +# Check definition av posix sigwait() +AC_CACHE_CHECK("style of sigwait", mysql_cv_sigwait, +AC_TRY_LINK( +[#ifndef SCO +#define _REENTRANT +#endif +#define _POSIX_PTHREAD_SEMANTICS +#include <pthread.h> +#include <signal.h>], +[sigset_t set; +int sig; +sigwait(&set);], +mysql_cv_sigwait=NONPOSIX, mysql_cv_sigwait=other)) +if test "$mysql_cv_sigwait" = "NONPOSIX" +then + AC_DEFINE(HAVE_NONPOSIX_SIGWAIT) +fi +fi +#---END: + +AC_OUTPUT(Makefile) diff --git a/ext/mysql/libmysql/ct_init.c b/ext/mysql/libmysql/ct_init.c new file mode 100644 index 0000000000..b0b1a8e126 --- /dev/null +++ b/ext/mysql/libmysql/ct_init.c @@ -0,0 +1,6 @@ +/* Generate definitions of ctype arrays +*/ + +#include <global.h> +#define CTYPE_LIBRARY /* initialize ctype arrays */ +#include "m_ctype.h" diff --git a/ext/mysql/libmysql/ctype-latin1.c b/ext/mysql/libmysql/ctype-latin1.c new file mode 100644 index 0000000000..f6b135b1c6 --- /dev/null +++ b/ext/mysql/libmysql/ctype-latin1.c @@ -0,0 +1,139 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* This implements the ISO 8859 Latin1 character-set */ + +#include <global.h> +#include "m_string.h" + +uchar NEAR ctype_latin1[257] = { +0, +32,32,32,32,32,32,32,32,32,40,40,40,40,40,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +72,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, +132,132,132,132,132,132,132,132,132,132,16,16,16,16,16,16, +16,129,129,129,129,129,129,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,16,16,16,16,16, +16,130,130,130,130,130,130,2,2,2,2,2,2,2,2,2, +2,2,2,2,2,2,2,2,2,2,2,16,16,16,16,32, +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, +72,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, +16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,16,1,1,1,1,1,1,1,2, +2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, +2,2,2,2,2,2,2,16,2,2,2,2,2,2,2,2, +}; + +uchar NEAR to_lower_latin1[]={ +'\000','\001','\002','\003','\004','\005','\006','\007', +'\010','\011','\012','\013','\014','\015','\016','\017', +'\020','\021','\022','\023','\024','\025','\026','\027', +'\030','\031','\032','\033','\034','\035','\036','\037', +' ', '!', '"', '#', '$', '%', '&', '\'', +'(', ')', '*', '+', ',', '-', '.', '/', +'0', '1', '2', '3', '4', '5', '6', '7', +'8', '9', ':', ';', '<', '=', '>', '?', +'@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', +'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', +'p', 'q', 'r', 's', 't', 'u', 'v', 'w', +'x', 'y', 'z', '[', '\\', ']', '^', '_', +'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', +'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', +'p', 'q', 'r', 's', 't', 'u', 'v', 'w', +'x', 'y', 'z', '{', '|', '}', '~', '\177', + +(uchar) '\200',(uchar) '\201',(uchar) '\202',(uchar) '\203',(uchar) '\204',(uchar) '\205',(uchar) '\206',(uchar) '\207', +(uchar) '\210',(uchar) '\211',(uchar) '\212',(uchar) '\213',(uchar) '\214',(uchar) '\215',(uchar) '\216',(uchar) '\217', +(uchar) '\220',(uchar) '\221',(uchar) '\222',(uchar) '\223',(uchar) '\224',(uchar) '\225',(uchar) '\226',(uchar) '\227', +(uchar) '\230',(uchar) '\231',(uchar) '\232',(uchar) '\233',(uchar) '\234',(uchar) '\235',(uchar) '\236',(uchar) '\237', +(uchar) '\240',(uchar) '\241',(uchar) '\242',(uchar) '\243',(uchar) '\244',(uchar) '\245',(uchar) '\246',(uchar) '\247', +(uchar) '\250',(uchar) '\251',(uchar) '\252',(uchar) '\253',(uchar) '\254',(uchar) '\255',(uchar) '\256',(uchar) '\257', +(uchar) '\260',(uchar) '\261',(uchar) '\262',(uchar) '\263',(uchar) '\264',(uchar) '\265',(uchar) '\266',(uchar) '\267', +(uchar) '\270',(uchar) '\271',(uchar) '\272',(uchar) '\273',(uchar) '\274',(uchar) '\275',(uchar) '\276',(uchar) '\277', +(uchar) '\340',(uchar) '\341',(uchar) '\342',(uchar) '\343',(uchar) '\344',(uchar) '\345',(uchar) '\346',(uchar) '\347', +(uchar) '\350',(uchar) '\351',(uchar) '\352',(uchar) '\353',(uchar) '\354',(uchar) '\355',(uchar) '\356',(uchar) '\357', +(uchar) '\360',(uchar) '\361',(uchar) '\362',(uchar) '\363',(uchar) '\364',(uchar) '\365',(uchar) '\366',(uchar) '\327', +(uchar) '\370',(uchar) '\371',(uchar) '\372',(uchar) '\373',(uchar) '\374',(uchar) '\375',(uchar) '\376',(uchar) '\337', +(uchar) '\340',(uchar) '\341',(uchar) '\342',(uchar) '\343',(uchar) '\344',(uchar) '\345',(uchar) '\346',(uchar) '\347', +(uchar) '\350',(uchar) '\351',(uchar) '\352',(uchar) '\353',(uchar) '\354',(uchar) '\355',(uchar) '\356',(uchar) '\357', +(uchar) '\360',(uchar) '\361',(uchar) '\362',(uchar) '\363',(uchar) '\364',(uchar) '\365',(uchar) '\366',(uchar) '\367', +(uchar) '\370',(uchar) '\371',(uchar) '\372',(uchar) '\373',(uchar) '\374',(uchar) '\375',(uchar) '\376',(uchar) '\377', +}; + +uchar NEAR to_upper_latin1[]={ +'\000','\001','\002','\003','\004','\005','\006','\007', +'\010','\011','\012','\013','\014','\015','\016','\017', +'\020','\021','\022','\023','\024','\025','\026','\027', +'\030','\031','\032','\033','\034','\035','\036','\037', +' ', '!', '"', '#', '$', '%', '&', '\'', +'(', ')', '*', '+', ',', '-', '.', '/', +'0', '1', '2', '3', '4', '5', '6', '7', +'8', '9', ':', ';', '<', '=', '>', '?', +'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', +'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', +'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', +'X', 'Y', 'Z', '[', '\\', ']', '^', '_', +'`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', +'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', +'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', +'X', 'Y', 'Z', '{', '|', '}', '~', '\177', + +(uchar) '\200',(uchar) '\201',(uchar) '\202',(uchar) '\203',(uchar) '\204',(uchar) '\205',(uchar) '\206',(uchar) '\207', +(uchar) '\210',(uchar) '\211',(uchar) '\212',(uchar) '\213',(uchar) '\214',(uchar) '\215',(uchar) '\216',(uchar) '\217', +(uchar) '\220',(uchar) '\221',(uchar) '\222',(uchar) '\223',(uchar) '\224',(uchar) '\225',(uchar) '\226',(uchar) '\227', +(uchar) '\230',(uchar) '\231',(uchar) '\232',(uchar) '\233',(uchar) '\234',(uchar) '\235',(uchar) '\236',(uchar) '\237', +(uchar) '\240',(uchar) '\241',(uchar) '\242',(uchar) '\243',(uchar) '\244',(uchar) '\245',(uchar) '\246',(uchar) '\247', +(uchar) '\250',(uchar) '\251',(uchar) '\252',(uchar) '\253',(uchar) '\254',(uchar) '\255',(uchar) '\256',(uchar) '\257', +(uchar) '\260',(uchar) '\261',(uchar) '\262',(uchar) '\263',(uchar) '\264',(uchar) '\265',(uchar) '\266',(uchar) '\267', +(uchar) '\270',(uchar) '\271',(uchar) '\272',(uchar) '\273',(uchar) '\274',(uchar) '\275',(uchar) '\276',(uchar) '\277', +(uchar) '\300',(uchar) '\301',(uchar) '\302',(uchar) '\303',(uchar) '\304',(uchar) '\305',(uchar) '\306',(uchar) '\307', +(uchar) '\310',(uchar) '\311',(uchar) '\312',(uchar) '\313',(uchar) '\314',(uchar) '\315',(uchar) '\316',(uchar) '\317', +(uchar) '\320',(uchar) '\321',(uchar) '\322',(uchar) '\323',(uchar) '\324',(uchar) '\325',(uchar) '\326',(uchar) '\327', +(uchar) '\330',(uchar) '\331',(uchar) '\332',(uchar) '\333',(uchar) '\334',(uchar) '\335',(uchar) '\336',(uchar) '\337', +(uchar) '\300',(uchar) '\301',(uchar) '\302',(uchar) '\303',(uchar) '\304',(uchar) '\305',(uchar) '\306',(uchar) '\307', +(uchar) '\310',(uchar) '\311',(uchar) '\312',(uchar) '\313',(uchar) '\314',(uchar) '\315',(uchar) '\316',(uchar) '\317', +(uchar) '\320',(uchar) '\321',(uchar) '\322',(uchar) '\323',(uchar) '\324',(uchar) '\325',(uchar) '\326',(uchar) '\367', +(uchar) '\330',(uchar) '\331',(uchar) '\332',(uchar) '\333',(uchar) '\334',(uchar) '\335',(uchar) '\336',(uchar) '\377', +}; + +#ifndef __WIN32__ +uchar NEAR sort_order_latin1[]={ +#else +uchar sort_order_latin1[]={ +#endif +'\000','\001','\002','\003','\004','\005','\006','\007', +'\010','\011','\012','\013','\014','\015','\016','\017', +'\020','\021','\022','\023','\024','\025','\026','\027', +'\030','\031','\032','\033','\034','\035','\036','\037', +' ', '!', '"', '#', '$', '%', '&', '\'', +'(', ')', '*', '+', ',', '-', '.', '/', +'0', '1', '2', '3', '4', '5', '6', '7', +'8', '9', ':', ';', '<', '=', '>', '?', +'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', +'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', +'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', +'X', 'Y', 'Z', '[', '\\', ']', '^', '_', +'`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', +'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', +'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', +'X', 'Y', 'Z', '{', '|', '}', '~', '\177', + +(uchar) '\200',(uchar) '\201',(uchar) '\202',(uchar) '\203',(uchar) '\204',(uchar) '\205',(uchar) '\206',(uchar) '\207', +(uchar) '\210',(uchar) '\211',(uchar) '\212',(uchar) '\213',(uchar) '\214',(uchar) '\215',(uchar) '\216',(uchar) '\217', +(uchar) '\220',(uchar) '\221',(uchar) '\222',(uchar) '\223',(uchar) '\224',(uchar) '\225',(uchar) '\226',(uchar) '\227', +(uchar) '\230',(uchar) '\231',(uchar) '\232',(uchar) '\233',(uchar) '\234',(uchar) '\235',(uchar) '\236',(uchar) '\237', +(uchar) '\240',(uchar) '\241',(uchar) '\242',(uchar) '\243',(uchar) '\244',(uchar) '\245',(uchar) '\246',(uchar) '\247', +(uchar) '\250',(uchar) '\251',(uchar) '\252',(uchar) '\253',(uchar) '\254',(uchar) '\255',(uchar) '\256',(uchar) '\257', +(uchar) '\260',(uchar) '\261',(uchar) '\262',(uchar) '\263',(uchar) '\264',(uchar) '\265',(uchar) '\266',(uchar) '\267', +(uchar) '\270',(uchar) '\271',(uchar) '\272',(uchar) '\273',(uchar) '\274',(uchar) '\275',(uchar) '\276',(uchar) '\277', +'A', 'A', 'A', 'A', '\\', '[', '\\', 'C', +'E', 'E', 'E', 'E', 'I', 'I', 'I', 'I', +'D', 'N', 'O', 'O', 'O', 'O', ']', (uchar) '\327', +(uchar) '\330','U', 'U', 'U', 'Y', 'Y', (uchar) '\336',(uchar) '\337', +'A', 'A', 'A', 'A', '\\', '[', '\\', 'C', +'E', 'E', 'E', 'E', 'I', 'I', 'I', 'I', +'D', 'N', 'O', 'O', 'O', 'O', ']', (uchar) '\367', +(uchar) '\330','U', 'U', 'U', 'Y', 'Y', (uchar) '\336',(uchar) '\377', +}; diff --git a/ext/mysql/libmysql/dbug.c b/ext/mysql/libmysql/dbug.c new file mode 100644 index 0000000000..8eb5fea5eb --- /dev/null +++ b/ext/mysql/libmysql/dbug.c @@ -0,0 +1,2074 @@ +/****************************************************************************** + * * + * N O T I C E * + * * + * Copyright Abandoned, 1987, Fred Fish * + * * + * * + * This previously copyrighted work has been placed into the public * + * domain by the author and may be freely used for any purpose, * + * private or commercial. * + * * + * Because of the number of inquiries I was receiving about the use * + * of this product in commercially developed works I have decided to * + * simply make it public domain to further its unrestricted use. I * + * specifically would be most happy to see this material become a * + * part of the standard Unix distributions by AT&T and the Berkeley * + * Computer Science Research Group, and a standard part of the GNU * + * system from the Free Software Foundation. * + * * + * I would appreciate it, as a courtesy, if this notice is left in * + * all copies and derivative works. Thank you. * + * * + * The author makes no warranty of any kind with respect to this * + * product and explicitly disclaims any implied warranties of mer- * + * chantability or fitness for any particular purpose. * + * * + ****************************************************************************** + */ + + +/* + * FILE + * + * dbug.c runtime support routines for dbug package + * + * SCCS + * + * @(#)dbug.c 1.25 7/25/89 + * + * DESCRIPTION + * + * These are the runtime support routines for the dbug package. + * The dbug package has two main components; the user include + * file containing various macro definitions, and the runtime + * support routines which are called from the macro expansions. + * + * Externally visible functions in the runtime support module + * use the naming convention pattern "_db_xx...xx_", thus + * they are unlikely to collide with user defined function names. + * + * AUTHOR(S) + * + * Fred Fish (base code) + * Enhanced Software Technologies, Tempe, AZ + * asuvax!mcdphx!estinc!fnf + * + * Binayak Banerjee (profiling enhancements) + * seismo!bpa!sjuvax!bbanerje + * + * Michael Widenius: + * DBUG_DUMP - To dump a pice of memory. + * PUSH_FLAG "O" - To be used insted of "o" if we don't + * want flushing (for slow systems) + * PUSH_FLAG "A" - as 'O', but we will append to the out file instead + * of creating a new one. + * Check of malloc on entry/exit (option "S") + */ + +#ifdef DBUG_OFF +#undef DBUG_OFF +#endif +#include <global.h> +#include <m_string.h> +#include <errno.h> +#if defined(MSDOS) || defined(__WIN32__) +#include <process.h> +#endif + +#ifdef _DBUG_CONDITION_ +#define _DBUG_START_CONDITION_ "d:t" +#else +#define _DBUG_START_CONDITION_ "" +#endif + +/* + * Manifest constants that should not require any changes. + */ + +#define EOS '\000' /* End Of String marker */ + +/* + * Manifest constants which may be "tuned" if desired. + */ + +#define PRINTBUF 1024 /* Print buffer size */ +#define INDENT 2 /* Indentation per trace level */ +#define MAXDEPTH 200 /* Maximum trace depth default */ + +/* + * The following flags are used to determine which + * capabilities the user has enabled with the state + * push macro. + */ + +#define TRACE_ON 000001 /* Trace enabled */ +#define DEBUG_ON 000002 /* Debug enabled */ +#define FILE_ON 000004 /* File name print enabled */ +#define LINE_ON 000010 /* Line number print enabled */ +#define DEPTH_ON 000020 /* Function nest level print enabled */ +#define PROCESS_ON 000040 /* Process name print enabled */ +#define NUMBER_ON 000100 /* Number each line of output */ +#define PROFILE_ON 000200 /* Print out profiling code */ +#define PID_ON 000400 /* Identify each line with process id */ +#define SANITY_CHECK_ON 001000 /* Check safemalloc on DBUG_ENTER */ +#define FLUSH_ON_WRITE 002000 /* Flush on every write */ + +#define TRACING (stack -> flags & TRACE_ON) +#define DEBUGGING (stack -> flags & DEBUG_ON) +#define PROFILING (stack -> flags & PROFILE_ON) +#define STREQ(a,b) (strcmp(a,b) == 0) + +/* + * Typedefs to make things more obvious. + */ + +#ifndef __WIN32__ +typedef int BOOLEAN; +#else +#define BOOLEAN BOOL +#endif + +/* + * Make it easy to change storage classes if necessary. + */ + +#define IMPORT extern /* Names defined externally */ +#define EXPORT /* Allocated here, available globally */ +#define AUTO auto /* Names to be allocated on stack */ +#define REGISTER register /* Names to be placed in registers */ + +/* + * The default file for profiling. Could also add another flag + * (G?) which allowed the user to specify this. + * + * If the automatic variables get allocated on the stack in + * reverse order from their declarations, then define AUTOS_REVERSE. + * This is used by the code that keeps track of stack usage. For + * forward allocation, the difference in the dbug frame pointers + * represents stack used by the callee function. For reverse allocation, + * the difference represents stack used by the caller function. + * + */ + +#define PROF_FILE "dbugmon.out" +#define PROF_EFMT "E\t%ld\t%s\n" +#define PROF_SFMT "S\t%lx\t%lx\t%s\n" +#define PROF_XFMT "X\t%ld\t%s\n" + +#ifdef M_I386 /* predefined by xenix 386 compiler */ +#define AUTOS_REVERSE 1 +#endif + +/* + * Variables which are available externally but should only + * be accessed via the macro package facilities. + */ + +EXPORT FILE *_db_fp_ = (FILE *) 0; /* Output stream, default stderr */ +EXPORT char *_db_process_ = (char*) "dbug"; /* Pointer to process name; argv[0] */ +EXPORT FILE *_db_pfp_ = (FILE *)0; /* Profile stream, 'dbugmon.out' */ +EXPORT BOOLEAN _db_on_ = FALSE; /* TRUE if debugging currently on */ +EXPORT BOOLEAN _db_pon_ = FALSE; /* TRUE if profile currently on */ +EXPORT BOOLEAN _no_db_ = FALSE; /* TRUE if no debugging at all */ + +/* + * Externally supplied functions. + */ + +#ifndef HAVE_PERROR +static void perror (); /* Fake system/library error print routine */ +#endif + +IMPORT int _sanity(const char *file,uint line); + +/* + * The user may specify a list of functions to trace or + * debug. These lists are kept in a linear linked list, + * a very simple implementation. + */ + +struct link { + char *str; /* Pointer to link's contents */ + struct link *next_link; /* Pointer to the next link */ +}; + +/* + * Debugging states can be pushed or popped off of a + * stack which is implemented as a linked list. Note + * that the head of the list is the current state and the + * stack is pushed by adding a new state to the head of the + * list or popped by removing the first link. + */ + +struct state { + int flags; /* Current state flags */ + int maxdepth; /* Current maximum trace depth */ + uint delay; /* Delay after each output line */ + int sub_level; /* Sub this from code_state->level */ + FILE *out_file; /* Current output stream */ + FILE *prof_file; /* Current profiling stream */ + char name[FN_REFLEN]; /* Name of output file */ + struct link *functions; /* List of functions */ + struct link *p_functions; /* List of profiled functions */ + struct link *keywords; /* List of debug keywords */ + struct link *processes; /* List of process names */ + struct state *next_state; /* Next state in the list */ +}; + + +/* + * Local variables not seen by user. + */ + + +static my_bool init_done = FALSE; /* Set to TRUE when initialization done */ +static struct state *stack=0; + +typedef struct st_code_state { + int lineno; /* Current debugger output line number */ + int level; /* Current function nesting level */ + const char *func; /* Name of current user function */ + const char *file; /* Name of current user file */ + char **framep; /* Pointer to current frame */ + int jmplevel; /* Remember nesting level at setjmp () */ + const char *jmpfunc; /* Remember current function for setjmp */ + const char *jmpfile; /* Remember current file for setjmp */ + +/* + * The following variables are used to hold the state information + * between the call to _db_pargs_() and _db_doprnt_(), during + * expansion of the DBUG_PRINT macro. This is the only macro + * that currently uses these variables. + * + * These variables are currently used only by _db_pargs_() and + * _db_doprnt_(). + */ + + uint u_line; /* User source code line number */ + const char *u_keyword; /* Keyword for current macro */ + int locked; /* If locked with _db_lock_file */ +} CODE_STATE; + + /* Parse a debug command string */ +static struct link *ListParse(char *ctlp); + /* Make a fresh copy of a string */ +static char *StrDup(const char *str); + /* Open debug output stream */ +static void DBUGOpenFile(const char *name, int append); +#ifndef THREAD + /* Open profile output stream */ +static FILE *OpenProfile(const char *name); + /* Profile if asked for it */ +static BOOLEAN DoProfile(void); +#endif + /* Return current user time (ms) */ +#ifndef THREAD +static unsigned long Clock (void); +#endif + /* Close debug output stream */ +static void CloseFile(FILE *fp); + /* Push current debug state */ +static void PushState(void); + /* Test for tracing enabled */ +static BOOLEAN DoTrace(CODE_STATE *state); + /* Test to see if file is writable */ +#if !(!defined(HAVE_ACCESS) || defined(MSDOS)) +static BOOLEAN Writable(char *pathname); + /* Change file owner and group */ +static void ChangeOwner(char *pathname); + /* Allocate memory for runtime support */ +#endif +static char *DbugMalloc(int size); + /* Remove leading pathname components */ +static char *BaseName(const char *pathname); +static void DoPrefix(uint line); +static void FreeList(struct link *linkp); +static void Indent(int indent); +static BOOLEAN InList(struct link *linkp,const char *cp); +static void dbug_flush(CODE_STATE *); +static void DbugExit(const char *why); +static int DelayArg(int value); + /* Supplied in Sys V runtime environ */ + /* Break string into tokens */ +static char *static_strtok(char *s1,pchar chr); + +/* + * Miscellaneous printf format strings. + */ + +#define ERR_MISSING_RETURN "%s: missing DBUG_RETURN or DBUG_VOID_RETURN macro in function \"%s\"\n" +#define ERR_OPEN "%s: can't open debug output stream \"%s\": " +#define ERR_CLOSE "%s: can't close debug file: " +#define ERR_ABORT "%s: debugger aborting because %s\n" +#define ERR_CHOWN "%s: can't change owner/group of \"%s\": " + +/* + * Macros and defines for testing file accessibility under UNIX and MSDOS. + */ + +#if !defined(HAVE_ACCESS) || defined(MSDOS) +#define EXISTS(pathname) (FALSE) /* Assume no existance */ +#define Writable(name) (TRUE) +#define ChangeOwner(name) +#else +#define EXISTS(pathname) (access (pathname, F_OK) == 0) +#define WRITABLE(pathname) (access (pathname, W_OK) == 0) +#endif + +/* + * Translate some calls among different systems. + */ + +#if defined(unix) || defined(xenix) || defined(VMS) || defined(__NetBSD__) +# define Delay(A) sleep((uint) A) +#elif defined(AMIGA) +IMPORT int Delay (); /* Pause for given number of ticks */ +#else +static int Delay(int ticks); +#endif + + +/* +** Macros to allow dbugging with threads +*/ + +#ifdef THREAD +#include <my_pthread.h> +pthread_mutex_t THR_LOCK_dbug; + +static void init_dbug_state(void) +{ + pthread_mutex_init(&THR_LOCK_dbug,NULL); +} + +static CODE_STATE *code_state(void) +{ + CODE_STATE *state=0; + struct st_my_thread_var *tmp=my_thread_var; + if (tmp) + { + if (!(state=(CODE_STATE *) tmp->dbug)) + { + state=(CODE_STATE*) DbugMalloc(sizeof(*state)); + bzero((char*) state,sizeof(*state)); + state->func="?func"; + state->file="?file"; + tmp->dbug=(gptr) state; + } + } + return state; +} + +#else /* !THREAD */ + +#define init_dbug_state() +#define code_state() (&static_code_state) +#define pthread_mutex_lock(A) {} +#define pthread_mutex_unlock(A) {} +static CODE_STATE static_code_state = { 0,0,"?func","?file",NULL,0,NULL, + NULL,0,"?",0}; +#endif + + +/* + * FUNCTION + * + * _db_push_ push current debugger state and set up new one + * + * SYNOPSIS + * + * VOID _db_push_ (control) + * char *control; + * + * DESCRIPTION + * + * Given pointer to a debug control string in "control", pushes + * the current debug state, parses the control string, and sets + * up a new debug state. + * + * The only attribute of the new state inherited from the previous + * state is the current function nesting level. This can be + * overridden by using the "r" flag in the control string. + * + * The debug control string is a sequence of colon separated fields + * as follows: + * + * <field_1>:<field_2>:...:<field_N> + * + * Each field consists of a mandatory flag character followed by + * an optional "," and comma separated list of modifiers: + * + * flag[,modifier,modifier,...,modifier] + * + * The currently recognized flag characters are: + * + * d Enable output from DBUG_<N> macros for + * for the current state. May be followed + * by a list of keywords which selects output + * only for the DBUG macros with that keyword. + * A null list of keywords implies output for + * all macros. + * + * D Delay after each debugger output line. + * The argument is the number of tenths of seconds + * to delay, subject to machine capabilities. + * I.E. -#D,20 is delay two seconds. + * + * f Limit debugging and/or tracing, and profiling to the + * list of named functions. Note that a null list will + * disable all functions. The appropriate "d" or "t" + * flags must still be given, this flag only limits their + * actions if they are enabled. + * + * F Identify the source file name for each + * line of debug or trace output. + * + * i Identify the process with the pid for each line of + * debug or trace output. + * + * g Enable profiling. Create a file called 'dbugmon.out' + * containing information that can be used to profile + * the program. May be followed by a list of keywords + * that select profiling only for the functions in that + * list. A null list implies that all functions are + * considered. + * + * L Identify the source file line number for + * each line of debug or trace output. + * + * n Print the current function nesting depth for + * each line of debug or trace output. + * + * N Number each line of dbug output. + * + * o Redirect the debugger output stream to the + * specified file. The default output is stderr. + * + * O As O but the file is really flushed between each + * write. When neaded the file is closed and reopened + * between each write. + * + * p Limit debugger actions to specified processes. + * A process must be identified with the + * DBUG_PROCESS macro and match one in the list + * for debugger actions to occur. + * + * P Print the current process name for each + * line of debug or trace output. + * + * r When pushing a new state, do not inherit + * the previous state's function nesting level. + * Useful when the output is to start at the + * left margin. + * + * S Do function _sanity(_file_,_line_) at each + * debugged function until _sanity() returns + * something that differs from 0. + * (Moustly used with safemalloc) + * + * t Enable function call/exit trace lines. + * May be followed by a list (containing only + * one modifier) giving a numeric maximum + * trace level, beyond which no output will + * occur for either debugging or tracing + * macros. The default is a compile time + * option. + * + * Some examples of debug control strings which might appear + * on a shell command line (the "-#" is typically used to + * introduce a control string to an application program) are: + * + * -#d:t + * -#d:f,main,subr1:F:L:t,20 + * -#d,input,output,files:n + * + * For convenience, any leading "-#" is stripped off. + * + */ + +void _db_push_ (control) +const char *control; +{ + reg1 char *scan; + reg2 struct link *temp; + CODE_STATE *state; + char *new_str; + + if (! _db_fp_) + _db_fp_= stderr; /* Output stream, default stderr */ + + if (control && *control == '-') + { + if (*++control == '#') + control++; + } + if (*control) + _no_db_=0; /* We are using dbug after all */ + + new_str = StrDup (control); + PushState (); + state=code_state(); + + scan = static_strtok (new_str, ':'); + for (; scan != NULL; scan = static_strtok ((char *)NULL, ':')) { + switch (*scan++) { + case 'd': + _db_on_ = TRUE; + stack -> flags |= DEBUG_ON; + if (*scan++ == ',') { + stack -> keywords = ListParse (scan); + } + break; + case 'D': + stack -> delay = 0; + if (*scan++ == ',') { + temp = ListParse (scan); + stack -> delay = DelayArg (atoi (temp -> str)); + FreeList (temp); + } + break; + case 'f': + if (*scan++ == ',') { + stack -> functions = ListParse (scan); + } + break; + case 'F': + stack -> flags |= FILE_ON; + break; + case 'i': + stack -> flags |= PID_ON; + break; +#ifndef THREAD + case 'g': + _db_pon_ = TRUE; + if (OpenProfile(PROF_FILE)) + { + stack -> flags |= PROFILE_ON; + if (*scan++ == ',') + stack -> p_functions = ListParse (scan); + } + break; +#endif + case 'L': + stack -> flags |= LINE_ON; + break; + case 'n': + stack -> flags |= DEPTH_ON; + break; + case 'N': + stack -> flags |= NUMBER_ON; + break; + case 'A': + case 'O': + stack -> flags |= FLUSH_ON_WRITE; + case 'a': + case 'o': + if (*scan++ == ',') { + temp = ListParse (scan); + DBUGOpenFile(temp -> str, (int) (scan[-2] == 'A' || scan[-2] == 'a')); + FreeList (temp); + } else { + DBUGOpenFile ("-",0); + } + break; + case 'p': + if (*scan++ == ',') { + stack -> processes = ListParse (scan); + } + break; + case 'P': + stack -> flags |= PROCESS_ON; + break; + case 'r': + stack->sub_level= state->level; + break; + case 't': + stack -> flags |= TRACE_ON; + if (*scan++ == ',') { + temp = ListParse (scan); + stack -> maxdepth = atoi (temp -> str); + FreeList (temp); + } + break; + case 'S': + stack -> flags |= SANITY_CHECK_ON; + break; + } + } + free (new_str); +} + + +/* + * FUNCTION + * + * _db_pop_ pop the debug stack + * + * DESCRIPTION + * + * Pops the debug stack, returning the debug state to its + * condition prior to the most recent _db_push_ invocation. + * Note that the pop will fail if it would remove the last + * valid state from the stack. This prevents user errors + * in the push/pop sequence from screwing up the debugger. + * Maybe there should be some kind of warning printed if the + * user tries to pop too many states. + * + */ + +void _db_pop_ () +{ + reg1 struct state *discard; + discard = stack; + if (discard != NULL && discard -> next_state != NULL) { + stack = discard -> next_state; + _db_fp_ = stack -> out_file; + _db_pfp_ = stack -> prof_file; + if (discard -> keywords != NULL) { + FreeList (discard -> keywords); + } + if (discard -> functions != NULL) { + FreeList (discard -> functions); + } + if (discard -> processes != NULL) { + FreeList (discard -> processes); + } + if (discard -> p_functions != NULL) { + FreeList (discard -> p_functions); + } + CloseFile (discard -> out_file); + if (discard -> prof_file) + CloseFile (discard -> prof_file); + free ((char *) discard); + if (!(stack->flags & DEBUG_ON)) + _db_on_=0; + } + else + { + _db_on_=0; + } +} + + +/* + * FUNCTION + * + * _db_enter_ process entry point to user function + * + * SYNOPSIS + * + * VOID _db_enter_ (_func_, _file_, _line_, + * _sfunc_, _sfile_, _slevel_, _sframep_) + * char *_func_; points to current function name + * char *_file_; points to current file name + * int _line_; called from source line number + * char **_sfunc_; save previous _func_ + * char **_sfile_; save previous _file_ + * int *_slevel_; save previous nesting level + * char ***_sframep_; save previous frame pointer + * + * DESCRIPTION + * + * Called at the beginning of each user function to tell + * the debugger that a new function has been entered. + * Note that the pointers to the previous user function + * name and previous user file name are stored on the + * caller's stack (this is why the ENTER macro must be + * the first "executable" code in a function, since it + * allocates these storage locations). The previous nesting + * level is also stored on the callers stack for internal + * self consistency checks. + * + * Also prints a trace line if tracing is enabled and + * increments the current function nesting depth. + * + * Note that this mechanism allows the debugger to know + * what the current user function is at all times, without + * maintaining an internal stack for the function names. + * + */ + +void _db_enter_ (_func_, _file_, _line_, _sfunc_, _sfile_, _slevel_, + _sframep_) +const char *_func_; +const char *_file_; +uint _line_; +const char **_sfunc_; +const char **_sfile_; +uint *_slevel_; +char ***_sframep_ __attribute__((unused)); +{ + reg1 CODE_STATE *state; + + if (!_no_db_) + { + int save_errno=errno; + if (!init_done) + _db_push_ (_DBUG_START_CONDITION_); + state=code_state(); + + *_sfunc_ = state->func; + *_sfile_ = state->file; + state->func =(char*) _func_; + state->file = (char*) _file_; /* BaseName takes time !! */ + *_slevel_ = ++state->level; +#ifndef THREAD + *_sframep_ = state->framep; + state->framep = (char **) _sframep_; + if (DoProfile ()) + { + long stackused; + if (*state->framep == NULL) { + stackused = 0; + } else { + stackused = ((long)(*state->framep)) - ((long)(state->framep)); + stackused = stackused > 0 ? stackused : -stackused; + } + (void) fprintf (_db_pfp_, PROF_EFMT , Clock (), state->func); +#ifdef AUTOS_REVERSE + (void) fprintf (_db_pfp_, PROF_SFMT, state->framep, stackused, *_sfunc_); +#else + (void) fprintf (_db_pfp_, PROF_SFMT, (ulong) state->framep, stackused, + state->func); +#endif + (void) fflush (_db_pfp_); + } +#endif + if (DoTrace (state)) + { + if (!state->locked) + pthread_mutex_lock(&THR_LOCK_dbug); + DoPrefix (_line_); + Indent (state -> level); + (void) fprintf (_db_fp_, ">%s\n", state->func); + dbug_flush (state); /* This does a unlock */ + } +#ifdef SAFEMALLOC + if (stack -> flags & SANITY_CHECK_ON) + if (_sanity(_file_,_line_)) /* Check of safemalloc */ + stack -> flags &= ~SANITY_CHECK_ON; +#endif + errno=save_errno; + } +} + +/* + * FUNCTION + * + * _db_return_ process exit from user function + * + * SYNOPSIS + * + * VOID _db_return_ (_line_, _sfunc_, _sfile_, _slevel_) + * int _line_; current source line number + * char **_sfunc_; where previous _func_ is to be retrieved + * char **_sfile_; where previous _file_ is to be retrieved + * int *_slevel_; where previous level was stashed + * + * DESCRIPTION + * + * Called just before user function executes an explicit or implicit + * return. Prints a trace line if trace is enabled, decrements + * the current nesting level, and restores the current function and + * file names from the defunct function's stack. + * + */ + +void _db_return_ (_line_, _sfunc_, _sfile_, _slevel_) +uint _line_; +const char **_sfunc_; +const char **_sfile_; +uint *_slevel_; +{ + CODE_STATE *state; + + if (!_no_db_) + { + int save_errno=errno; + if (!init_done) + _db_push_ (""); + if (!(state=code_state())) + return; /* Only happens at end of program */ + if (stack->flags & (TRACE_ON | DEBUG_ON | PROFILE_ON)) + { + if (!state->locked) + pthread_mutex_lock(&THR_LOCK_dbug); + if (state->level != (int) *_slevel_) + (void) fprintf (_db_fp_, ERR_MISSING_RETURN, _db_process_, + state->func); + else + { +#ifdef SAFEMALLOC + if (stack -> flags & SANITY_CHECK_ON) + if (_sanity(*_sfile_,_line_)) + stack->flags &= ~SANITY_CHECK_ON; +#endif +#ifndef THREAD + if (DoProfile ()) + (void) fprintf (_db_pfp_, PROF_XFMT, Clock(), state->func); +#endif + if (DoTrace (state)) + { + DoPrefix (_line_); + Indent (state->level); + (void) fprintf (_db_fp_, "<%s\n", state->func); + } + } + dbug_flush(state); + } + state->level = *_slevel_-1; + state->func = *_sfunc_; + state->file = *_sfile_; +#ifndef THREAD + if (state->framep != NULL) + state->framep = (char **) *state->framep; +#endif + errno=save_errno; + } +} + + +/* + * FUNCTION + * + * _db_pargs_ log arguments for subsequent use by _db_doprnt_() + * + * SYNOPSIS + * + * VOID _db_pargs_ (_line_, keyword) + * int _line_; + * char *keyword; + * + * DESCRIPTION + * + * The new universal printing macro DBUG_PRINT, which replaces + * all forms of the DBUG_N macros, needs two calls to runtime + * support routines. The first, this function, remembers arguments + * that are used by the subsequent call to _db_doprnt_(). + * + */ + +void _db_pargs_ (_line_, keyword) +uint _line_; +const char *keyword; +{ + CODE_STATE *state=code_state(); + state->u_line = _line_; + state->u_keyword = (char*) keyword; +} + + +/* + * FUNCTION + * + * _db_doprnt_ handle print of debug lines + * + * SYNOPSIS + * + * VOID _db_doprnt_ (format, va_alist) + * char *format; + * va_dcl; + * + * DESCRIPTION + * + * When invoked via one of the DBUG macros, tests the current keyword + * set by calling _db_pargs_() to see if that macro has been selected + * for processing via the debugger control string, and if so, handles + * printing of the arguments via the format string. The line number + * of the DBUG macro in the source is found in u_line. + * + * Note that the format string SHOULD NOT include a terminating + * newline, this is supplied automatically. + * + */ + +#include <stdarg.h> + +void _db_doprnt_ (const char *format,...) +{ + va_list args; + CODE_STATE *state; + state=code_state(); + + va_start(args,format); + + if (_db_keyword_ (state->u_keyword)) { + int save_errno=errno; + if (!state->locked) + pthread_mutex_lock(&THR_LOCK_dbug); + DoPrefix (state->u_line); + if (TRACING) { + Indent (state->level + 1); + } else { + (void) fprintf (_db_fp_, "%s: ", state->func); + } + (void) fprintf (_db_fp_, "%s: ", state->u_keyword); + (void) vfprintf (_db_fp_, format, args); + va_end(args); + (void) fputc('\n',_db_fp_); + dbug_flush(state); + errno=save_errno; + } + va_end(args); +} + + +/* + * FUNCTION + * + * _db_dump_ dump a string until '\0' is found + * + * SYNOPSIS + * + * void _db_dump_ (_line_,keyword,memory,length) + * int _line_; current source line number + * char *keyword; + * char *memory; Memory to print + * int length; Bytes to print + * + * DESCRIPTION + * Dump N characters in a binary array. + * Is used to examine corrputed memory or arrays. + */ + +void _db_dump_(_line_,keyword,memory,length) +uint _line_,length; +const char *keyword; +const char *memory; +{ + int pos; + char dbuff[90]; + CODE_STATE *state; + state=code_state(); + + if (_db_keyword_ ((char*) keyword)) + { + if (!state->locked) + pthread_mutex_lock(&THR_LOCK_dbug); + DoPrefix (_line_); + if (TRACING) + { + Indent (state->level + 1); + pos= min(max(state->level-stack->sub_level,0)*INDENT,80); + } + else + { + fprintf(_db_fp_, "%s: ", state->func); + } + sprintf(dbuff,"%s: Memory: %lx Bytes: (%d)\n", + keyword,(ulong) memory, length); + (void) fputs(dbuff,_db_fp_); + + pos=0; + while (length-- > 0) + { + uint tmp= *((unsigned char*) memory++); + if ((pos+=3) >= 80) + { + fputc('\n',_db_fp_); + pos=3; + } + fputc(_dig_vec[((tmp >> 4) & 15)], _db_fp_); + fputc(_dig_vec[tmp & 15], _db_fp_); + fputc(' ',_db_fp_); + } + (void) fputc('\n',_db_fp_); + dbug_flush(state); + } +} + +/* + * FUNCTION + * + * ListParse parse list of modifiers in debug control string + * + * SYNOPSIS + * + * static struct link *ListParse (ctlp) + * char *ctlp; + * + * DESCRIPTION + * + * Given pointer to a comma separated list of strings in "cltp", + * parses the list, building a list and returning a pointer to it. + * The original comma separated list is destroyed in the process of + * building the linked list, thus it had better be a duplicate + * if it is important. + * + * Note that since each link is added at the head of the list, + * the final list will be in "reverse order", which is not + * significant for our usage here. + * + */ + +static struct link *ListParse (ctlp) +char *ctlp; +{ + REGISTER char *start; + REGISTER struct link *new; + REGISTER struct link *head; + + head = NULL; + while (*ctlp != EOS) { + start = ctlp; + while (*ctlp != EOS && *ctlp != ',') { + ctlp++; + } + if (*ctlp == ',') { + *ctlp++ = EOS; + } + new = (struct link *) DbugMalloc (sizeof (struct link)); + new -> str = StrDup (start); + new -> next_link = head; + head = new; + } + return (head); +} + +/* + * FUNCTION + * + * InList test a given string for member of a given list + * + * SYNOPSIS + * + * static BOOLEAN InList (linkp, cp) + * struct link *linkp; + * char *cp; + * + * DESCRIPTION + * + * Tests the string pointed to by "cp" to determine if it is in + * the list pointed to by "linkp". Linkp points to the first + * link in the list. If linkp is NULL then the string is treated + * as if it is in the list (I.E all strings are in the null list). + * This may seem rather strange at first but leads to the desired + * operation if no list is given. The net effect is that all + * strings will be accepted when there is no list, and when there + * is a list, only those strings in the list will be accepted. + * + */ + +static BOOLEAN InList (linkp, cp) +struct link *linkp; +const char *cp; +{ + REGISTER struct link *scan; + REGISTER BOOLEAN accept; + + if (linkp == NULL) { + accept = TRUE; + } else { + accept = FALSE; + for (scan = linkp; scan != NULL; scan = scan -> next_link) { + if (STREQ (scan -> str, cp)) { + accept = TRUE; + break; + } + } + } + return (accept); +} + + +/* + * FUNCTION + * + * PushState push current state onto stack and set up new one + * + * SYNOPSIS + * + * static VOID PushState () + * + * DESCRIPTION + * + * Pushes the current state on the state stack, and initializes + * a new state. The only parameter inherited from the previous + * state is the function nesting level. This action can be + * inhibited if desired, via the "r" flag. + * + * The state stack is a linked list of states, with the new + * state added at the head. This allows the stack to grow + * to the limits of memory if necessary. + * + */ + +static void PushState () +{ + REGISTER struct state *new; + + if (!init_done) + { + init_dbug_state(); + init_done=TRUE; + } + (void) code_state(); /* Alloc memory */ + new = (struct state *) DbugMalloc (sizeof (struct state)); + new -> flags = 0; + new -> delay = 0; + new -> maxdepth = MAXDEPTH; + new -> sub_level=0; + new -> out_file = stderr; + new -> prof_file = (FILE*) 0; + new -> functions = NULL; + new -> p_functions = NULL; + new -> keywords = NULL; + new -> processes = NULL; + new -> next_state = stack; + stack=new; +} + + +/* + * FUNCTION + * + * DoTrace check to see if tracing is current enabled + * + * SYNOPSIS + * + * static BOOLEAN DoTrace (stack) + * + * DESCRIPTION + * + * Checks to see if tracing is enabled based on whether the + * user has specified tracing, the maximum trace depth has + * not yet been reached, the current function is selected, + * and the current process is selected. Returns TRUE if + * tracing is enabled, FALSE otherwise. + * + */ + +static BOOLEAN DoTrace (CODE_STATE *state) +{ + reg2 BOOLEAN trace=FALSE; + + if (TRACING && + state->level <= stack -> maxdepth && + InList (stack -> functions, state->func) && + InList (stack -> processes, _db_process_)) + trace = TRUE; + return (trace); +} + + +/* + * FUNCTION + * + * DoProfile check to see if profiling is current enabled + * + * SYNOPSIS + * + * static BOOLEAN DoProfile () + * + * DESCRIPTION + * + * Checks to see if profiling is enabled based on whether the + * user has specified profiling, the maximum trace depth has + * not yet been reached, the current function is selected, + * and the current process is selected. Returns TRUE if + * profiling is enabled, FALSE otherwise. + * + */ + +#ifndef THREAD +static BOOLEAN DoProfile () +{ + REGISTER BOOLEAN profile; + CODE_STATE *state; + state=code_state(); + + profile = FALSE; + if (PROFILING && + state->level <= stack -> maxdepth && + InList (stack -> p_functions, state->func) && + InList (stack -> processes, _db_process_)) + profile = TRUE; + return (profile); +} +#endif + + +/* + * FUNCTION + * + * _db_keyword_ test keyword for member of keyword list + * + * SYNOPSIS + * + * BOOLEAN _db_keyword_ (keyword) + * char *keyword; + * + * DESCRIPTION + * + * Test a keyword to determine if it is in the currently active + * keyword list. As with the function list, a keyword is accepted + * if the list is null, otherwise it must match one of the list + * members. When debugging is not on, no keywords are accepted. + * After the maximum trace level is exceeded, no keywords are + * accepted (this behavior subject to change). Additionally, + * the current function and process must be accepted based on + * their respective lists. + * + * Returns TRUE if keyword accepted, FALSE otherwise. + * + */ + +BOOLEAN _db_keyword_ (keyword) +const char *keyword; +{ + REGISTER BOOLEAN accept; + CODE_STATE *state; + + if (!init_done) + _db_push_ (""); + state=code_state(); + accept = FALSE; + if (DEBUGGING && + state->level <= stack -> maxdepth && + InList (stack -> functions, state->func) && + InList (stack -> keywords, keyword) && + InList (stack -> processes, _db_process_)) + accept = TRUE; + return (accept); +} + +/* + * FUNCTION + * + * Indent indent a line to the given indentation level + * + * SYNOPSIS + * + * static VOID Indent (indent) + * int indent; + * + * DESCRIPTION + * + * Indent a line to the given level. Note that this is + * a simple minded but portable implementation. + * There are better ways. + * + * Also, the indent must be scaled by the compile time option + * of character positions per nesting level. + * + */ + +static void Indent (indent) +int indent; +{ + REGISTER int count; + + indent= max(indent-1-stack->sub_level,0)*INDENT; + for (count = 0; count < indent ; count++) + { + if ((count % INDENT) == 0) + fputc('|',_db_fp_); + else + fputc(' ',_db_fp_); + } +} + + +/* + * FUNCTION + * + * FreeList free all memory associated with a linked list + * + * SYNOPSIS + * + * static VOID FreeList (linkp) + * struct link *linkp; + * + * DESCRIPTION + * + * Given pointer to the head of a linked list, frees all + * memory held by the list and the members of the list. + * + */ + +static void FreeList (linkp) +struct link *linkp; +{ + REGISTER struct link *old; + + while (linkp != NULL) { + old = linkp; + linkp = linkp -> next_link; + if (old -> str != NULL) { + free (old -> str); + } + free ((char *) old); + } +} + + +/* + * FUNCTION + * + * StrDup make a duplicate of a string in new memory + * + * SYNOPSIS + * + * static char *StrDup (my_string) + * char *string; + * + * DESCRIPTION + * + * Given pointer to a string, allocates sufficient memory to make + * a duplicate copy, and copies the string to the newly allocated + * memory. Failure to allocated sufficient memory is immediately + * fatal. + * + */ + + +static char *StrDup (str) +const char *str; +{ + reg1 char *new; + new = DbugMalloc ((int) strlen (str) + 1); + (void) strcpy (new, str); + return (new); +} + + +/* + * FUNCTION + * + * DoPrefix print debugger line prefix prior to indentation + * + * SYNOPSIS + * + * static VOID DoPrefix (_line_) + * int _line_; + * + * DESCRIPTION + * + * Print prefix common to all debugger output lines, prior to + * doing indentation if necessary. Print such information as + * current process name, current source file name and line number, + * and current function nesting depth. + * + */ + +static void DoPrefix (_line_) +uint _line_; +{ + CODE_STATE *state; + state=code_state(); + + state->lineno++; + if (stack -> flags & PID_ON) { +#ifdef THREAD + (void) fprintf (_db_fp_, "%-7s: ", my_thread_name()); +#else + (void) fprintf (_db_fp_, "%5d: ", getpid ()); +#endif + } + if (stack -> flags & NUMBER_ON) { + (void) fprintf (_db_fp_, "%5d: ", state->lineno); + } + if (stack -> flags & PROCESS_ON) { + (void) fprintf (_db_fp_, "%s: ", _db_process_); + } + if (stack -> flags & FILE_ON) { + (void) fprintf (_db_fp_, "%14s: ", BaseName(state->file)); + } + if (stack -> flags & LINE_ON) { + (void) fprintf (_db_fp_, "%5d: ", _line_); + } + if (stack -> flags & DEPTH_ON) { + (void) fprintf (_db_fp_, "%4d: ", state->level); + } +} + + +/* + * FUNCTION + * + * DBUGOpenFile open new output stream for debugger output + * + * SYNOPSIS + * + * static VOID DBUGOpenFile (name) + * char *name; + * + * DESCRIPTION + * + * Given name of a new file (or "-" for stdout) opens the file + * and sets the output stream to the new file. + * + */ + +static void DBUGOpenFile (const char *name,int append) +{ + REGISTER FILE *fp; + REGISTER BOOLEAN newfile; + + if (name != NULL) + { + strmov(stack->name,name); + if (strcmp (name, "-") == 0) + { + _db_fp_ = stdout; + stack -> out_file = _db_fp_; + stack -> flags |= FLUSH_ON_WRITE; + } + else + { + if (!Writable(name)) + { + (void) fprintf (stderr, ERR_OPEN, _db_process_, name); + perror (""); + fflush(stderr); + } + else + { + newfile= !EXISTS (name); + if (!(fp = fopen(name, append ? "a+" : "w"))) + { + (void) fprintf (stderr, ERR_OPEN, _db_process_, name); + perror (""); + fflush(stderr); + } + else + { + _db_fp_ = fp; + stack -> out_file = fp; + if (newfile) { + ChangeOwner (name); + } + } + } + } + } +} + + +/* + * FUNCTION + * + * OpenProfile open new output stream for profiler output + * + * SYNOPSIS + * + * static FILE *OpenProfile (name) + * char *name; + * + * DESCRIPTION + * + * Given name of a new file, opens the file + * and sets the profiler output stream to the new file. + * + * It is currently unclear whether the prefered behavior is + * to truncate any existing file, or simply append to it. + * The latter behavior would be desirable for collecting + * accumulated runtime history over a number of separate + * runs. It might take some changes to the analyzer program + * though, and the notes that Binayak sent with the profiling + * diffs indicated that append was the normal mode, but this + * does not appear to agree with the actual code. I haven't + * investigated at this time [fnf; 24-Jul-87]. + */ + +#ifndef THREAD +static FILE *OpenProfile (const char *name) +{ + REGISTER FILE *fp; + REGISTER BOOLEAN newfile; + + fp=0; + if (!Writable (name)) + { + (void) fprintf (_db_fp_, ERR_OPEN, _db_process_, name); + perror (""); + dbug_flush(0); + (void) Delay (stack -> delay); + } + else + { + newfile= !EXISTS (name); + if (!(fp = fopen (name, "w"))) + { + (void) fprintf (_db_fp_, ERR_OPEN, _db_process_, name); + perror (""); + dbug_flush(0); + } + else + { + _db_pfp_ = fp; + stack -> prof_file = fp; + if (newfile) + { + ChangeOwner (name); + } + } + } + return fp; +} +#endif + +/* + * FUNCTION + * + * CloseFile close the debug output stream + * + * SYNOPSIS + * + * static VOID CloseFile (fp) + * FILE *fp; + * + * DESCRIPTION + * + * Closes the debug output stream unless it is standard output + * or standard error. + * + */ + +static void CloseFile (fp) +FILE *fp; +{ + if (fp != stderr && fp != stdout) { + if (fclose (fp) == EOF) { + pthread_mutex_lock(&THR_LOCK_dbug); + (void) fprintf (_db_fp_, ERR_CLOSE, _db_process_); + perror (""); + dbug_flush(0); + } + } +} + + +/* + * FUNCTION + * + * DbugExit print error message and exit + * + * SYNOPSIS + * + * static VOID DbugExit (why) + * char *why; + * + * DESCRIPTION + * + * Prints error message using current process name, the reason for + * aborting (typically out of memory), and exits with status 1. + * This should probably be changed to use a status code + * defined in the user's debugger include file. + * + */ + +static void DbugExit (const char *why) +{ + (void) fprintf (stderr, ERR_ABORT, _db_process_, why); + (void) fflush (stderr); + exit (1); +} + + +/* + * FUNCTION + * + * DbugMalloc allocate memory for debugger runtime support + * + * SYNOPSIS + * + * static long *DbugMalloc (size) + * int size; + * + * DESCRIPTION + * + * Allocate more memory for debugger runtime support functions. + * Failure to to allocate the requested number of bytes is + * immediately fatal to the current process. This may be + * rather unfriendly behavior. It might be better to simply + * print a warning message, freeze the current debugger state, + * and continue execution. + * + */ + +static char *DbugMalloc (size) +int size; +{ + register char *new; + + if (!(new = malloc ((unsigned int) size))) + DbugExit ("out of memory"); + return (new); +} + + +/* + * As strtok but two separators in a row are changed to one + * separator (to allow directory-paths in dos). + */ + +static char *static_strtok (s1, separator) +char *s1; +pchar separator; +{ + static char *end = NULL; + reg1 char *rtnval,*cpy; + + rtnval = NULL; + if (s1 != NULL) + end = s1; + if (end != NULL && *end != EOS) + { + rtnval=cpy=end; + do + { + if ((*cpy++ = *end++) == separator) + { + if (*end != separator) + { + cpy--; /* Point at separator */ + break; + } + end++; /* Two separators in a row, skipp one */ + } + } while (*end != EOS); + *cpy=EOS; /* Replace last separator */ + } + return (rtnval); +} + + +/* + * FUNCTION + * + * BaseName strip leading pathname components from name + * + * SYNOPSIS + * + * static char *BaseName (pathname) + * char *pathname; + * + * DESCRIPTION + * + * Given pointer to a complete pathname, locates the base file + * name at the end of the pathname and returns a pointer to + * it. + * + */ + +static char *BaseName (const char *pathname) +{ + register const char *base; + + base = strrchr (pathname, FN_LIBCHAR); + if (base++ == NullS) + base = pathname; + return ((char*) base); +} + + +/* + * FUNCTION + * + * Writable test to see if a pathname is writable/creatable + * + * SYNOPSIS + * + * static BOOLEAN Writable (pathname) + * char *pathname; + * + * DESCRIPTION + * + * Because the debugger might be linked in with a program that + * runs with the set-uid-bit (suid) set, we have to be careful + * about opening a user named file for debug output. This consists + * of checking the file for write access with the real user id, + * or checking the directory where the file will be created. + * + * Returns TRUE if the user would normally be allowed write or + * create access to the named file. Returns FALSE otherwise. + * + */ + + +#ifndef Writable + +static BOOLEAN Writable (pathname) +char *pathname; +{ + REGISTER BOOLEAN granted; + REGISTER char *lastslash; + + granted = FALSE; + if (EXISTS (pathname)) { + if (WRITABLE (pathname)) { + granted = TRUE; + } + } else { + lastslash = strrchr (pathname, '/'); + if (lastslash != NULL) { + *lastslash = EOS; + } else { + pathname = "."; + } + if (WRITABLE (pathname)) { + granted = TRUE; + } + if (lastslash != NULL) { + *lastslash = '/'; + } + } + return (granted); +} +#endif + + +/* + * FUNCTION + * + * ChangeOwner change owner to real user for suid programs + * + * SYNOPSIS + * + * static VOID ChangeOwner (pathname) + * + * DESCRIPTION + * + * For unix systems, change the owner of the newly created debug + * file to the real owner. This is strictly for the benefit of + * programs that are running with the set-user-id bit set. + * + * Note that at this point, the fact that pathname represents + * a newly created file has already been established. If the + * program that the debugger is linked to is not running with + * the suid bit set, then this operation is redundant (but + * harmless). + * + */ + +#ifndef ChangeOwner +static void ChangeOwner (pathname) +char *pathname; +{ + if (chown (pathname, getuid (), getgid ()) == -1) + { + (void) fprintf (stderr, ERR_CHOWN, _db_process_, pathname); + perror (""); + (void) fflush (stderr); + } +} +#endif + + +/* + * FUNCTION + * + * _db_setjmp_ save debugger environment + * + * SYNOPSIS + * + * VOID _db_setjmp_ () + * + * DESCRIPTION + * + * Invoked as part of the user's DBUG_SETJMP macro to save + * the debugger environment in parallel with saving the user's + * environment. + * + */ + +#ifdef HAVE_LONGJMP + +EXPORT void _db_setjmp_ () +{ + CODE_STATE *state; + state=code_state(); + + state->jmplevel = state->level; + state->jmpfunc = state->func; + state->jmpfile = state->file; +} + +/* + * FUNCTION + * + * _db_longjmp_ restore previously saved debugger environment + * + * SYNOPSIS + * + * VOID _db_longjmp_ () + * + * DESCRIPTION + * + * Invoked as part of the user's DBUG_LONGJMP macro to restore + * the debugger environment in parallel with restoring the user's + * previously saved environment. + * + */ + +EXPORT void _db_longjmp_ () +{ + CODE_STATE *state; + state=code_state(); + + state->level = state->jmplevel; + if (state->jmpfunc) { + state->func = state->jmpfunc; + } + if (state->jmpfile) { + state->file = state->jmpfile; + } +} +#endif + +/* + * FUNCTION + * + * DelayArg convert D flag argument to appropriate value + * + * SYNOPSIS + * + * static int DelayArg (value) + * int value; + * + * DESCRIPTION + * + * Converts delay argument, given in tenths of a second, to the + * appropriate numerical argument used by the system to delay + * that that many tenths of a second. For example, on the + * amiga, there is a system call "Delay()" which takes an + * argument in ticks (50 per second). On unix, the sleep + * command takes seconds. Thus a value of "10", for one + * second of delay, gets converted to 50 on the amiga, and 1 + * on unix. Other systems will need to use a timing loop. + * + */ + +#ifdef AMIGA +#define HZ (50) /* Probably in some header somewhere */ +#endif + +static int DelayArg (value) +int value; +{ + uint delayarg = 0; + +#if (unix || xenix) + delayarg = value / 10; /* Delay is in seconds for sleep () */ +#endif +#ifdef AMIGA + delayarg = (HZ * value) / 10; /* Delay in ticks for Delay () */ +#endif + return (delayarg); +} + + +/* + * A dummy delay stub for systems that do not support delays. + * With a little work, this can be turned into a timing loop. + */ + +#if ! defined(Delay) && ! defined(AMIGA) +static int Delay (ticks) +int ticks; +{ + return ticks; +} +#endif + + +/* + * FUNCTION + * + * perror perror simulation for systems that don't have it + * + * SYNOPSIS + * + * static VOID perror (s) + * char *s; + * + * DESCRIPTION + * + * Perror produces a message on the standard error stream which + * provides more information about the library or system error + * just encountered. The argument string s is printed, followed + * by a ':', a blank, and then a message and a newline. + * + * An undocumented feature of the unix perror is that if the string + * 's' is a null string (NOT a NULL pointer!), then the ':' and + * blank are not printed. + * + * This version just complains about an "unknown system error". + * + */ + +#ifndef HAVE_PERROR +static void perror (s) +char *s; +{ + if (s && *s != EOS) { + (void) fprintf (stderr, "%s: ", s); + } + (void) fprintf (stderr, "<unknown system error>\n"); +} +#endif /* HAVE_PERROR */ + + + /* flush dbug-stream, free mutex lock & wait delay */ + /* This is because some systems (MSDOS!!) dosn't flush fileheader */ + /* and dbug-file isn't readable after a system crash !! */ + +static void dbug_flush(CODE_STATE *state) +{ +#ifndef THREAD + if (stack->flags & FLUSH_ON_WRITE) +#endif + { +#if defined(MSDOS) || defined(__WIN32__) + if (_db_fp_ != stdout && _db_fp_ != stderr) + { + if (!(freopen(stack->name,"a",_db_fp_))) + { + (void) fprintf(stderr, ERR_OPEN, _db_process_); + fflush(stderr); + _db_fp_ = stdout; + stack -> out_file = _db_fp_; + stack -> flags|=FLUSH_ON_WRITE; + } + } + else +#endif + { + (void) fflush (_db_fp_); + if (stack->delay) + (void) Delay (stack->delay); + } + } + if (!state || !state->locked) + pthread_mutex_unlock(&THR_LOCK_dbug); +} /* dbug_flush */ + + +void _db_lock_file() +{ + CODE_STATE *state; + state=code_state(); + pthread_mutex_lock(&THR_LOCK_dbug); + state->locked=1; +} + +void _db_unlock_file() +{ + CODE_STATE *state; + state=code_state(); + state->locked=0; + pthread_mutex_unlock(&THR_LOCK_dbug); +} + +/* + * Here we need the definitions of the clock routine. Add your + * own for whatever system that you have. + */ + +#ifdef HAVE_GETRUSAGE + +#include <sys/param.h> +#include <sys/resource.h> + +/* extern int getrusage(int, struct rusage *); */ + +/* + * Returns the user time in milliseconds used by this process so + * far. + */ + +static unsigned long Clock () +{ + struct rusage ru; + + (void) getrusage (RUSAGE_SELF, &ru); + return ((ru.ru_utime.tv_sec * 1000) + (ru.ru_utime.tv_usec / 1000)); +} + +#else +#if defined(MSDOS) || defined(__WIN32__) + +static ulong Clock() +{ + return clock()*(1000/CLOCKS_PER_SEC); +} +#else +#ifdef amiga + +struct DateStamp { /* Yes, this is a hack, but doing it right */ + long ds_Days; /* is incredibly ugly without splitting this */ + long ds_Minute; /* off into a separate file */ + long ds_Tick; +}; + +static int first_clock = TRUE; +static struct DateStamp begin; +static struct DateStamp elapsed; + +static unsigned long Clock () +{ + register struct DateStamp *now; + register unsigned long millisec = 0; + extern VOID *AllocMem (); + + now = (struct DateStamp *) AllocMem ((long) sizeof (struct DateStamp), 0L); + if (now != NULL) { + if (first_clock == TRUE) { + first_clock = FALSE; + (void) DateStamp (now); + begin = *now; + } + (void) DateStamp (now); + millisec = 24 * 3600 * (1000 / HZ) * (now -> ds_Days - begin.ds_Days); + millisec += 60 * (1000 / HZ) * (now -> ds_Minute - begin.ds_Minute); + millisec += (1000 / HZ) * (now -> ds_Tick - begin.ds_Tick); + (void) FreeMem (now, (long) sizeof (struct DateStamp)); + } + return (millisec); +} + +#else + +#ifndef THREAD +static unsigned long Clock () +{ + return (0); +} +#endif +#endif /* amiga */ +#endif /* MSDOS || __WIN32__ */ +#endif /* RUSAGE */ + + +#ifdef NO_VARARGS + +/* + * Fake vfprintf for systems that don't support it. If this + * doesn't work, you are probably SOL... + */ + +static int vfprintf (stream, format, ap) +FILE *stream; +char *format; +va_list ap; +{ + int rtnval; + ARGS_DCL; + + ARG0 = va_arg (ap, ARGS_TYPE); + ARG1 = va_arg (ap, ARGS_TYPE); + ARG2 = va_arg (ap, ARGS_TYPE); + ARG3 = va_arg (ap, ARGS_TYPE); + ARG4 = va_arg (ap, ARGS_TYPE); + ARG5 = va_arg (ap, ARGS_TYPE); + ARG6 = va_arg (ap, ARGS_TYPE); + ARG7 = va_arg (ap, ARGS_TYPE); + ARG8 = va_arg (ap, ARGS_TYPE); + ARG9 = va_arg (ap, ARGS_TYPE); + rtnval = fprintf (stream, format, ARGS_LIST); + return (rtnval); +} + +#endif /* NO_VARARGS */ diff --git a/ext/mysql/libmysql/dbug.h b/ext/mysql/libmysql/dbug.h new file mode 100644 index 0000000000..3331f9032d --- /dev/null +++ b/ext/mysql/libmysql/dbug.h @@ -0,0 +1,75 @@ +#ifndef _dbug_h +#define _dbug_h +#ifdef __cplusplus +extern "C" { +#endif +#if !defined(DBUG_OFF) && !defined(_lint) +extern int _db_on_,_no_db_; +extern FILE *_db_fp_; +extern char *_db_process_; +extern int _db_keyword_(const char *keyword); +extern void _db_setjmp_(void); +extern void _db_longjmp_(void); +extern void _db_push_(const char *control); +extern void _db_pop_(void); +extern void _db_enter_(const char *_func_,const char *_file_,uint _line_, + const char **_sfunc_,const char **_sfile_, + uint *_slevel_, char ***); +extern void _db_return_(uint _line_,const char **_sfunc_,const char **_sfile_, + uint *_slevel_); +extern void _db_pargs_(uint _line_,const char *keyword); +extern void _db_doprnt_ _VARARGS((const char *format,...)); +extern void _db_dump_(uint _line_,const char *keyword,const char *memory, + uint length); +extern void _db_lock_file(); +extern void _db_unlock_file(); + +#define DBUG_ENTER(a) const char *_db_func_, *_db_file_; uint _db_level_; \ + char **_db_framep_; \ + _db_enter_ (a,__FILE__,__LINE__,&_db_func_,&_db_file_,&_db_level_, \ + &_db_framep_) +#define DBUG_LEAVE \ + (_db_return_ (__LINE__, &_db_func_, &_db_file_, &_db_level_)) +#define DBUG_RETURN(a1) {DBUG_LEAVE; return(a1);} +#define DBUG_VOID_RETURN {DBUG_LEAVE; return;} +#define DBUG_EXECUTE(keyword,a1) \ + {if (_db_on_) {if (_db_keyword_ (keyword)) { a1 }}} +#define DBUG_PRINT(keyword,arglist) \ + {if (_db_on_) {_db_pargs_(__LINE__,keyword); _db_doprnt_ arglist;}} +#define DBUG_PUSH(a1) _db_push_ (a1) +#define DBUG_POP() _db_pop_ () +#define DBUG_PROCESS(a1) (_db_process_ = a1) +#define DBUG_FILE (_db_fp_) +#define DBUG_SETJMP(a1) (_db_setjmp_ (), setjmp (a1)) +#define DBUG_LONGJMP(a1,a2) (_db_longjmp_ (), longjmp (a1, a2)) +#define DBUG_DUMP(keyword,a1,a2)\ + {if (_db_on_) {_db_dump_(__LINE__,keyword,a1,a2);}} +#define DBUG_IN_USE (_db_fp_ && _db_fp_ != stderr) +#define DEBUGGER_OFF _no_db_=1;_db_on_=0; +#define DEBUGGER_ON _no_db_=0 +#define DBUG_LOCK_FILE { _db_lock_file(); } +#define DBUG_UNLOCK_FILE { _db_unlock_file(); } +#else /* No debugger */ + +#define DBUG_ENTER(a1) +#define DBUG_RETURN(a1) return(a1) +#define DBUG_VOID_RETURN return +#define DBUG_EXECUTE(keyword,a1) {} +#define DBUG_PRINT(keyword,arglist) {} +#define DBUG_PUSH(a1) {} +#define DBUG_POP() {} +#define DBUG_PROCESS(a1) {} +#define DBUG_FILE (stderr) +#define DBUG_SETJMP setjmp +#define DBUG_LONGJMP longjmp +#define DBUG_DUMP(keyword,a1,a2) {} +#define DBUG_IN_USE 0 +#define DEBUGGER_OFF +#define DEBUGGER_ON +#define DBUG_LOCK_FILE +#define DBUG_UNLOCK_FILE +#endif +#ifdef __cplusplus +} +#endif +#endif diff --git a/ext/mysql/libmysql/default.c b/ext/mysql/libmysql/default.c new file mode 100644 index 0000000000..b1e33f3e59 --- /dev/null +++ b/ext/mysql/libmysql/default.c @@ -0,0 +1,345 @@ +/* Copyright Abandoned 1998 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/**************************************************************************** +** 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. +** --print-defaults ; Print the modified command line and exit +** --defaults-file=full-path-to-default-file ; Only this file will be read. +****************************************************************************/ + +#undef SAFEMALLOC /* safe_malloc is not yet initailized */ + +#include "mysys_priv.h" +#include "m_string.h" +#include "m_ctype.h" + +/* Which directories are searched for options (and in which order) */ + +const char *default_directories[]= { +#ifdef __WIN32__ +"C:/", +#else +"/etc/", +#endif +#ifdef DATADIR +DATADIR, +#endif +#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, *extra_default_file; + TYPELIB group; + my_bool print_defaults=0; + MEM_ROOT alloc; + char *ptr,**res; + DBUG_ENTER("load_defaults"); + + init_alloc_root(&alloc,128); + 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; + memcpy(ptr,&alloc,sizeof(alloc)); /* Save alloc root for free */ + DBUG_VOID_RETURN; + } + + /* Check if we want to force the use a specific default file */ + extra_default_file=0; + if (*argc >= 2 && is_prefix(argv[0][1],"--defaults-file=")) + extra_default_file=strchr(argv[0][1],'=')+1; + + group.count=0; + group.name= (char*) "defaults"; + group.type_names=(char**) groups; + for (; *groups ; groups++) + group.count++; + + if (init_dynamic_array(&args, sizeof(char*),*argc, 32)) + goto err; + if (extra_default_file) + { + if (search_default_file(&args, &alloc, "", extra_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 + for (dirs=default_directories ; *dirs; dirs++) + { + if (search_default_file(&args, &alloc, *dirs, conf_file, default_ext, + &group)) + 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*)); + if (extra_default_file) + { + --*argc; /* Skipp --defaults-file */ + ++*argv; + } + + /* Check if we wan't to see the new argument list */ + if (*argc >= 2 && !strcmp(argv[0][1],"--print-defaults")) + { + 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; + memcpy(ptr,&alloc,sizeof(alloc)); /* Save alloc root for free */ + delete_dynamic(&args); + if (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((char*) &ptr,(char *) argv - sizeof(ptr),sizeof(ptr)); + free_root(&ptr); +} + + +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[257],*ptr,*end,*value,*tmp; + FILE *fp; + uint line=0; + my_bool read_values=0,found_group=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); + } + 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 (*ptr == '#' || *ptr == ';' || !*ptr) + continue; + 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--) ; + 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; + 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) +{ + bool have_ext=fn_ext(conf_file)[0] != 0; + 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 + for (dirs=default_directories ; *dirs; dirs++) + { + strmov(name,*dirs); + 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 #"); +}; diff --git a/ext/mysql/libmysql/errmsg.h b/ext/mysql/libmysql/errmsg.h new file mode 100644 index 0000000000..d88653929b --- /dev/null +++ b/ext/mysql/libmysql/errmsg.h @@ -0,0 +1,33 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* Error messages for mysql clients */ +/* error messages for the demon is in share/language/errmsg.sys */ + +void init_client_errs(void); +extern const char *client_errors[]; /* Error messages */ + +#define CR_MIN_ERROR 2000 /* For easier client code */ +#define CR_MAX_ERROR 2999 +#define ER(X) client_errors[(X)-CR_MIN_ERROR] +#define CLIENT_ERRMAP 2 /* Errormap used by my_error() */ + +#define CR_UNKNOWN_ERROR 2000 +#define CR_SOCKET_CREATE_ERROR 2001 +#define CR_CONNECTION_ERROR 2002 +#define CR_CONN_HOST_ERROR 2003 +#define CR_IPSOCK_ERROR 2004 +#define CR_UNKNOWN_HOST 2005 +#define CR_SERVER_GONE_ERROR 2006 +#define CR_VERSION_ERROR 2007 +#define CR_OUT_OF_MEMORY 2008 +#define CR_WRONG_HOST_INFO 2009 +#define CR_LOCALHOST_CONNECTION 2010 +#define CR_TCP_CONNECTION 2011 +#define CR_SERVER_HANDSHAKE_ERR 2012 +#define CR_SERVER_LOST 2013 +#define CR_COMMANDS_OUT_OF_SYNC 2014 +#define CR_NAMEDPIPE_CONNECTION 2015 +#define CR_NAMEDPIPEWAIT_ERROR 2016 +#define CR_NAMEDPIPEOPEN_ERROR 2017 +#define CR_NAMEDPIPESETSTATE_ERROR 2018 diff --git a/ext/mysql/libmysql/errors.c b/ext/mysql/libmysql/errors.c new file mode 100644 index 0000000000..358d092844 --- /dev/null +++ b/ext/mysql/libmysql/errors.c @@ -0,0 +1,68 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +#include "mysys_priv.h" +#include "mysys_err.h" + +#ifndef SHARED_LIBRARY + +const char * NEAR globerrs[GLOBERRS]= +{ + "File '%s' not found (Errcode: %d)", + "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", + "%d files and %d streams is left open\n", + "Disk is full writing '%s'. Waiting for someone to free space...", + "Can't create directory '%s' (Errcode: %d)", +}; + +void init_glob_errs(void) +{ + errmsg[GLOB] = & globerrs[0]; +} /* init_glob_errs */ + +#else + +void init_glob_errs() +{ + 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)"; +} +#endif diff --git a/ext/mysql/libmysql/global.h b/ext/mysql/libmysql/global.h new file mode 100644 index 0000000000..87e14c04e0 --- /dev/null +++ b/ext/mysql/libmysql/global.h @@ -0,0 +1,786 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* This is the main include file that should included 'first' in every + C file. */ + +#ifndef _global_h +#define _global_h + +#if defined(__WIN32__) || defined(WIN32) +#include <config-win32.h> +#else +#include <my_config.h> +#endif +#if defined(__cplusplus) && defined(inline) +#undef inline /* fix configure problem */ +#endif + +/* The client defines this to avoid all thread code */ +#if defined(UNDEF_THREADS_HACK) && !defined(THREAD_SAFE_CLIENT) +#undef THREAD +#undef HAVE_mit_thread +#undef HAVE_LINUXTHREADS +#undef HAVE_UNIXWARE7_THREADS +#endif + +#ifdef HAVE_THREADS_WITHOUT_SOCKETS +/* MIT pthreads does not work with unix sockets */ +#undef HAVE_SYS_UN_H +#endif + +#define __EXTENSIONS__ 1 /* We want some extension */ +#ifndef __STDC_EXT__ +#define __STDC_EXT__ 1 /* To get large file support on hpux */ +#endif +/* #define _GNU_SOURCE 1 */ /* Get define for strtok_r on Alpha-linux */ + +#if defined(THREAD) && !defined(__WIN32__) +#define _POSIX_PTHREAD_SEMANTICS /* We want posix threads */ +/* was #if defined(HAVE_LINUXTHREADS) || defined(HAVE_DEC_THREADS) || defined(HPUX) */ +#if !defined(SCO) +#define _REENTRANT 1 /* Some thread libraries require this */ +#endif +#if !defined(_THREAD_SAFE) && !defined(_AIX) +#define _THREAD_SAFE /* Required for OSF1 */ +#endif +#ifndef HAVE_mit_thread +#ifdef HAVE_UNIXWARE7_THREADS +#include <thread.h> +#else +#include <pthread.h> /* AIX must have this included first */ +#endif /* HAVE_UNIXWARE7_THREADS */ +#endif /* HAVE_mit_thread */ +#if !defined(SCO) && !defined(_REENTRANT) +#define _REENTRANT 1 /* Threads requires reentrant code */ +#endif +#endif /* THREAD */ + +/* Go around some bugs in different OS and compilers */ +#ifdef _AIX /* By soren@t.dk */ +#define _H_STRINGS +#define _SYS_STREAM_H +#define _AIX32_CURSES +#endif + +#ifdef HAVE_BROKEN_SNPRINTF /* HPUX 10.20 don't have this defined */ +#undef HAVE_SNPRINTF +#endif +#ifdef HAVE_BROKEN_PREAD /* These doesn't work on HPUX 11.x */ +#undef HAVE_PREAD +#undef HAVE_PWRITE +#endif + +/* Fix a bug in gcc 2.8.0 on IRIX 6.2 */ +#if SIZEOF_LONG == 4 && defined(__LONG_MAX__) +#undef __LONG_MAX__ /* Is a longlong value in gcc 2.8.0 ??? */ +#define __LONG_MAX__ 2147483647 +#endif + +#if defined(_lint) && !defined(lint) +#define lint +#endif +#if SIZEOF_LONG_LONG > 4 && !defined(_LONG_LONG) +#define _LONG_LONG 1 /* For AIX string library */ +#endif + +#ifndef stdin +#include <stdio.h> +#endif +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#ifdef HAVE_STDDEF_H +#include <stddef.h> +#endif + +#include <math.h> +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif +#ifdef HAVE_FLOAT_H +#include <float.h> +#endif + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif +#ifdef HAVE_SYS_TIMEB_H +#include <sys/timeb.h> /* Avoid warnings on SCO */ +#endif +#if TIME_WITH_SYS_TIME +# include <sys/time.h> +# include <time.h> +#else +# if HAVE_SYS_TIME_H +# include <sys/time.h> +# else +# include <time.h> +# endif +#endif /* TIME_WITH_SYS_TIME */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#if defined(__cplusplus) && defined(NO_CPLUSPLUS_ALLOCA) +#undef HAVE_ALLOCA +#undef HAVE_ALLOCA_H +#endif +#ifdef HAVE_ALLOCA_H +#include <alloca.h> +#endif + +/* Go around some bugs in different OS and compilers */ +#if defined(_HPUX_SOURCE) && defined(HAVE_SYS_STREAM_H) +#include <sys/stream.h> /* HPUX 10.20 defines ulong here. UGLY !!! */ +#define HAVE_ULONG +#endif +#ifdef DONT_USE_FINITE /* HPUX 11.x has is_finite() */ +#undef HAVE_FINITE +#endif + +/* We can not live without these */ + +#define USE_MYFUNC 1 /* Must use syscall indirection */ +#define MASTER 1 /* Compile without unireg */ +#define ENGLISH 1 /* Messages in English */ +#define POSIX_MISTAKE 1 /* regexp: Fix stupid spec error */ +#define USE_REGEX 1 /* We want the use the regex library */ +/* Do not define for ultra sparcs */ +#define USE_BMOVE512 1 /* Use this unless the system bmove is faster */ + +/* Paranoid settings. Define I_AM_PARANOID if you are paranoid */ +#ifdef I_AM_PARANOID +#define DONT_ALLOW_USER_CHANGE 1 +#define DONT_USE_MYSQL_PWD 1 +#endif + +/* #define USE_some_charset 1 was deprecated by changes to configure */ +/* my_ctype my_to_upper, my_to_lower, my_sort_order gain theit right value */ +/* automagically during configuration */ + +/* Does the system remember a signal handler after a signal ? */ +#ifndef HAVE_BSD_SIGNALS +#define DONT_REMEMBER_SIGNAL +#endif + +/* Define void to stop lint from generating "null effekt" comments */ +#ifdef _lint +int __void__; +#define VOID(X) (__void__ = (int) (X)) +#else +#undef VOID +#define VOID(X) (X) +#endif + +#if defined(_lint) || defined(FORCE_INIT_OF_VARS) +#define LINT_INIT(var) var=0 /* No uninitialize-warning */ +#else +#define LINT_INIT(var) +#endif + +/* Define som useful general macros */ +#if defined(__cplusplus) && defined(__GNUC__) +#define max(a, b) ((a) >? (b)) +#define min(a, b) ((a) <? (b)) +#elif !defined(max) +#define max(a, b) ((a) > (b) ? (a) : (b)) +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + +#if defined(__EMX__) || !defined(HAVE_UINT) +typedef unsigned int uint; +typedef unsigned short ushort; +#endif + +#define sgn(a) (((a) < 0) ? -1 : ((a) > 0) ? 1 : 0) +#define swap(t,a,b) { register t dummy; dummy = a; a = b; b = dummy; } +#define test(a) ((a) ? 1 : 0) +#define set_if_bigger(a,b) { if ((a) < (b)) (a)=(b); } +#define set_if_smaller(a,b) { if ((a) > (b)) (a)=(b); } +#define test_all_bits(a,b) (((a) & (b)) == (b)) +#define array_elements(A) ((uint) (sizeof(A)/sizeof(A[0]))) +#ifndef HAVE_RINT +#define rint(A) floor((A)+0.5) +#endif + +/* Define som general constants */ +#ifndef TRUE +#define TRUE (1) /* Logical true */ +#define FALSE (0) /* Logical false */ +#endif + +#if defined(__GNUC__) +#define function_volatile volatile +#define my_reinterpret_cast(A) reinterpret_cast<A> +#define my_const_cast(A) const_cast<A> +#elif !defined(my_reinterpret_cast) +#define my_reinterpret_cast(A) (A) +#define my_const_cast(A) (A) +#endif +#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8) +#define __attribute__(A) +#endif + +/* From old s-system.h */ + +/* Support macros for non ansi & other old compilers. Since such + things are no longer supported we do nothing. We keep then since + some of our code may still be needed to upgrade old customers. */ +#define _VARARGS(X) X +#define _STATIC_VARARGS(X) X +#define _PC(X) X + +#if defined(DBUG_ON) && defined(DBUG_OFF) +#undef DBUG_OFF +#endif + +#if defined(_lint) && !defined(DBUG_OFF) +#define DBUG_OFF +#endif + +#include <dbug.h> + +#define MIN_ARRAY_SIZE 0 /* Zero or One. Gcc allows zero*/ +#define ASCII_BITS_USED 8 /* Bit char used */ +#define NEAR_F /* No near function handling */ + +/* Some types that is different between systems */ + +typedef int File; /* File descriptor */ +#ifndef Socket_defined +typedef int my_socket; /* File descriptor for sockets */ +#define INVALID_SOCKET -1 +#endif +typedef RETSIGTYPE sig_handler; /* Function to handle signals */ +typedef void (*sig_return)();/* Returns type from signal */ +#if defined(__GNUC__) && !defined(_lint) +typedef char pchar; /* Mixed prototypes can take char */ +typedef char puchar; /* Mixed prototypes can take char */ +typedef char pbool; /* Mixed prototypes can take char */ +typedef short pshort; /* Mixed prototypes can take short int */ +typedef float pfloat; /* Mixed prototypes can take float */ +#else +typedef int pchar; /* Mixed prototypes can't take char */ +typedef uint puchar; /* Mixed prototypes can't take char */ +typedef int pbool; /* Mixed prototypes can't take char */ +typedef int pshort; /* Mixed prototypes can't take short int */ +typedef double pfloat; /* Mixed prototypes can't take float */ +#endif +typedef int (*qsort_cmp)(const void *,const void *); +#ifdef HAVE_mit_thread +#define qsort_t void +#undef QSORT_TYPE_IS_VOID +#define QSORT_TYPE_IS_VOID +#else +#define qsort_t RETQSORTTYPE /* Broken GCC cant handle typedef !!!! */ +#endif +#ifdef HAVE_mit_thread +typedef int size_socket; /* Type of last arg to accept */ +#else +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +typedef SOCKET_SIZE_TYPE size_socket; +#endif + +/* file create flags */ + +#ifndef O_SHARE +#define O_SHARE 0 /* Flag to my_open for shared files */ +#ifndef O_BINARY +#define O_BINARY 0 /* Flag to my_open for binary files */ +#endif +#define FILE_BINARY 0 /* Flag to my_fopen for binary streams */ +#ifdef HAVE_FCNTL +#define HAVE_FCNTL_LOCK +#define F_TO_EOF 0L /* Param to lockf() to lock rest of file */ +#endif +#endif /* O_SHARE */ +#ifndef O_TEMPORARY +#define O_TEMPORARY 0 +#endif +#ifndef O_SHORT_LIVED +#define O_SHORT_LIVED 0 +#endif + +/* #define USE_RECORD_LOCK */ + + /* Unsigned types supported by the compiler */ +#define UNSINT8 /* unsigned int8 (char) */ +#define UNSINT16 /* unsigned int16 */ +#define UNSINT32 /* unsigned int32 */ + + /* General constants */ +#define SC_MAXWIDTH 256 /* Max width of screen (for error messages) */ +#define FN_LEN 256 /* Max file name len */ +#define FN_HEADLEN 253 /* Max length of filepart of file name */ +#define FN_EXTLEN 20 /* Max length of extension (part of FN_LEN) */ +#define FN_REFLEN 512 /* Max length of full path-name */ +#define FN_EXTCHAR '.' +#define FN_HOMELIB '~' /* ~/ is used as abbrev for home dir */ +#define FN_CURLIB '.' /* ./ is used as abbrev for current dir */ +#define FN_PARENTDIR ".." /* Parentdirectory; Must be a string */ +#define FN_DEVCHAR ':' + +#ifndef FN_LIBCHAR +#define FN_LIBCHAR '/' +#define FN_ROOTDIR "/" +#define MY_NFILE 127 /* This is only used to save filenames */ +#endif + +/* #define EXT_IN_LIBNAME */ +/* #define FN_NO_CASE_SENCE */ +/* #define FN_UPPER_CASE TRUE */ + +/* Io buffer size; Must be a power of 2 and a multiple of 512. May be + smaller what the disk page size. This influences the speed of the + isam btree library. eg to big to slow. */ +#define IO_SIZE 4096 +/* How much overhead does malloc have. The code often allocates + something like 1024-MALLOC_OVERHEAD bytes */ +#ifdef SAFEMALLOC +#define MALLOC_OVERHEAD (8+24+4) +#else +#define MALLOC_OVERHEAD 8 +#endif + /* get memory in huncs */ +#define ONCE_ALLOC_INIT (uint) (4096-MALLOC_OVERHEAD) + /* Typical record cash */ +#define RECORD_CACHE_SIZE (uint) (64*1024-MALLOC_OVERHEAD) + /* Typical key cash */ +#define KEY_CACHE_SIZE (uint) (8*1024*1024-MALLOC_OVERHEAD) + + /* Some things that this system doesn't have */ + +#define ONLY_OWN_DATABASES /* We are using only databases by monty */ +#define NO_PISAM /* Not needed anymore */ +#define NO_MISAM /* Not needed anymore */ +#define NO_HASH /* Not needed anymore */ +#ifdef __WIN32__ +#define NO_DIR_LIBRARY /* Not standar dir-library */ +#define USE_MY_STAT_STRUCT /* For my_lib */ +#endif + +/* Some things that this system does have */ + +#ifndef HAVE_ITOA +#define USE_MY_ITOA /* There is no itoa */ +#endif + +/* Some defines of functions for portability */ + +#ifndef HAVE_ATOD +#define atod atof +#endif +#ifdef USE_MY_ATOF +#define atof my_atof +extern void init_my_atof(void); +extern double my_atof(const char*); +#endif +#undef remove /* Crashes MySQL on SCO 5.0.0 */ +#ifndef __WIN32__ +#define closesocket(A) close(A) +#ifndef ulonglong2double +#define ulonglong2double(A) ((double) (A)) +#define my_off_t2double(A) ((double) (A)) +#endif +#endif + +#ifndef offsetof +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#endif +#define ulong_to_double(X) ((double) (ulong) (X)) +#define SET_STACK_SIZE(X) /* Not needed on real machines */ + +#if !defined(HAVE_mit_thread) && !defined(HAVE_STRTOK_R) +#define strtok_r(A,B,C) strtok((A),(B)) +#endif + +#ifdef HAVE_LINUXTHREADS +/* #define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C)) */ +#define sigset(A,B) signal((A),(B)) +#endif + +/* Remove some things that mit_thread break or doesn't support */ +#if defined(HAVE_mit_thread) && defined(THREAD) +#undef HAVE_PREAD +#undef HAVE_REALPATH +#undef HAVE_MLOCK +#undef HAVE_TEMPNAM /* Use ours */ +#undef HAVE_PTHREAD_SETPRIO +#endif + +/* This is from the old m-machine.h file */ + +#if SIZEOF_LONG_LONG > 4 +#define HAVE_LONG_LONG 1 +#endif + +#if defined(HAVE_LONG_LONG) && !defined(LONGLONG_MIN) +#define LONGLONG_MIN ((long long) 0x8000000000000000LL) +#define LONGLONG_MAX ((long long) 0x7FFFFFFFFFFFFFFFLL) +#endif + +#if SIZEOF_LONG == 4 +#define INT_MIN32 (long) 0x80000000L +#define INT_MAX32 (long) 0x7FFFFFFFL +#define INT_MIN24 ((long) 0xff800000L) +#define INT_MAX24 0x007fffffL +#define INT_MIN16 ((short int) 0x8000) +#define INT_MAX16 0x7FFF +#define INT_MIN8 ((char) 0x80) +#define INT_MAX8 ((char) 0x7F) +#else /* Probably Alpha */ +#define INT_MIN32 ((long) (int) 0x80000000) +#define INT_MAX32 ((long) (int) 0x7FFFFFFF) +#define INT_MIN24 ((long) (int) 0xff800000) +#define INT_MAX24 ((long) (int) 0x007fffff) +#define INT_MIN16 ((short int) 0xffff8000) +#define INT_MAX16 ((short int) 0x00007FFF) +#endif + +/* From limits.h instead */ +#ifndef DBL_MIN +#define DBL_MIN 4.94065645841246544e-324 +#define FLT_MIN ((float)1.40129846432481707e-45) +#endif +#ifndef DBL_MAX +#define DBL_MAX 1.79769313486231470e+308 +#define FLT_MAX ((float)3.40282346638528860e+38) +#endif + +/* Max size that must be added to a so that we know Size to make + adressable obj. */ +typedef long my_ptrdiff_t; +#define MY_ALIGN(A,L) (((A) + (L) - 1) & ~((L) - 1)) +#define ALIGN_SIZE(A) MY_ALIGN((A),sizeof(double)) +/* Size to make adressable obj. */ +#define ALIGN_PTR(A, t) ((t*) MY_ALIGN((A),sizeof(t))) + /* Offset of filed f in structure t */ +#define OFFSET(t, f) ((size_t)(char *)&((t *)0)->f) +#define ADD_TO_PTR(ptr,size,type) (type) ((byte*) (ptr)+size) +#define PTR_BYTE_DIFF(A,B) (my_ptrdiff_t) ((byte*) (A) - (byte*) (B)) + +#define NullS (char *) 0 +/* Nowdays we do not support MessyDos */ +#ifndef NEAR +#define NEAR /* Who needs segments ? */ +#define FAR /* On a good machine */ +#define HUGE_PTR +#define STDCALL +#endif + +/* Typdefs for easyier portability */ + +#if defined(VOIDTYPE) +typedef void *gptr; /* Generic pointer */ +#else +typedef char *gptr; /* Generic pointer */ +#endif +#ifndef HAVE_INT_8_16_32 +typedef char int8; /* Signed integer >= 8 bits */ +typedef short int16; /* Signed integer >= 16 bits */ +#endif +#ifndef HAVE_UCHAR +typedef unsigned char uchar; /* Short for unsigned char */ +#endif +typedef unsigned char uint8; /* Short for unsigned integer >= 8 bits */ +typedef unsigned short uint16; /* Short for unsigned integer >= 16 bits */ + +#if SIZEOF_INT == 4 +#ifndef HAVE_INT_8_16_32 +typedef int int32; +#endif +typedef unsigned int uint32; /* Short for unsigned integer >= 32 bits */ +#elif SIZEOF_LONG == 4 +#ifndef HAVE_INT_8_16_32 +typedef long int32; +#endif +typedef unsigned long uint32; /* Short for unsigned integer >= 32 bits */ +#else +error "Neither int or long is of 4 bytes width" +#endif + +#if !defined(HAVE_ULONG) && !defined(HAVE_LINUXTHREADS) && !defined(__USE_MISC) +typedef unsigned long ulong; /* Short for unsigned long */ +#endif +#ifndef longlong_defined +#if defined(HAVE_LONG_LONG) && SIZEOF_LONG != 8 +typedef unsigned long long ulonglong; /* ulong or unsigned long long */ +typedef long long longlong; +#else +typedef unsigned long ulonglong; /* ulong or unsigned long long */ +typedef long longlong; +#endif +#endif + +#ifdef USE_RAID +/* The following is done with a if to not get problems with pre-processors + with late define evaluation */ +#if SIZEOF_OFF_T == 4 +#define SYSTEM_SIZEOF_OFF_T 4 +#else +#define SYSTEM_SIZEOF_OFF_T 8 +#endif +#undef SIZEOF_OFF_T +#define SIZEOF_OFF_T 8 +#endif + +#if SIZEOF_OFF_T > 4 +typedef ulonglong my_off_t; +#else +typedef unsigned long my_off_t; +#endif +#define MY_FILEPOS_ERROR (~(my_off_t) 0) +typedef off_t os_off_t; + +typedef uint8 int7; /* Most effective integer 0 <= x <= 127 */ +typedef short int15; /* Most effective integer 0 <= x <= 32767 */ +typedef char *my_string; /* String of characters */ +typedef unsigned long size_s; /* Size of strings (In string-funcs) */ +typedef int myf; /* Type of MyFlags in my_funcs */ +#ifndef byte_defined +typedef char byte; /* Smallest addressable unit */ +#endif +typedef char my_bool; /* Small bool */ +#if !defined(bool) && !defined(bool_defined) && (!defined(HAVE_BOOL) || !defined(__cplusplus)) +typedef char bool; /* Ordinary boolean values 0 1 */ +#endif + /* Macros for converting *constants* to the right type */ +#define INT8(v) (int8) (v) +#define INT16(v) (int16) (v) +#define INT32(v) (int32) (v) +#define MYF(v) (myf) (v) + +/* Defines to make it possible to prioritize register assignments. No + longer needed with moder compilers */ +#ifndef USING_X +#define reg1 register +#define reg2 register +#define reg3 register +#define reg4 register +#define reg5 register +#define reg6 register +#define reg7 register +#define reg8 register +#define reg9 register +#define reg10 register +#define reg11 register +#define reg12 register +#define reg13 register +#define reg14 register +#define reg15 register +#define reg16 register +#endif + +/* Defines for time function */ +#define SCALE_SEC 100 +#define SCALE_USEC 10000 +#define MY_HOW_OFTEN_TO_ALARM 2 /* How often we want info on screen */ +#define MY_HOW_OFTEN_TO_WRITE 1000 /* How often we want info on screen */ + +/* +** Define-funktions for reading and storing in machine independent format +** (low byte first) +*/ + +/* Optimized store functions for Intel x86 */ +#ifdef __i386__ +#define sint2korr(A) (*((int16 *) (A))) +#define sint3korr(A) ((int32) ((((uchar) (A)[2]) & 128) ? \ + (((uint32) 255L << 24) | \ + (((uint32) (uchar) (A)[2]) << 16) |\ + (((uint32) (uchar) (A)[1]) << 8) | \ + ((uint32) (uchar) (A)[0])) : \ + (((uint32) (uchar) (A)[2]) << 16) |\ + (((uint32) (uchar) (A)[1]) << 8) | \ + ((uint32) (uchar) (A)[0]))) +#define sint4korr(A) (*((long *) (A))) +#define uint2korr(A) (*((uint16 *) (A))) +#define uint3korr(A) (long) (*((unsigned long *) (A)) & 0xFFFFFF) +#define uint4korr(A) (*((unsigned long *) (A))) +#define uint5korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) +\ + (((uint32) ((uchar) (A)[1])) << 8) +\ + (((uint32) ((uchar) (A)[2])) << 16) +\ + (((uint32) ((uchar) (A)[3])) << 24)) +\ + (((ulonglong) ((uchar) (A)[4])) << 32)) +#define uint8korr(A) (*((ulonglong *) (A))) +#define sint8korr(A) (*((longlong *) (A))) +#define int2store(T,A) *((uint16*) (T))= (uint16) (A) +#define int3store(T,A) { *(T)= (uchar) ((A));\ + *(T+1)=(uchar) (((uint) (A) >> 8));\ + *(T+2)=(uchar) (((A) >> 16)); } +#define int4store(T,A) *((long *) (T))= (long) (A) +#define int5store(T,A) { *(T)= (uchar)((A));\ + *((T)+1)=(uchar) (((A) >> 8));\ + *((T)+2)=(uchar) (((A) >> 16));\ + *((T)+3)=(uchar) (((A) >> 24)); \ + *((T)+4)=(uchar) (((A) >> 32)); } +#define int8store(T,A) *((ulonglong *) (T))= (ulonglong) (A) + +#define doubleget(V,M) { *((long *) &V) = *((long*) M); \ + *(((long *) &V)+1) = *(((long*) M)+1); } +#define doublestore(T,V) { *((long *) T) = *((long*) &V); \ + *(((long *) T)+1) = *(((long*) &V)+1); } +#define float4get(V,M) { *((long *) &(V)) = *((long*) (M)); } +#define float8get(V,M) doubleget((V),(M)) +#define float4store(V,M) memcpy((byte*) V,(byte*) (&M),sizeof(float)) +#define float8store(V,M) doublestore((V),(M)) +#endif /* __i386__ */ + +#ifndef sint2korr +#define sint2korr(A) (int16) (((int16) ((uchar) (A)[0])) +\ + ((int16) ((int16) (A)[1]) << 8)) +#define sint3korr(A) ((int32) ((((uchar) (A)[2]) & 128) ? \ + (((uint32) 255L << 24) | \ + (((uint32) (uchar) (A)[2]) << 16) |\ + (((uint32) (uchar) (A)[1]) << 8) | \ + ((uint32) (uchar) (A)[0])) : \ + (((uint32) (uchar) (A)[2]) << 16) |\ + (((uint32) (uchar) (A)[1]) << 8) | \ + ((uint32) (uchar) (A)[0]))) +#define sint4korr(A) (int32) (((int32) ((uchar) (A)[0])) +\ + (((int32) ((uchar) (A)[1]) << 8)) +\ + (((int32) ((uchar) (A)[2]) << 16)) +\ + (((int32) ((int16) (A)[3]) << 24))) +#define sint8korr(A) (longlong) uint8korr(A) +#define uint2korr(A) (uint16) (((uint16) ((uchar) (A)[0])) +\ + ((uint16) ((uchar) (A)[1]) << 8)) +#define uint3korr(A) (uint32) (((uint32) ((uchar) (A)[0])) +\ + (((uint32) ((uchar) (A)[1])) << 8) +\ + (((uint32) ((uchar) (A)[2])) << 16)) +#define uint4korr(A) (uint32) (((uint32) ((uchar) (A)[0])) +\ + (((uint32) ((uchar) (A)[1])) << 8) +\ + (((uint32) ((uchar) (A)[2])) << 16) +\ + (((uint32) ((uchar) (A)[3])) << 24)) +#define uint5korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) +\ + (((uint32) ((uchar) (A)[1])) << 8) +\ + (((uint32) ((uchar) (A)[2])) << 16) +\ + (((uint32) ((uchar) (A)[3])) << 24)) +\ + (((ulonglong) ((uchar) (A)[4])) << 32)) +#define uint8korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) +\ + (((uint32) ((uchar) (A)[1])) << 8) +\ + (((uint32) ((uchar) (A)[2])) << 16) +\ + (((uint32) ((uchar) (A)[3])) << 24)) +\ + (((ulonglong) (((uint32) ((uchar) (A)[4])) +\ + (((uint32) ((uchar) (A)[5])) << 8) +\ + (((uint32) ((uchar) (A)[6])) << 16) +\ + (((uint32) ((uchar) (A)[7])) << 24))) <<\ + 32)) +#define int2store(T,A) { uint def_temp= (uint) (A) ;\ + *((uchar*) (T))= (uchar)(def_temp); \ + *((uchar*) (T+1))=(uchar)((def_temp >> 8)); } +#define int3store(T,A) { /*lint -save -e734 */\ + *((T))=(char) ((A));\ + *((T)+1)=(char) (((A) >> 8));\ + *((T)+2)=(char) (((A) >> 16)); \ + /*lint -restore */} +#define int4store(T,A) { *(T)=(char) ((A));\ + *((T)+1)=(char) (((A) >> 8));\ + *((T)+2)=(char) (((A) >> 16));\ + *((T)+3)=(char) (((A) >> 24)); } +#define int5store(T,A) { *(T)=((A));\ + *((T)+1)=(((A) >> 8));\ + *((T)+2)=(((A) >> 16));\ + *((T)+3)=(((A) >> 24)); \ + *((T)+4)=(((A) >> 32)); } +#define int8store(T,A) { uint def_temp= (uint) (A), def_temp2= (uint) ((A) >> 32); \ + int4store((T),def_temp); \ + int4store((T+4),def_temp2); \ + } +#ifdef WORDS_BIGENDIAN +#define float4store(T,A) { *(T)= ((byte *) &A)[3];\ + *((T)+1)=(char) ((byte *) &A)[2];\ + *((T)+2)=(char) ((byte *) &A)[1];\ + *((T)+3)=(char) ((byte *) &A)[0]; } + +#define float4get(V,M) { float def_temp;\ + ((byte*) &def_temp)[0]=(M)[3];\ + ((byte*) &def_temp)[1]=(M)[2];\ + ((byte*) &def_temp)[2]=(M)[1];\ + ((byte*) &def_temp)[3]=(M)[0];\ + (V)=def_temp; } +#define float8store(T,V) { *(T)= ((byte *) &V)[7];\ + *((T)+1)=(char) ((byte *) &V)[6];\ + *((T)+2)=(char) ((byte *) &V)[5];\ + *((T)+3)=(char) ((byte *) &V)[4];\ + *((T)+4)=(char) ((byte *) &V)[3];\ + *((T)+5)=(char) ((byte *) &V)[2];\ + *((T)+6)=(char) ((byte *) &V)[1];\ + *((T)+7)=(char) ((byte *) &V)[0]; } + +#define float8get(V,M) { double def_temp;\ + ((byte*) &def_temp)[0]=(M)[7];\ + ((byte*) &def_temp)[1]=(M)[6];\ + ((byte*) &def_temp)[2]=(M)[5];\ + ((byte*) &def_temp)[3]=(M)[4];\ + ((byte*) &def_temp)[4]=(M)[3];\ + ((byte*) &def_temp)[5]=(M)[2];\ + ((byte*) &def_temp)[6]=(M)[1];\ + ((byte*) &def_temp)[7]=(M)[0];\ + (V) = def_temp; } +#else +#define float4get(V,M) memcpy((byte*) &V,(byte*) (M),sizeof(float)) +#define float4store(V,M) memcpy((byte*) V,(byte*) (&M),sizeof(float)) +#define float8get(V,M) doubleget((V),(M)) +#define float8store(V,M) doublestore((V),(M)) +#endif /* WORDS_BIGENDIAN */ + +#endif /* sint2korr */ + +/* Define-funktions for reading and storing in machine format from/to + short/long to/from some place in memory V should be a (not + register) variable, M is a pointer to byte */ + +#ifdef WORDS_BIGENDIAN + +#define ushortget(V,M) { V = (uint16) (((uint16) ((uchar) (M)[1]))+\ + ((uint16) ((uint16) (M)[0]) << 8)); } +#define shortget(V,M) { V = (short) (((short) ((uchar) (M)[1]))+\ + ((short) ((short) (M)[0]) << 8)); } +#define longget(V,M) { int32 def_temp;\ + ((byte*) &def_temp)[0]=(M)[0];\ + ((byte*) &def_temp)[1]=(M)[1];\ + ((byte*) &def_temp)[2]=(M)[2];\ + ((byte*) &def_temp)[3]=(M)[3];\ + (V)=def_temp; } +#define ulongget(V,M) { uint32 def_temp;\ + ((byte*) &def_temp)[0]=(M)[0];\ + ((byte*) &def_temp)[1]=(M)[1];\ + ((byte*) &def_temp)[2]=(M)[2];\ + ((byte*) &def_temp)[3]=(M)[3];\ + (V)=def_temp; } +#define shortstore(T,A) { uint def_temp=(uint) (A) ;\ + *(T+1)=(char)(def_temp); \ + *(T+0)=(char)(def_temp >> 8); } +#define longstore(T,A) { *((T)+3)=((A));\ + *((T)+2)=(((A) >> 8));\ + *((T)+1)=(((A) >> 16));\ + *((T)+0)=(((A) >> 24)); } + +#define doubleget(V,M) memcpy((byte*) &V,(byte*) (M),sizeof(double)) +#define doublestore(T,V) memcpy((byte*) (T),(byte*) &V,sizeof(double)) +#define longlongget(V,M) memcpy((byte*) &V,(byte*) (M),sizeof(ulonglong)) +#define longlongstore(T,V) memcpy((byte*) (T),(byte*) &V,sizeof(ulonglong)) + +#else + +#define ushortget(V,M) { V = uint2korr(M); } +#define shortget(V,M) { V = sint2korr(M); } +#define longget(V,M) { V = sint4korr(M); } +#define ulongget(V,M) { V = uint4korr(M); } +#define shortstore(T,V) int2store(T,V) +#define longstore(T,V) int4store(T,V) +#ifndef doubleget +#define doubleget(V,M) memcpy((byte*) &V,(byte*) (M),sizeof(double)) +#define doublestore(T,V) memcpy((byte*) (T),(byte*) &V,sizeof(double)) +#endif +#define longlongget(V,M) memcpy((byte*) &V,(byte*) (M),sizeof(ulonglong)) +#define longlongstore(T,V) memcpy((byte*) (T),(byte*) &V,sizeof(ulonglong)) + +#endif /* WORDS_BIGENDIAN */ + +#endif /* _global_h */ diff --git a/ext/mysql/libmysql/int2str.c b/ext/mysql/libmysql/int2str.c new file mode 100644 index 0000000000..9d6d435721 --- /dev/null +++ b/ext/mysql/libmysql/int2str.c @@ -0,0 +1,97 @@ +/* + 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 <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; + + 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'; + *--p = _dig_vec[(ulong) val % (ulong) radix]; + val = (ulong) val / (ulong) radix; +#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) + { + *--p = _dig_vec[val%radix]; + val /= radix; + } +#endif + 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 diff --git a/ext/mysql/libmysql/is_prefix.c b/ext/mysql/libmysql/is_prefix.c new file mode 100644 index 0000000000..09b3accf75 --- /dev/null +++ b/ext/mysql/libmysql/is_prefix.c @@ -0,0 +1,20 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* 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 <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 */ +} diff --git a/ext/mysql/libmysql/list.c b/ext/mysql/libmysql/list.c new file mode 100644 index 0000000000..f39ac7e3e3 --- /dev/null +++ b/ext/mysql/libmysql/list.c @@ -0,0 +1,100 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* + 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) +{ + 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; + 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, pbool free_data) +{ + LIST *next; + while (root) + { + next=root->next; + if (free_data) + my_free((gptr) root->data,MYF(0)); + my_free((gptr) root,MYF(0)); + root=next; + } +} + + +LIST *list_cons(void *data, LIST *list) +{ + LIST *new=(LIST*) my_malloc(sizeof(LIST),MYF(MY_FAE)); + if (!new) + return 0; + new->data=data; + return list_add(list,new); +} + + +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; +} diff --git a/ext/mysql/libmysql/longlong2str.c b/ext/mysql/libmysql/longlong2str.c new file mode 100644 index 0000000000..9759208266 --- /dev/null +++ b/ext/mysql/libmysql/longlong2str.c @@ -0,0 +1,81 @@ +/* + 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 <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) + { + *--p = _dig_vec[long_val%radix]; + long_val /= radix; + } + while ((*dst++ = *p++) != 0) ; + return dst-1; +} + +#endif diff --git a/ext/mysql/libmysql/m_ctype.h b/ext/mysql/libmysql/m_ctype.h new file mode 100644 index 0000000000..d3b55aafff --- /dev/null +++ b/ext/mysql/libmysql/m_ctype.h @@ -0,0 +1,231 @@ +/* Copyright (C) 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + For a more info consult the file COPYRIGHT distributed with this file */ +/* + A better inplementation of the UNIX ctype(3) library. + Notes: global.h should be included before ctype.h +*/ + +#ifndef _m_ctype_h +#define _m_ctype_h + +#define MY_CHARSET_UNDEFINED 0 +#define MY_CHARSET_BIG5 1 +#define MY_CHARSET_CZECH 2 +#define MY_CHARSET_DEC8 3 +#define MY_CHARSET_DOS 4 +#define MY_CHARSET_GERMAN1 5 +#define MY_CHARSET_HP8 6 +#define MY_CHARSET_KOI8_RU 7 +#define MY_CHARSET_LATIN1 8 +#define MY_CHARSET_LATIN2 9 +#define MY_CHARSET_SWE7 10 +#define MY_CHARSET_USA7 11 +#define MY_CHARSET_UJIS 12 +#define MY_CHARSET_SJIS 13 +#define MY_CHARSET_CP1251 14 +#define MY_CHARSET_DANISH 15 +#define MY_CHARSET_HEBREW 16 +#define MY_CHARSET_WIN1251 17 +#define MY_CHARSET_TIS620 18 +#define MY_CHARSET_EUC_KR 19 +#define MY_CHARSET_ESTONIA 20 +#define MY_CHARSET_HUNGARIAN 21 +#define MY_CHARSET_KOI8_UKR 22 +#define MY_CHARSET_WIN1251UKR 23 +#define MY_CHARSET_GB2312 24 +#define MY_CHARSET_GREEK 25 +#define MY_CHARSET_WIN1250 26 +#define MY_CHARSET_CROAT 27 +#define MY_CHARSET_GBK 28 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __WIN32__ +#include <ctype.h> +#endif +/* Don't include std ctype.h when this is included */ +#define _CTYPE_H +#define _CTYPE_INCLUDED +#define __CTYPE_INCLUDED +#define _CTYPE_USING /* Don't put names in global namespace. */ + +#ifndef CTYPE_LIBRARY +#define EXT extern +#define D(x) +#else +#define EXT +#define D(x) = x +#endif + +#define _U 01 /* Upper case */ +#define _L 02 /* Lower case */ +#define _N 04 /* Numeral (digit) */ +#define _S 010 /* Spacing character */ +#define _P 020 /* Punctuation */ +#define _C 040 /* Control character */ +#define _B 0100 /* Blank */ +#define _X 0200 /* heXadecimal digit */ + +extern uchar NEAR ctype_latin1[]; +extern uchar NEAR to_upper_latin1[]; +extern uchar NEAR to_lower_latin1[]; +extern uchar NEAR sort_order_latin1[]; + +#define my_ctype ctype_latin1 +#define my_to_upper to_upper_latin1 +#define my_to_lower to_lower_latin1 +#define my_sort_order sort_order_latin1 + +#ifndef __WIN32__ +#define _toupper(c) (char) my_to_upper[(uchar) (c)] +#define _tolower(c) (char) my_to_lower[(uchar) (c)] +#define toupper(c) (char) my_to_upper[(uchar) (c)] +#define tolower(c) (char) my_to_lower[(uchar) (c)] + +#define isalpha(c) ((my_ctype+1)[(uchar) (c)] & (_U | _L)) +#define isupper(c) ((my_ctype+1)[(uchar) (c)] & _U) +#define islower(c) ((my_ctype+1)[(uchar) (c)] & _L) +#define isdigit(c) ((my_ctype+1)[(uchar) (c)] & _N) +#define isxdigit(c) ((my_ctype+1)[(uchar) (c)] & _X) +#define isalnum(c) ((my_ctype+1)[(uchar) (c)] & (_U | _L | _N)) +#define isspace(c) ((my_ctype+1)[(uchar) (c)] & _S) +#define ispunct(c) ((my_ctype+1)[(uchar) (c)] & _P) +#define isprint(c) ((my_ctype+1)[(uchar) (c)] & (_P | _U | _L | _N | _B)) +#define isgraph(c) ((my_ctype+1)[(uchar) (c)] & (_P | _U | _L | _N)) +#define iscntrl(c) ((my_ctype+1)[(uchar) (c)] & _C) +#define isascii(c) (!((c) & ~0177)) +#define toascii(c) ((c) & 0177) + +#ifdef ctype +#undef ctype +#endif /* ctype */ + +#endif /* __WIN32__ */ + +/* Some macros that should be cleaned up a little */ +#define isvar(c) (isalnum(c) || (c) == '_') +#define isvar_start(c) (isalpha(c) || (c) == '_') +#define tocntrl(c) ((c) & 31) +#define toprint(c) ((c) | 64) + +/* Support for Japanese(UJIS) characters, by tommy@valley.ne.jp */ +#if MY_CHARSET_CURRENT == MY_CHARSET_UJIS +#define USE_MB +#define USE_MB_IDENT +#define isujis(c) ((0xa1<=((c)&0xff) && ((c)&0xff)<=0xfe)) +#define iskata(c) ((0xa1<=((c)&0xff) && ((c)&0xff)<=0xdf)) +#define isujis_ss2(c) (((c)&0xff) == 0x8e) +#define isujis_ss3(c) (((c)&0xff) == 0x8f) +#define ismbchar(p, end) ((*(uchar*)(p)<0x80)? 0:\ + isujis(*(p)) && (end)-(p)>1 && isujis(*((p)+1))? 2:\ + isujis_ss2(*(p)) && (end)-(p)>1 && iskata(*((p)+1))? 2:\ + isujis_ss3(*(p)) && (end)-(p)>2 && isujis(*((p)+1)) && isujis(*((p)+2))? 3:\ + 0) +#define ismbhead(c) (isujis(c) || isujis_ss2(c) || isujis_ss3(c)) +#define mbcharlen(c) (isujis(c)? 2: isujis_ss2(c)? 2: isujis_ss3(c)? 3: 0) +#define MBMAXLEN 3 +#endif + +/* Support for Japanese(SJIS) characters, by tommy@valley.ne.jp */ +#if MY_CHARSET_CURRENT == MY_CHARSET_SJIS +#define USE_MB +#define USE_MB_IDENT +#define issjishead(c) ((0x81<=((c)&0xff) && ((c)&0xff)<=0x9f) || (0xe0<=((c)&0xff) && ((c)&0xff)<=0xfc)) +#define issjistail(c) ((0x40<=((c)&0xff) && ((c)&0xff)<=0x7e) || (0x80<=((c)&0xff) && ((c)&0xff)<=0xfc)) +#define ismbchar(p, end) (issjishead(*(p)) && (end)-(p)>1 && issjistail(*((p)+1))? 2: 0) +#define ismbhead(c) issjishead(c) +#define mbcharlen(c) (issjishead(c)? 2: 0) +#define MBMAXLEN 2 +#endif + +/* Support for Chinese(BIG5) characters, by jou@nematic.ieo.nctu.edu.tw + modified by Wei He (hewei@mail.ied.ac.cn) */ + +#if MY_CHARSET_CURRENT == MY_CHARSET_BIG5 +#define USE_MB +#define USE_MB_IDENT +#define isbig5head(c) (0xa1<=(uchar)(c) && (uchar)(c)<=0xf9) +#define isbig5tail(c) ((0x40<=(uchar)(c) && (uchar)(c)<=0x7e) || \ + (0xa1<=(uchar)(c) && (uchar)(c)<=0xfe)) +#define ismbchar(p, end) (isbig5head(*(p)) && (end)-(p)>1 && isbig5tail(*((p)+1))? 2: 0) +#define ismbhead(c) isbig5head(c) +#define mbcharlen(c) (isbig5head(c)? 2: 0) +#define MBMAXLEN 2 +# +#undef USE_STRCOLL +#define USE_STRCOLL +#endif + +/* Support for Chinese(GB2312) characters, by Miles Tsai (net-bull@126.com) + modified by Wei He (hewei@mail.ied.ac.cn) */ + +#if MY_CHARSET_CURRENT == MY_CHARSET_GB2312 +#define USE_MB +#define USE_MB_IDENT +#define isgb2312head(c) (0xa1<=(uchar)(c) && (uchar)(c)<=0xf7) +#define isgb2312tail(c) (0xa1<=(uchar)(c) && (uchar)(c)<=0xfe) +#define ismbchar(p, end) (isgb2312head(*(p)) && (end)-(p)>1 && isgb2312tail(*((p)+1))? 2: 0) +#define ismbhead(c) isgb2312head(c) +#define mbcharlen(c) (isgb2312head(c)? 2:0) +#define MBMAXLEN 2 +#endif + +/* Support for Chinese(GBK) characters, by hewei@mail.ied.ac.cn */ + +#if MY_CHARSET_CURRENT == MY_CHARSET_GBK +#define USE_MB +#define USE_MB_IDENT +#define isgbkhead(c) (0x81<=(uchar)(c) && (uchar)(c)<=0xfe) +#define isgbktail(c) ((0x40<=(uchar)(c) && (uchar)(c)<=0x7e) || \ + (0x80<=(uchar)(c) && (uchar)(c)<=0xfe)) +#define ismbchar(p, end) (isgbkhead(*(p)) && (end)-(p)>1 && isgbktail(*((p)+1))? 2: 0) +#define ismbhead(c) isgbkhead(c) +#define mbcharlen(c) (isgbkhead(c)? 2:0) +#define MBMAXLEN 2 +#undef USE_STRCOLL +#define USE_STRCOLL +#endif + +/* Define, how much will the string grow under strxfrm */ +#if MY_CHARSET_CURRENT == MY_CHARSET_CZECH +#undef USE_STRCOLL +#define USE_STRCOLL +#endif +#if MY_CHARSET_CURRENT == MY_CHARSET_TIS620 +#undef USE_STRCOLL +#define USE_STRCOLL +#define USE_TIS620 +#include "t_ctype.h" +#endif + +/* Support for Korean(EUC_KR) characters, by powerm90@tinc.co.kr and mrpark@tinc.co.kr */ +#if MY_CHARSET_CURRENT == MY_CHARSET_EUC_KR +#define USE_MB +#define USE_MB_IDENT +#define iseuc_kr(c) ((0xa1<=(uchar)(c) && (uchar)(c)<=0xfe)) +#define ismbchar(p, end) ((*(uchar*)(p)<0x80)? 0:\ + iseuc_kr(*(p)) && (end)-(p)>1 && iseuc_kr(*((p)+1))? 2:\ + 0) +#define ismbhead(c) (iseuc_kr(c)) +#define mbcharlen(c) (iseuc_kr(c) ? 2 : 0) +#define MBMAXLEN 2 +#endif + +#ifdef USE_STRCOLL +extern uint MY_STRXFRM_MULTIPLY; +extern int my_strnxfrm(unsigned char *, unsigned char *, int, int); +extern int my_strnncoll(const unsigned char *, int, const unsigned char *, int); +extern int my_strxfrm(unsigned char *, unsigned char *, int); +extern int my_strcoll(const unsigned char *, const unsigned char *); +extern my_bool my_like_range(const char *ptr,uint ptr_length,pchar escape, + uint res_length, char *min_str,char *max_str, + uint *min_length,uint *max_length); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _m_ctype_h */ diff --git a/ext/mysql/libmysql/m_string.h b/ext/mysql/libmysql/m_string.h new file mode 100644 index 0000000000..37207b6612 --- /dev/null +++ b/ext/mysql/libmysql/m_string.h @@ -0,0 +1,209 @@ +/* Copyright (C) 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + For a more info consult the file COPYRIGHT distributed with this file */ + +/* There may be prolems include all of theese. Try to test in + configure with ones are needed? */ + +/* This is needed for the definitions of strchr... on solaris */ + +#ifndef _m_string_h +#define _m_string_h +#if defined(HAVE_STRINGS_H) +#include <strings.h> +#endif +#if defined(HAVE_STRING_H) +#include <string.h> +#endif + +/* Correct some things for UNIXWARE7 */ +#ifdef HAVE_UNIXWARE7_THREADS +#undef HAVE_STRINGS_H +#undef HAVE_MEMORY_H +#define HAVE_MEMCPY +#ifndef HAVE_MEMMOVE +#define HAVE_MEMMOVE +#endif +#undef HAVE_BCMP +#undef bcopy +#undef bcmp +#undef bzero +#endif /* HAVE_UNIXWARE7_THREADS */ +#ifdef _AIX +#undef HAVE_BCMP +#endif + +/* This is needed for the definitions of bzero... on solaris */ +#if defined(HAVE_STRINGS_H) && !defined(HAVE_mit_thread) +#include <strings.h> +#endif + +/* This is needed for the definitions of memcpy... on solaris */ +#if defined(HAVE_MEMORY_H) && !defined(__cplusplus) +#include <memory.h> +#endif + +#if !defined(HAVE_MEMCPY) && !defined(HAVE_MEMMOVE) +# define memcpy(d, s, n) bcopy ((s), (d), (n)) +# define memset(A,C,B) bfill((A),(B),(C)) +# define memmove(d, s, n) bmove ((s), (d), (n)) +#elif defined(HAVE_MEMMOVE) +# define bmove(d, s, n) memmove((d), (s), (n)) +#else +# define memmove(d, s, n) bmove((d), (s), (n)) /* our bmove */ +#endif + +/* Unixware 7 */ +#if !defined(HAVE_BFILL) +# define bfill(A,B,C) memset((A),(C),(B)) +# define bmove_allign(A,B,C) memcpy((A),(B),(C)) +#endif + +#if !defined(HAVE_BCMP) +# define bcopy(s, d, n) memcpy((d), (s), (n)) +# define bcmp(A,B,C) memcmp((A),(B),(C)) +# define bzero(A,B) memset((A),0,(B)) +# define bmove_allign(A,B,C) memcpy((A),(B),(C)) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +extern char NEAR _dig_vec[]; /* Declared in int2str() */ + +#ifdef BAD_STRING_COMPILER +#define strmov(A,B) (memccpy(A,B,0,INT_MAX)-1) +#else +#define strmov_overlapp(A,B) strmov(A,B) +#define strmake_overlapp(A,B,C) strmake(A,B,C) +#endif + +#ifdef MSDOS +#undef bmove_allign +#define bmove512(A,B,C) bmove_allign(A,B,C) +#define my_itoa(A,B,C) itoa(A,B,C) +#define my_ltoa(A,B,C) ltoa(A,B,C) +extern void bmove_allign(gptr dst,const gptr src,uint len); +#endif + +#if (!defined(USE_BMOVE512) || defined(HAVE_purify)) && !defined(bmove512) +#define bmove512(A,B,C) memcpy(A,B,C) +#endif + + /* Prototypes for string functions */ + +#if !defined(bfill) && !defined(HAVE_BFILL) +extern void bfill(gptr dst,uint len,pchar fill); +#endif + +#if !defined(bzero) && !defined(HAVE_BZERO) +extern void bzero(gptr dst,uint len); +#endif + +#if !defined(bcmp) && !defined(HAVE_BCMP) +extern int bcmp(const char *s1,const char *s2,uint len); +#ifdef HAVE_purify +extern int my_bcmp(const char *s1,const char *s2,uint len); +#define bcmp(A,B,C) my_bcmp((A),(B),(C)) +#endif +#endif + +#ifndef bmove512 +extern void bmove512(gptr dst,const gptr src,uint len); +#endif + +#if !defined(HAVE_BMOVE) && !defined(bmove) +extern void bmove(gptr dst,const char *src,uint len); +#endif + +extern void bmove_upp(char *dst,const char *src,uint len); +extern void bchange(char *dst,uint old_len,const char *src, + uint new_len,uint tot_len); +extern void strappend(char *s,uint len,pchar fill); +extern char *strend(const char *s); +extern char *strcend(const char *, pchar); +extern char *strfield(char *src,int fields,int chars,int blanks, + int tabch); +extern char *strfill(my_string s,uint len,pchar fill); +extern uint strinstr(const char *str,const char *search); +extern uint r_strinstr(reg1 my_string str,int from, reg4 my_string search); +extern char *strkey(char *dst,char *head,char *tail,char *flags); +extern char *strmake(char *dst,const char *src,uint length); +#ifndef strmake_overlapp +extern char *strmake_overlapp(char *dst,const char *src, uint length); +#endif + +#ifndef strmov +extern char *strmov(char *dst,const char *src); +#endif +extern uint strnlen(const char *s,uint n); +extern char *strnmov(char *dst,const char *src,uint n); +extern char *strsuff(const char *src,const char *suffix); +extern char *strcont(const char *src,const char *set); +extern char *strxcat _VARARGS((char *dst,const char *src, ...)); +extern char *strxmov _VARARGS((char *dst,const char *src, ...)); +extern char *strxcpy _VARARGS((char *dst,const char *src, ...)); +extern char *strxncat _VARARGS((char *dst,uint len, const char *src, ...)); +extern char *strxnmov _VARARGS((char *dst,uint len, const char *src, ...)); +extern char *strxncpy _VARARGS((char *dst,uint len, const char *src, ...)); + +/* Prototypes of normal stringfunctions (with may ours) */ + +#ifdef WANT_STRING_PROTOTYPES +extern char *strcat(char *, const char *); +extern char *strchr(const char *, pchar); +extern char *strrchr(const char *, pchar); +extern char *strcpy(char *, const char *); +extern int strcmp(const char *, const char *); +#ifndef __GNUC__ +extern size_t strlen(const char *); +#endif +#endif + +#if !defined(__cplusplus) +#ifndef HAVE_STRPBRK +extern char *strpbrk(const char *, const char *); +#endif +#ifndef HAVE_STRSTR +extern char *strstr(const char *, const char *); +#endif +#endif +extern qsort_cmp get_ptr_compare(uint); +extern int is_prefix(const char *, const char *); + +/* Conversion rutins */ + +#ifdef USE_MY_ITOA +extern char *my_itoa(int val,char *dst,int radix); +extern char *my_ltoa(long val,char *dst,int radix); +#endif + +#ifndef HAVE_STRTOUL +extern long strtol(const char *str, char **ptr, int base); +extern ulong strtoul(const char *str, char **ptr, int base); +#endif + +extern char *int2str(long val,char *dst,int radix); +extern char *str2int(const char *src,int radix,long lower,long upper, + long *val); +#if SIZEOF_LONG == SIZEOF_LONG_LONG +#define longlong2str(A,B,C) int2str((A),(B),(C)) +#define strtoll(A,B,C) strtol((A),(B),(C)) +#define strtoull(A,B,C) strtoul((A),(B),(C)) +#ifndef HAVE_STRTOULL +#define HAVE_STRTOULL +#endif +#else +#ifdef HAVE_LONG_LONG +extern char *longlong2str(longlong val,char *dst,int radix); +#if (!defined(HAVE_STRTOULL) || defined(HAVE_mit_thread)) || defined(NO_STRTOLL_PROTO) +extern longlong strtoll(const char *str, char **ptr, int base); +extern ulonglong strtoull(const char *str, char **ptr, int base); +#endif +#endif +#endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ext/mysql/libmysql/mf_casecnv.c b/ext/mysql/libmysql/mf_casecnv.c new file mode 100644 index 0000000000..6b24182b9c --- /dev/null +++ b/ext/mysql/libmysql/mf_casecnv.c @@ -0,0 +1,195 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* + Functions to convert to lover_case and to upper_case in scandinavia. + + case_sort converts a character string to a representaion that can + be compared by strcmp to find with is alfabetical bigger. + (lower- and uppercase letters is compared as the same) +*/ + +#include "mysys_priv.h" +#include <m_ctype.h> + + /* string to uppercase */ + +void caseup_str(my_string str) +{ +#ifdef USE_MB + register uint32 l; + register char *end=str+strlen(str); + while (*str) + { + if ((l=ismbchar(str,end))) str+=l; + else *str=toupper(*str),++str; + } +#else + while ((*str = toupper(*str)) != 0) + str++; +#endif +} /* caseup_str */ + + /* string to lowercase */ + +void casedn_str(my_string str) +{ +#ifdef USE_MB + register uint32 l; + register char *end=str+strlen(str); + while (*str) + { + if ((l=ismbchar(str,end))) str+=l; + else *str=tolower(*str),++str; + } +#else + while ((*str= tolower(*str)) != 0) + str++; +#endif +} /* casedn_str */ + + + /* to uppercase */ + +void caseup(my_string str, uint length) +{ +#ifdef USE_MB + register uint32 l; + register char *end=str+length; + while (str<end) + { + if ((l=ismbchar(str,end))) str+=l; + else *str=toupper(*str),++str; + } +#else + for ( ; length>0 ; length--, str++) + *str= toupper(*str); +#endif +} /* caseup */ + + /* to lowercase */ + +void casedn(my_string str, uint length) +{ +#ifdef USE_MB + register uint32 l; + register char *end=str+length; + while (str<end) + { + if ((l=ismbchar(str,end))) str+=l; + else *str=tolower(*str),++str; + } +#else + for ( ; length>0 ; length--, str++) + *str= tolower(*str); +#endif +} /* casedn */ + + /* to sort-string that can be compared to get text in order */ + +void case_sort(my_string str, uint length) +{ + for ( ; length>0 ; length--, str++) + *str= (char) my_sort_order[(uchar) *str]; +} /* case_sort */ + + /* find string in another with no case_sensivity */ + +/* ToDo: This function should be modified to support multibyte charset. + However it is not used untill 3.23.5. + Wei He (hewei@mail.ied.ac.cn) +*/ + +my_string strcasestr(const char *str, const char *search) +{ + uchar *i,*j,*pos; + + pos=(uchar*) str; +skipp: + while (*pos != '\0') + { + if (toupper((uchar) *pos++) == toupper((uchar) *search)) { + i=(uchar*) pos; j=(uchar*) search+1; + while (*j) + if (toupper(*i++) != toupper(*j++)) goto skipp; + return ((char*) pos-1); + } + } + return ((my_string) 0); +} /* strcstr */ + + + /* compare strings without regarding to case */ + +int my_strcasecmp(const char *s, const char *t) +{ +#ifdef USE_MB + register uint32 l; + register const char *end=s+strlen(s); + while (s<end) + { + if ((l=ismbchar(s,end))) + { + while (l--) + if (*s++ != *t++) return 1; + } + else if (ismbhead(*t)) return 1; + else if (toupper((uchar) *s++) != toupper((uchar) *t++)) return 1; + } + return *t; +#else + while (toupper((uchar) *s) == toupper((uchar) *t++)) + if (!*s++) return 0; + return ((int) toupper((uchar) s[0]) - (int) toupper((uchar) t[-1])); +#endif +} + + +int my_casecmp(const char *s, const char *t, uint len) +{ +#ifdef USE_MB + register uint32 l; + register const char *end=s+len; + while (s<end) + { + if ((l=ismbchar(s,end))) + { + while (l--) + if (*s++ != *t++) return 1; + } + else if (ismbhead(*t)) return 1; + else if (toupper((uchar) *s++) != toupper((uchar) *t++)) return 1; + } + return 0; +#else + while (len-- != 0 && toupper(*s++) == toupper(*t++)) ; + return (int) len+1; +#endif +} + + +int my_strsortcmp(const char *s, const char *t) +{ +#ifdef USE_STRCOLL + return my_strcoll((uchar *)s, (uchar *)t); +#else + while (my_sort_order[(uchar) *s] == my_sort_order[(uchar) *t++]) + if (!*s++) return 0; + return ((int) my_sort_order[(uchar) s[0]] - (int) my_sort_order[(uchar) t[-1]]); +#endif +} + +int my_sortcmp(const char *s, const char *t, uint len) +{ +#ifndef USE_STRCOLL + while (len--) + { + if (my_sort_order[(uchar) *s++] != my_sort_order[(uchar) *t++]) + return ((int) my_sort_order[(uchar) s[-1]] - + (int) my_sort_order[(uchar) t[-1]]); + } + return 0; +#else + return my_strnncoll((uchar *)s, len, (uchar *)t, len); +#endif +} diff --git a/ext/mysql/libmysql/mf_dirname.c b/ext/mysql/libmysql/mf_dirname.c new file mode 100644 index 0000000000..0897be7882 --- /dev/null +++ b/ext/mysql/libmysql/mf_dirname.c @@ -0,0 +1,92 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +#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=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 + +void convert_dirname(my_string to) +{ +#ifdef FN_UPPER_CASE + caseup_str(to); +#endif +#ifdef FN_LOWER_CASE + casedn_str(to); +#endif +#if FN_LIBCHAR != '/' + { + reg1 my_string pos; + pos=to-1; /* Change from '/' */ + while ((pos=strchr(pos+1,'/')) != 0) + *pos=FN_LIBCHAR; + } +#endif +#ifdef FN_C_BEFORE_DIR_2 + { + reg1 my_string pos; + 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 */ + char *end=strend(to); + if (end != to && (end[-1] != FN_LIBCHAR && end[-1] != FN_DEVCHAR)) + { + end[0]=FN_LIBCHAR; + end[1]=0; + } + } +#endif +} /* convert_dirname */ diff --git a/ext/mysql/libmysql/mf_fn_ext.c b/ext/mysql/libmysql/mf_fn_ext.c new file mode 100644 index 0000000000..0a52e60af3 --- /dev/null +++ b/ext/mysql/libmysql/mf_fn_ext.c @@ -0,0 +1,31 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* Returnerar en pekare till filnamnets extension. */ + +#include "mysys_priv.h" +#include <m_string.h> + + /* Returnera en pekare till ett filnamns extension. + Pekaren pekar p} extensions-karakt{ren. Om ingen extension hittas + returneras en pekare till NULL-tecknet i filnamnet */ + /* Denna funktion r|r inte p} utg}ngsnamnet */ + +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 */ diff --git a/ext/mysql/libmysql/mf_format.c b/ext/mysql/libmysql/mf_format.c new file mode 100644 index 0000000000..ca2188b199 --- /dev/null +++ b/ext/mysql/libmysql/mf_format.c @@ -0,0 +1,132 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +#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 */ + +#ifdef MAXPATHLEN +#define BUFF_LEN MAXPATHLEN +#else +#define BUFF_LEN FN_LEN +#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) strmov(dev,dsk); /* 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=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=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; + } + (void) strmov(strnmov(strmov(to,dev),name,length),ext); +#ifdef FN_UPPER_CASE + caseup_str(to); +#endif +#ifdef FN_LOWER_CASE + casedn_str(to); +#endif + } + /* Purify gives a lot of UMR errors when using realpath */ +#if defined(HAVE_REALPATH) && !defined(HAVE_purify) + if (flag & 16) + { + struct stat stat_buff; + if (flag & 32 || (!lstat(to,&stat_buff) && S_ISLNK(stat_buff.st_mode))) + { + if (realpath(to,buff)) + strmov(to,buff); + } + } +#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 */ diff --git a/ext/mysql/libmysql/mf_loadpath.c b/ext/mysql/libmysql/mf_loadpath.c new file mode 100644 index 0000000000..8e3118968d --- /dev/null +++ b/ext/mysql/libmysql/mf_loadpath.c @@ -0,0 +1,39 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +#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: %d",path,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 */ diff --git a/ext/mysql/libmysql/mf_pack.c b/ext/mysql/libmysql/mf_pack.c new file mode 100644 index 0000000000..3dab1621f5 --- /dev/null +++ b/ext/mysql/libmysql/mf_pack.c @@ -0,0 +1,472 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +#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 */ + +void pack_dirname(my_string to, const char *from) + + /* to may be == from */ +{ + int cwd_err; + uint d_length,length,buff_length; + 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=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,strlen(to)+1); + } + } + + if ((d_length= cleanup_dirname(to,to)) != 0) + { + length=0; + if (home_dir) + { + length=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=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 */ + + + /* 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],*suffix,*tilde_expansion; + DBUG_ENTER("unpack_dirname"); + + (void) intern_filename(buff,from); /* Change to intern name */ + length=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=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); + } + } + } + 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 */ diff --git a/ext/mysql/libmysql/mf_path.c b/ext/mysql/libmysql/mf_path.c new file mode 100644 index 0000000000..c51a79e238 --- /dev/null +++ b/ext/mysql/libmysql/mf_path.c @@ -0,0 +1,106 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +#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,strlen(curr_dir),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__) +#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 */ +} diff --git a/ext/mysql/libmysql/mf_unixpath.c b/ext/mysql/libmysql/mf_unixpath.c new file mode 100644 index 0000000000..f28bfb3f23 --- /dev/null +++ b/ext/mysql/libmysql/mf_unixpath.c @@ -0,0 +1,19 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +#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 +} diff --git a/ext/mysql/libmysql/mf_wcomp.c b/ext/mysql/libmysql/mf_wcomp.c new file mode 100644 index 0000000000..8c9d43a01c --- /dev/null +++ b/ext/mysql/libmysql/mf_wcomp.c @@ -0,0 +1,54 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* 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 */ diff --git a/ext/mysql/libmysql/mulalloc.c b/ext/mysql/libmysql/mulalloc.c new file mode 100644 index 0000000000..88cfd33ef5 --- /dev/null +++ b/ext/mysql/libmysql/mulalloc.c @@ -0,0 +1,39 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + + /* 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); +} diff --git a/ext/mysql/libmysql/my_alarm.h b/ext/mysql/libmysql/my_alarm.h new file mode 100644 index 0000000000..42e41cc48f --- /dev/null +++ b/ext/mysql/libmysql/my_alarm.h @@ -0,0 +1,46 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* + File to include when we want to use alarm or a loop_counter to display + some information when a program is running +*/ +#ifndef _my_alarm_h +#define _my_alarm_h +#ifdef __cplusplus +extern "C" { +#endif + +extern int volatile my_have_got_alarm; +extern ulong my_time_to_wait_for_lock; + +#if defined(HAVE_ALARM) && !defined(NO_ALARM_LOOP) +#include <signal.h> +#define ALARM_VARIABLES uint alarm_old=0; \ + sig_return alarm_signal=0 +#define ALARM_INIT my_have_got_alarm=0 ; \ + alarm_old=(uint) alarm(MY_HOW_OFTEN_TO_ALARM); \ + alarm_signal=signal(SIGALRM,my_set_alarm_variable); +#define ALARM_END VOID(signal(SIGALRM,alarm_signal)); \ + VOID(alarm(alarm_old)); +#define ALARM_TEST my_have_got_alarm +#ifdef DONT_REMEMBER_SIGNAL +#define ALARM_REINIT VOID(alarm(MY_HOW_OFTEN_TO_ALARM)); \ + VOID(signal(SIGALRM,my_set_alarm_variable));\ + my_have_got_alarm=0; +#else +#define ALARM_REINIT VOID(alarm((uint) MY_HOW_OFTEN_TO_ALARM)); \ + my_have_got_alarm=0; +#endif /* DONT_REMEMBER_SIGNAL */ +#else +#define ALARM_VARIABLES long alarm_pos=0,alarm_end_pos=MY_HOW_OFTEN_TO_WRITE-1 +#define ALARM_INIT +#define ALARM_END +#define ALARM_TEST (alarm_pos++ >= alarm_end_pos) +#define ALARM_REINIT alarm_end_pos+=MY_HOW_OFTEN_TO_WRITE +#endif /* HAVE_ALARM */ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ext/mysql/libmysql/my_alloc.c b/ext/mysql/libmysql/my_alloc.c new file mode 100644 index 0000000000..4dec9115d9 --- /dev/null +++ b/ext/mysql/libmysql/my_alloc.c @@ -0,0 +1,115 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* Routines to handle mallocing of results which will be freed the same time */ + +#include <global.h> +#include <my_sys.h> +#include <m_string.h> + +void init_alloc_root(MEM_ROOT *mem_root,uint block_size) +{ + mem_root->free=mem_root->used=0; + mem_root->min_malloc=16; + mem_root->block_size=block_size-MALLOC_OVERHEAD-sizeof(USED_MEM)-8; + mem_root->error_handler=0; +} + +gptr alloc_root(MEM_ROOT *mem_root,unsigned int 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 + uint get_size,max_left; + gptr point; + reg1 USED_MEM *next; + reg2 USED_MEM **prev; + + Size= ALIGN_SIZE(Size); + prev= &mem_root->free; + max_left=0; + for (next= *prev ; 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 < mem_root->block_size && get_size < mem_root->block_size) + get_size=mem_root->block_size; /* Normal alloc */ + + 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 */ + } + 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; + } + return(point); +#endif +} + + /* deallocate everything used by alloc_root */ + +void free_root(MEM_ROOT *root) +{ + reg1 USED_MEM *next,*old; + DBUG_ENTER("free_root"); + + if (!root) + DBUG_VOID_RETURN; /* purecov: inspected */ + for (next= root->used ; next ; ) + { + old=next; next= next->next ; + my_free((gptr) old,MYF(0)); + } + for (next= root->free ; next ; ) + { + old=next; next= next->next ; + my_free((gptr) old,MYF(0)); + } + root->used=root->free=0; + DBUG_VOID_RETURN; +} + +char *strdup_root(MEM_ROOT *root,const char *str) +{ + uint 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,uint len) +{ + char *pos; + if ((pos=alloc_root(root,len))) + memcpy(pos,str,len); + return pos; +} diff --git a/ext/mysql/libmysql/my_compress.c b/ext/mysql/libmysql/my_compress.c new file mode 100644 index 0000000000..79d4d2963d --- /dev/null +++ b/ext/mysql/libmysql/my_compress.c @@ -0,0 +1,73 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* Written by Sinisa Milivojevic <sinisa@coresinc.com> */ + +#include <global.h> +#ifdef HAVE_COMPRESS +#include <my_sys.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(byte *packet, ulong *len, ulong *complen) +{ + if (*len < MIN_COMPRESS_LENGTH) + *complen=0; + else + { + byte *compbuf=my_compress_alloc(packet,len,complen); + if (!compbuf) + return *complen ? 0 : 1; + memcpy(packet,compbuf,*len); + my_free(compbuf,MYF(MY_WME)); } + return 0; +} + + +byte *my_compress_alloc(const byte *packet, ulong *len, ulong *complen) +{ + byte *compbuf; + *complen = *len * 120 / 100 + 12; + if (!(compbuf = (byte *) 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,MYF(MY_WME)); + return 0; + } + if (*complen >= *len) + { + *complen=0; + my_free(compbuf,MYF(MY_WME)); + return 0; + } + swap(ulong,*len,*complen); /* *len is now packet length */ + return compbuf; +} + + +my_bool my_uncompress (byte *packet, ulong *len, ulong *complen) +{ + if (*complen) /* If compressed */ + { + byte *compbuf = (byte *) my_malloc (*complen,MYF(MY_WME)); + if (!compbuf) + return 1; /* Not enough memory */ + if (uncompress((Bytef*) compbuf, complen, (Bytef*) packet, *len) != Z_OK) + { /* Probably wrong packet */ + my_free (compbuf,MYF(MY_WME)); + return 1; + } + *len = *complen; + memcpy(packet,compbuf,*len); + my_free(compbuf,MYF(MY_WME)); + } + return 0; +} +#endif /* HAVE_COMPRESS */ diff --git a/ext/mysql/libmysql/my_config.h b/ext/mysql/libmysql/my_config.h new file mode 100644 index 0000000000..6d6238bf81 --- /dev/null +++ b/ext/mysql/libmysql/my_config.h @@ -0,0 +1,650 @@ +/* config.h. Generated automatically by configure. */ +/* config.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define if using alloca.c. */ +/* #undef C_ALLOCA */ + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. + This function is required for alloca.c support on those systems. */ +/* #undef CRAY_STACKSEG_END */ + +/* Define if you have alloca, as a function or macro. */ +#define HAVE_ALLOCA 1 + +/* Define if you have <alloca.h> and it should be used (not on Ultrix). */ +#define HAVE_ALLOCA_H 1 + +/* Define if you don't have vprintf but do have _doprnt. */ +/* #undef HAVE_DOPRNT */ + +/* Define if you have a working `mmap' system call. */ +#define HAVE_MMAP 1 + +/* Define if system calls automatically restart after interruption + by a signal. */ +/* #undef HAVE_RESTARTABLE_SYSCALLS */ + +/* Define if your struct stat has st_rdev. */ +#define HAVE_ST_RDEV 1 + +/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define if utime(file, NULL) sets file's timestamp to the present. */ +#define HAVE_UTIME_NULL 1 + +/* Define if you have the vprintf function. */ +#define HAVE_VPRINTF 1 + +/* Define as __inline if that's what the C compiler calls it. */ +/* #undef inline */ + +/* Define to `long' if <sys/types.h> doesn't define. */ +/* #undef off_t */ + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define to `unsigned' if <sys/types.h> doesn't define. */ +/* #undef size_t */ + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown + */ +#define STACK_DIRECTION -1 + +/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */ +/* #undef STAT_MACROS_BROKEN */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you can safely include both <sys/time.h> and <time.h>. */ +#define TIME_WITH_SYS_TIME 1 + +/* Define if your <sys/time.h> declares struct tm. */ +/* #undef TM_IN_SYS_TIME */ + +/* Define if your processor stores words with the most significant + byte first (like Motorola and SPARC, unlike Intel and VAX). */ +#define WORDS_BIGENDIAN 1 + +/* Version of .frm files */ +#define DOT_FRM_VERSION 6 + +/* READLINE: */ +/* #undef FIONREAD_IN_SYS_IOCTL */ + +/* READLINE: Define if your system defines TIOCGWINSZ in sys/ioctl.h. */ +/* #undef GWINSZ_IN_SYS_IOCTL */ + +/* Do we have FIONREAD */ +/* #undef FIONREAD_IN_SYS_IOCTL */ + +/* bool is not defined by all C++ compilators */ +#define HAVE_BOOL 1 + +/* DSB style signals ? */ +/* #undef HAVE_BSD_SIGNALS */ + +/* Can netinet be included */ +/* #undef HAVE_BROKEN_NETINET_INCLUDES */ + +/* READLINE: */ +/* #undef HAVE_BSD_SIGNALS */ + +/* Define if we are using OSF1 DEC threads */ +/* #undef HAVE_DEC_THREADS */ + +/* Define if we are using OSF1 DEC threads on 3.2 */ +/* #undef HAVE_DEC_3_2_THREADS */ + +/* fp_except from ieeefp.h */ +#define HAVE_FP_EXCEPT 1 + +/* READLINE: */ +/* #undef HAVE_GETPW_DECLS */ + +/* Solaris define gethostbyname_r with 5 arguments. glibc2 defines + this with 6 arguments */ +/* #undef HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R */ + +/* Define if have -lwrap */ +/* #undef HAVE_LIBWRAP */ + +/* Define if we are using Xavier Leroy's LinuxThreads */ +/* #undef HAVE_LINUXTHREADS */ + +/* Do we use user level threads */ +#define HAVE_mit_thread 1 + +/* For some non posix threads */ +/* #undef HAVE_NONPOSIX_PTHREAD_GETSPECIFIC */ + +/* For some non posix threads */ +/* #undef HAVE_NONPOSIX_PTHREAD_MUTEX_INIT */ + +/* READLINE: */ +#define HAVE_POSIX_SIGNALS 1 + +/* sigwait with one argument */ +/* #undef HAVE_NONPOSIX_SIGWAIT */ + +/* pthread_attr_setscope */ +/* #undef HAVE_PTHREAD_ATTR_SETSCOPE */ + +/* POSIX readdir_r */ +#define HAVE_READDIR_R 1 + +/* POSIX sigwait */ +#define HAVE_SIGWAIT 1 + +/* Solaris define gethostbyaddr_r with 7 arguments. glibc2 defines + this with 8 arguments */ +#define HAVE_SOLARIS_STYLE_GETHOST 1 + +/* MIT pthreads does not support connecting with unix sockets */ +#define HAVE_THREADS_WITHOUT_SOCKETS 1 + +/* Timespec has a ts_sec instead of tv_sev */ +/* #undef HAVE_TIMESPEC_TS_SEC */ + +/* Define if the system files define uchar */ +/* #undef HAVE_UCHAR */ + +/* Define if the system files define uint */ +#define HAVE_UINT 1 + +/* Define if the system files define ulong */ +#define HAVE_ULONG 1 + +/* UNIXWARE7 threads are not posix */ +/* #undef HAVE_UNIXWARE7_THREADS */ + +/* new UNIXWARE7 threads that are not yet posix */ +/* #undef HAVE_UNIXWARE7_POSIX */ + +/* READLINE: */ +/* #undef HAVE_USG_SIGHOLD */ + +/* Define if want -lwrap */ +/* #undef LIBWRAP */ + +/* Define to machine type name eg sun10 */ +#define MACHINE_TYPE "sparc" + +/* Defined to used character set */ +#define MY_CHARSET_CURRENT MY_CHARSET_LATIN1 + +/* mysql client protocoll version */ +#define PROTOCOL_VERSION 10 + +/* Define if qsort returns void */ +#define QSORT_TYPE_IS_VOID 1 + +/* Define as the return type of qsort (int or void). */ +#define RETQSORTTYPE void + +/* Size of off_t */ +#define SIZEOF_OFF_T 4 + +/* Define as the base type of the last arg to accept */ +#define SOCKET_SIZE_TYPE int + +/* Needed to get large file supportat HPUX 10.20 */ +#define __STDC_EXT__ 1 + +/* #undef STRUCT_DIRENT_HAS_D_FILENO */ +#define STRUCT_DIRENT_HAS_D_INO 1 + +/* Define to name of system eg solaris*/ +#define SYSTEM_TYPE "sun-solaris2.5.1" + +/* Define if you want to have threaded code. This may be undef on client code */ +#define THREAD 1 + +/* Should be client be thread safe */ +/* #undef THREAD_SAFE_CLIENT */ + +/* READLINE: */ +/* #undef TIOCSTAT_IN_SYS_IOCTL */ + +/* Use MySQL RAID */ +/* #undef USE_RAID */ + +/* READLINE: */ +#define VOID_SIGHANDLER 1 + +/* The number of bytes in a char. */ +#define SIZEOF_CHAR 1 + +/* The number of bytes in a int. */ +#define SIZEOF_INT 4 + +/* The number of bytes in a long. */ +#define SIZEOF_LONG 4 + +/* The number of bytes in a long long. */ +#define SIZEOF_LONG_LONG 8 + +/* Define if you have the alarm function. */ +#define HAVE_ALARM 1 + +/* Define if you have the atod function. */ +/* #undef HAVE_ATOD */ + +/* Define if you have the bcmp function. */ +#define HAVE_BCMP 1 + +/* Define if you have the bfill function. */ +/* #undef HAVE_BFILL */ + +/* Define if you have the bmove function. */ +/* #undef HAVE_BMOVE */ + +/* Define if you have the bzero function. */ +#define HAVE_BZERO 1 + +/* Define if you have the chsize function. */ +/* #undef HAVE_CHSIZE */ + +/* Define if you have the crypt function. */ +#define HAVE_CRYPT 1 + +/* Define if you have the cuserid function. */ +#define HAVE_CUSERID 1 + +/* Define if you have the dlerror function. */ +#define HAVE_DLERROR 1 + +/* Define if you have the dlopen function. */ +#define HAVE_DLOPEN 1 + +/* Define if you have the fchmod function. */ +#define HAVE_FCHMOD 1 + +/* Define if you have the fcntl function. */ +#define HAVE_FCNTL 1 + +/* Define if you have the fconvert function. */ +#define HAVE_FCONVERT 1 + +/* Define if you have the finite function. */ +#define HAVE_FINITE 1 + +/* Define if you have the fpresetsticky function. */ +/* #undef HAVE_FPRESETSTICKY */ + +/* Define if you have the fpsetmask function. */ +#define HAVE_FPSETMASK 1 + +/* Define if you have the fseeko function. */ +/* #undef HAVE_FSEEKO */ + +/* Define if you have the ftruncate function. */ +#define HAVE_FTRUNCATE 1 + +/* Define if you have the getcwd function. */ +#define HAVE_GETCWD 1 + +/* Define if you have the gethostbyaddr_r function. */ +#define HAVE_GETHOSTBYADDR_R 1 + +/* Define if you have the gethostbyname_r function. */ +#define HAVE_GETHOSTBYNAME_R 1 + +/* Define if you have the getpagesize function. */ +#define HAVE_GETPAGESIZE 1 + +/* Define if you have the getpass function. */ +#define HAVE_GETPASS 1 + +/* Define if you have the getpassphrase function. */ +/* #undef HAVE_GETPASSPHRASE */ + +/* Define if you have the getpwnam function. */ +#define HAVE_GETPWNAM 1 + +/* Define if you have the getpwuid function. */ +#define HAVE_GETPWUID 1 + +/* Define if you have the getrlimit function. */ +#define HAVE_GETRLIMIT 1 + +/* Define if you have the getrusage function. */ +#define HAVE_GETRUSAGE 1 + +/* Define if you have the getwd function. */ +#define HAVE_GETWD 1 + +/* Define if you have the index function. */ +#define HAVE_INDEX 1 + +/* Define if you have the localtime_r function. */ +#define HAVE_LOCALTIME_R 1 + +/* Define if you have the locking function. */ +/* #undef HAVE_LOCKING */ + +/* Define if you have the longjmp function. */ +#define HAVE_LONGJMP 1 + +/* Define if you have the lrand48 function. */ +#define HAVE_LRAND48 1 + +/* Define if you have the lstat function. */ +#define HAVE_LSTAT 1 + +/* Define if you have the madvise function. */ +#define HAVE_MADVISE 1 + +/* Define if you have the memcpy function. */ +#define HAVE_MEMCPY 1 + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE 1 + +/* Define if you have the perror function. */ +#define HAVE_PERROR 1 + +/* Define if you have the pread function. */ +#define HAVE_PREAD 1 + +/* Define if you have the pthread_attr_create function. */ +/* #undef HAVE_PTHREAD_ATTR_CREATE */ + +/* Define if you have the pthread_attr_setprio function. */ +/* #undef HAVE_PTHREAD_ATTR_SETPRIO */ + +/* Define if you have the pthread_attr_setschedparam function. */ +/* #undef HAVE_PTHREAD_ATTR_SETSCHEDPARAM */ + +/* Define if you have the pthread_attr_setstacksize function. */ +/* #undef HAVE_PTHREAD_ATTR_SETSTACKSIZE */ + +/* Define if you have the pthread_condattr_create function. */ +/* #undef HAVE_PTHREAD_CONDATTR_CREATE */ + +/* Define if you have the pthread_getsequence_np function. */ +/* #undef HAVE_PTHREAD_GETSEQUENCE_NP */ + +/* Define if you have the pthread_init function. */ +/* #undef HAVE_PTHREAD_INIT */ + +/* Define if you have the pthread_setprio function. */ +/* #undef HAVE_PTHREAD_SETPRIO */ + +/* Define if you have the pthread_setprio_np function. */ +/* #undef HAVE_PTHREAD_SETPRIO_NP */ + +/* Define if you have the pthread_setschedparam function. */ +/* #undef HAVE_PTHREAD_SETSCHEDPARAM */ + +/* Define if you have the pthread_sigmask function. */ +/* #undef HAVE_PTHREAD_SIGMASK */ + +/* Define if you have the putenv function. */ +#define HAVE_PUTENV 1 + +/* Define if you have the realpath function. */ +#define HAVE_REALPATH 1 + +/* Define if you have the rename function. */ +#define HAVE_RENAME 1 + +/* Define if you have the rint function. */ +#define HAVE_RINT 1 + +/* Define if you have the rwlock_init function. */ +#define HAVE_RWLOCK_INIT 1 + +/* Define if you have the select function. */ +#define HAVE_SELECT 1 + +/* Define if you have the setenv function. */ +/* #undef HAVE_SETENV */ + +/* Define if you have the setlocale function. */ +#define HAVE_SETLOCALE 1 + +/* Define if you have the setupterm function. */ +/* #undef HAVE_SETUPTERM */ + +/* Define if you have the sighold function. */ +#define HAVE_SIGHOLD 1 + +/* Define if you have the sigset function. */ +#define HAVE_SIGSET 1 + +/* Define if you have the sigthreadmask function. */ +/* #undef HAVE_SIGTHREADMASK */ + +/* Define if you have the snprintf function. */ +/* #undef HAVE_SNPRINTF */ + +/* Define if you have the socket function. */ +#define HAVE_SOCKET 1 + +/* Define if you have the strcasecmp function. */ +#define HAVE_STRCASECMP 1 + +/* Define if you have the strcoll function. */ +#define HAVE_STRCOLL 1 + +/* Define if you have the strerror function. */ +#define HAVE_STRERROR 1 + +/* Define if you have the strnlen function. */ +/* #undef HAVE_STRNLEN */ + +/* Define if you have the strpbrk function. */ +#define HAVE_STRPBRK 1 + +/* Define if you have the strstr function. */ +#define HAVE_STRSTR 1 + +/* Define if you have the strtok_r function. */ +#define HAVE_STRTOK_R 1 + +/* Define if you have the strtoul function. */ +#define HAVE_STRTOUL 1 + +/* Define if you have the strtoull function. */ +#define HAVE_STRTOULL 1 + +/* Define if you have the tcgetattr function. */ +#define HAVE_TCGETATTR 1 + +/* Define if you have the tell function. */ +#define HAVE_TELL 1 + +/* Define if you have the tempnam function. */ +#define HAVE_TEMPNAM 1 + +/* Define if you have the thr_setconcurrency function. */ +#define HAVE_THR_SETCONCURRENCY 1 + +/* Define if you have the vidattr function. */ +/* #undef HAVE_VIDATTR */ + +/* Define if you have the <alloca.h> header file. */ +#define HAVE_ALLOCA_H 1 + +/* Define if you have the <asm/termbits.h> header file. */ +/* #undef HAVE_ASM_TERMBITS_H */ + +/* Define if you have the <crypt.h> header file. */ +#define HAVE_CRYPT_H 1 + +/* Define if you have the <curses.h> header file. */ +#define HAVE_CURSES_H 1 + +/* Define if you have the <dirent.h> header file. */ +#define HAVE_DIRENT_H 1 + +/* Define if you have the <fcntl.h> header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the <float.h> header file. */ +#define HAVE_FLOAT_H 1 + +/* Define if you have the <floatingpoint.h> header file. */ +#define HAVE_FLOATINGPOINT_H 1 + +/* Define if you have the <ieeefp.h> header file. */ +#define HAVE_IEEEFP_H 1 + +/* Define if you have the <limits.h> header file. */ +#define HAVE_LIMITS_H 1 + +/* Define if you have the <locale.h> header file. */ +#define HAVE_LOCALE_H 1 + +/* Define if you have the <memory.h> header file. */ +#define HAVE_MEMORY_H 1 + +/* Define if you have the <ndir.h> header file. */ +/* #undef HAVE_NDIR_H */ + +/* Define if you have the <pwd.h> header file. */ +#define HAVE_PWD_H 1 + +/* Define if you have the <sched.h> header file. */ +#define HAVE_SCHED_H 1 + +/* Define if you have the <select.h> header file. */ +/* #undef HAVE_SELECT_H */ + +/* Define if you have the <stdarg.h> header file. */ +#define HAVE_STDARG_H 1 + +/* Define if you have the <stddef.h> header file. */ +#define HAVE_STDDEF_H 1 + +/* Define if you have the <stdlib.h> header file. */ +#define HAVE_STDLIB_H 1 + +/* Define if you have the <string.h> header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the <strings.h> header file. */ +#define HAVE_STRINGS_H 1 + +/* Define if you have the <synch.h> header file. */ +#define HAVE_SYNCH_H 1 + +/* Define if you have the <sys/dir.h> header file. */ +/* #undef HAVE_SYS_DIR_H */ + +/* Define if you have the <sys/file.h> header file. */ +#define HAVE_SYS_FILE_H 1 + +/* Define if you have the <sys/mman.h> header file. */ +#define HAVE_SYS_MMAN_H 1 + +/* Define if you have the <sys/ndir.h> header file. */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define if you have the <sys/pte.h> header file. */ +/* #undef HAVE_SYS_PTE_H */ + +/* Define if you have the <sys/ptem.h> header file. */ +#define HAVE_SYS_PTEM_H 1 + +/* Define if you have the <sys/select.h> header file. */ +#define HAVE_SYS_SELECT_H 1 + +/* Define if you have the <sys/socket.h> header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define if you have the <sys/stream.h> header file. */ +#define HAVE_SYS_STREAM_H 1 + +/* Define if you have the <sys/timeb.h> header file. */ +#define HAVE_SYS_TIMEB_H 1 + +/* Define if you have the <sys/types.h> header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define if you have the <sys/un.h> header file. */ +#define HAVE_SYS_UN_H 1 + +/* Define if you have the <sys/utime.h> header file. */ +#define HAVE_SYS_UTIME_H 1 + +/* Define if you have the <sys/vadvise.h> header file. */ +/* #undef HAVE_SYS_VADVISE_H */ + +/* Define if you have the <sys/wait.h> header file. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define if you have the <term.h> header file. */ +#define HAVE_TERM_H 1 + +/* Define if you have the <termbits.h> header file. */ +/* #undef HAVE_TERMBITS_H */ + +/* Define if you have the <termcap.h> header file. */ +/* #undef HAVE_TERMCAP_H */ + +/* Define if you have the <termio.h> header file. */ +#define HAVE_TERMIO_H 1 + +/* Define if you have the <termios.h> header file. */ +#define HAVE_TERMIOS_H 1 + +/* Define if you have the <unistd.h> header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the <utime.h> header file. */ +#define HAVE_UTIME_H 1 + +/* Define if you have the <varargs.h> header file. */ +#define HAVE_VARARGS_H 1 + +/* Define if you have the bind library (-lbind). */ +/* #undef HAVE_LIBBIND */ + +/* Define if you have the c_r library (-lc_r). */ +/* #undef HAVE_LIBC_R */ + +/* Define if you have the compat library (-lcompat). */ +/* #undef HAVE_LIBCOMPAT */ + +/* Define if you have the crypt library (-lcrypt). */ +#define HAVE_LIBCRYPT 1 + +/* Define if you have the dl library (-ldl). */ +#define HAVE_LIBDL 1 + +/* Define if you have the gen library (-lgen). */ +#define HAVE_LIBGEN 1 + +/* Define if you have the m library (-lm). */ +#define HAVE_LIBM 1 + +/* Define if you have the nsl library (-lnsl). */ +#define HAVE_LIBNSL 1 + +/* Define if you have the nsl_r library (-lnsl_r). */ +/* #undef HAVE_LIBNSL_R */ + +/* Define if you have the pthread library (-lpthread). */ +#define HAVE_LIBPTHREAD 1 + +/* Define if you have the socket library (-lsocket). */ +#define HAVE_LIBSOCKET 1 + +/* Name of package */ +#define PACKAGE "mysql" + +/* Version number of package */ +#define VERSION "3.23.10-alpha" + diff --git a/ext/mysql/libmysql/my_create.c b/ext/mysql/libmysql/my_create.c new file mode 100644 index 0000000000..d227140b09 --- /dev/null +++ b/ext/mysql/libmysql/my_create.c @@ -0,0 +1,66 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +#define USES_TYPES +#include "mysys_priv.h" +#include <my_dir.h> +#include "mysys_err.h" +#include <errno.h> +#if defined(MSDOS) || defined(__WIN32__) +#include <share.h> +#endif + + /* + ** Create a new file + ** Arguments: + ** Path-name of file + ** Read | write on file (umask value) + ** Read & Write on open file + ** Special flags + */ + + +File my_create(const char *FileName, int CreateFlags, int access_flags, + myf MyFlags) +{ + int fd; + DBUG_ENTER("my_create"); + DBUG_PRINT("my",("Name: '%s' CreateFlags: %d AccessFlags: %d MyFlags: %d", + FileName, CreateFlags, access_flags, MyFlags)); + +#if !defined(NO_OPEN_3) + fd = open((my_string) FileName, access_flags | O_CREAT, + CreateFlags ? CreateFlags : my_umask); +#elif defined(VMS) + fd = open((my_string) FileName, access_flags | O_CREAT, 0, + "ctx=stm","ctx=bin"); +#elif defined(MSDOS) || defined(__WIN32__) + if (access_flags & O_SHARE) + fd = sopen((my_string) FileName, access_flags | O_CREAT | O_BINARY, + SH_DENYNO, MY_S_IREAD | MY_S_IWRITE); + else + fd = open((my_string) FileName, access_flags | O_CREAT | O_BINARY, + MY_S_IREAD | MY_S_IWRITE); +#else + fd = open(FileName, access_flags); +#endif + + if (fd >= 0) + { + if ((int) fd >= MY_NFILE) + DBUG_RETURN(fd); /* safeguard */ + if ((my_file_info[fd].name = (char*) my_strdup(FileName,MyFlags))) + { + my_file_opened++; + my_file_info[fd].type = FILE_BY_CREATE; + DBUG_RETURN(fd); + } + VOID(my_close(fd,MyFlags)); + my_errno=ENOMEM; + } + else + my_errno=errno; + if (MyFlags & (MY_FFNF | MY_FAE | MY_WME)) + my_error(EE_CANTCREATEFILE, MYF(ME_BELL+ME_WAITTANG), FileName,my_errno); + DBUG_RETURN(-1); +} /* my_create */ diff --git a/ext/mysql/libmysql/my_delete.c b/ext/mysql/libmysql/my_delete.c new file mode 100644 index 0000000000..b29631b90a --- /dev/null +++ b/ext/mysql/libmysql/my_delete.c @@ -0,0 +1,22 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +#include "mysys_priv.h" + +#include "mysys_err.h" + +int my_delete(const char *name, myf MyFlags) +{ + int err; + DBUG_ENTER("my_delete"); + DBUG_PRINT("my",("name %s MyFlags %d", name, MyFlags)); + + if ((err = unlink(name)) == -1) + { + my_errno=errno; + if (MyFlags & (MY_FAE+MY_WME)) + my_error(EE_DELETE,MYF(ME_BELL+ME_WAITTANG+(MyFlags & ME_NOINPUT)), + name,errno); + } + DBUG_RETURN(err); +} /* my_delete */ diff --git a/ext/mysql/libmysql/my_dir.h b/ext/mysql/libmysql/my_dir.h new file mode 100644 index 0000000000..0fdd5a148e --- /dev/null +++ b/ext/mysql/libmysql/my_dir.h @@ -0,0 +1,85 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +#ifndef _my_dir_h +#define _my_dir_h +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef MY_DIR_H +#define MY_DIR_H + +#include <sys/stat.h> + + /* Defines for my_dir and my_stat */ + +#define MY_S_IFMT S_IFMT /* type of file */ +#define MY_S_IFDIR S_IFDIR /* directory */ +#define MY_S_IFCHR S_IFCHR /* character special */ +#define MY_S_IFBLK S_IFBLK /* block special */ +#define MY_S_IFREG S_IFREG /* regular */ +#define MY_S_IFIFO S_IFIFO /* fifo */ +#define MY_S_ISUID S_ISUID /* set user id on execution */ +#define MY_S_ISGID S_ISGID /* set group id on execution */ +#define MY_S_ISVTX S_ISVTX /* save swapped text even after use */ +#define MY_S_IREAD S_IREAD /* read permission, owner */ +#define MY_S_IWRITE S_IWRITE /* write permission, owner */ +#define MY_S_IEXEC S_IEXEC /* execute/search permission, owner */ + +#define MY_S_ISDIR(m) (((m) & MY_S_IFMT) == MY_S_IFDIR) +#define MY_S_ISCHR(m) (((m) & MY_S_IFMT) == MY_S_IFCHR) +#define MY_S_ISBLK(m) (((m) & MY_S_IFMT) == MY_S_IFBLK) +#define MY_S_ISREG(m) (((m) & MY_S_IFMT) == MY_S_IFREG) +#define MY_S_ISFIFO(m) (((m) & MY_S_IFMT) == MY_S_IFIFO) + +#define MY_DONT_SORT 512 /* my_lib; Don't sort files */ +#define MY_WANT_STAT 1024 /* my_lib; stat files */ + + /* typedefs for my_dir & my_stat */ + +#ifdef USE_MY_STAT_STRUCT + +typedef struct my_stat +{ + dev_t st_dev; /* major & minor device numbers */ + ino_t st_ino; /* inode number */ + ushort st_mode; /* file permissons (& suid sgid .. bits) */ + short st_nlink; /* number of links to file */ + ushort st_uid; /* user id */ + ushort st_gid; /* group id */ + dev_t st_rdev; /* more major & minor device numbers (???) */ + off_t st_size; /* size of file */ + time_t st_atime; /* time for last read */ + time_t st_mtime; /* time for last contens modify */ + time_t st_ctime; /* time for last inode or contents modify */ +} MY_STAT; + +#else + +#define MY_STAT struct stat /* Orginal struct have what we need */ + +#endif /* USE_MY_STAT_STRUCT */ + +typedef struct fileinfo /* Struct returned from my_dir & my_stat */ +{ + char *name; + MY_STAT mystat; +} FILEINFO; + +typedef struct st_my_dir /* Struct returned from my_dir */ +{ + struct fileinfo *dir_entry; + uint number_off_files; +} MY_DIR; + +extern MY_DIR *my_dir(const char *path,myf MyFlags); +extern void my_dirend(MY_DIR *buffer); +extern MY_STAT *my_stat(const char *path, MY_STAT *stat_area, myf my_flags); + +#endif /* MY_DIR_H */ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ext/mysql/libmysql/my_div.c b/ext/mysql/libmysql/my_div.c new file mode 100644 index 0000000000..9650b28136 --- /dev/null +++ b/ext/mysql/libmysql/my_div.c @@ -0,0 +1,17 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +#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 */ +} diff --git a/ext/mysql/libmysql/my_error.c b/ext/mysql/libmysql/my_error.c new file mode 100644 index 0000000000..aeef85dbd4 --- /dev/null +++ b/ext/mysql/libmysql/my_error.c @@ -0,0 +1,105 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +#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 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 && errmsg[GLOB] == 0) + init_glob_errs(); + + olen=(uint) strlen(tpos=errmsg[nr / ERRMOD][nr % ERRMOD]); + endpos=ebuff; + + while (*tpos) + { + if (tpos[0] != '%') + { + *endpos++= *tpos++; /* Copy ordinary char */ + 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 == '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); + plen= (uint) (int2str((long) iarg,endpos,*tpos == 'd' ? -10 : 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); +} diff --git a/ext/mysql/libmysql/my_fopen.c b/ext/mysql/libmysql/my_fopen.c new file mode 100644 index 0000000000..f22f492b4f --- /dev/null +++ b/ext/mysql/libmysql/my_fopen.c @@ -0,0 +1,150 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +#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); + if ((fd = fopen(FileName, type)) != 0) + { + /* + 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) + 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 ? 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); + } + if ((uint) file < MY_NFILE && my_file_info[file].type != UNOPEN) + { + my_file_info[file].type = UNOPEN; + my_free(my_file_info[file].name, MYF(0)); + my_stream_opened--; + } + pthread_mutex_unlock(&THR_LOCK_open); + DBUG_RETURN(err); +} /* my_fclose */ + + + /* Make a stream out of a file handle */ + +FILE *my_fdopen(File Filedes, int Flags, myf MyFlags) + + /* Read | write .. */ + /* Special flags */ +{ + 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); + if (my_file_info[Filedes].type != UNOPEN) + { + my_file_info[Filedes].type = STREAM_BY_FDOPEN; + my_file_opened--; /* File is opened with my_open ! */ + my_stream_opened++; + } + 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 */ diff --git a/ext/mysql/libmysql/my_getwd.c b/ext/mysql/libmysql/my_getwd.c new file mode 100644 index 0000000000..0267a3eaa6 --- /dev/null +++ b/ext/mysql/libmysql/my_getwd.c @@ -0,0 +1,168 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* 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 + + + /* 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) + if (!getcwd(buf,size-2) && MyFlags & MY_WME) + { + 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) + 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) /* MSDOS chdir can't change drive */ +#if !defined(_DDL) && !defined(WIN32) + if ((pos=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) + { + _dos_setdrive(drive,&drives); + _dos_getdrive(&drives); + } + 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 */ + if ((res=chdir((char*) dir)) != 0) + { + 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 */ diff --git a/ext/mysql/libmysql/my_init.c b/ext/mysql/libmysql/my_init.c new file mode 100644 index 0000000000..db45d991d3 --- /dev/null +++ b/ext/mysql/libmysql/my_init.c @@ -0,0 +1,282 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +#include "mysys_priv.h" +#include "my_static.h" +#include "mysys_err.h" +#include <m_string.h> +#ifdef THREAD +#include <my_pthread.h> +#endif +#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 +static my_bool my_init_done=0; + + /* 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 + { + DBUG_ENTER("my_init"); + DBUG_PROCESS(my_progname ? my_progname : (char*) "unknown"); + if (!home_dir) + { /* Don't initialize twice */ + my_win_init(); + if ((home_dir=getenv("HOME")) != 0) + home_dir=intern_filename(home_dir_buff,home_dir); +#ifndef VMS + if ((str=getenv("UMASK")) != 0) + my_umask=atoi(str) | 0600; /* Default creation of new files */ +#endif +#ifdef VMS + init_ctype(); /* Stupid linker don't link _ctype.c */ +#endif + DBUG_PRINT("exit",("home: '%s'",home_dir)); + } +#ifdef __WIN32__ + win32_init_tcp_ip(); +#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,"\nUser time %.2f, System time %.2f\nMaximum resident set size %d, Integral resident set size %d\nNon physical pagefaults %d, Physical pagefaults %d, Swaps %d\nBlocks in %d out %d, Messages in %d out %d, Signals %d\nVouluntary context switches %d, Invouluntary context switches %d\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_keycache); + pthread_mutex_destroy(&THR_LOCK_malloc); + pthread_mutex_destroy(&THR_LOCK_open); + DBUG_POP(); /* Must be done before my_thread_end */ + my_thread_end(); + my_thread_global_end(); +#endif +#ifdef __WIN32__ + if (have_tcpip); + WSACleanup( ); +#endif /* __WIN32__ */ +} /* 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) +{ + HKEY hSoftMysql ; + DWORD dimName = 256 ; + DWORD dimData = 1024 ; + DWORD dimNameValueBuffer = 256 ; + DWORD dimDataValueBuffer = 1024 ; + DWORD indexValue = 0 ; + long retCodeEnumValue ; + char NameValueBuffer[256] ; + char DataValueBuffer[1024] ; + char EnvString[1271] ; + const char *targetKey = "Software\\MySQL" ; + DBUG_ENTER("my_win_init"); + + setlocale(LC_CTYPE, ""); /* To get right sortorder */ + + /* apre la chiave HKEY_LOCAL_MACHINES\software\MySQL */ + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,(LPCTSTR)targetKey,0, + KEY_READ,&hSoftMysql) != ERROR_SUCCESS) + DBUG_VOID_RETURN; + + /* + ** Ne legge i valori e li inserisce nell'ambiente + ** suppone che tutti i valori letti siano di tipo stringa + '\0' + ** Legge il valore con indice 0 e lo scarta + */ + retCodeEnumValue = RegEnumValue(hSoftMysql, indexValue++, + (LPTSTR)NameValueBuffer, &dimNameValueBuffer, + NULL, NULL, (LPBYTE)DataValueBuffer, + &dimDataValueBuffer) ; + + while (retCodeEnumValue != ERROR_NO_MORE_ITEMS) + { + char *my_env; + /* Crea la stringa d'ambiente */ + setEnvString(EnvString, NameValueBuffer, DataValueBuffer) ; + + /* Inserisce i dati come variabili d'ambiente */ + my_env=strdup(EnvString); /* variable for putenv must be allocated ! */ + putenv(EnvString) ; + + dimNameValueBuffer = dimName ; + dimDataValueBuffer = dimData ; + + retCodeEnumValue = RegEnumValue(hSoftMysql, indexValue++, + NameValueBuffer, &dimNameValueBuffer, + NULL, NULL, (LPBYTE)DataValueBuffer, + &dimDataValueBuffer) ; + } + + /* chiude la chiave */ + RegCloseKey(hSoftMysql) ; + 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 diff --git a/ext/mysql/libmysql/my_list.h b/ext/mysql/libmysql/my_list.h new file mode 100644 index 0000000000..d5a28ac139 --- /dev/null +++ b/ext/mysql/libmysql/my_list.h @@ -0,0 +1,33 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +#ifndef _list_h_ +#define _list_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct st_list { + struct st_list *prev,*next; + void *data; +} LIST; + +typedef int (*list_walk_action)(void *,void *); + +extern LIST *list_add(LIST *root,LIST *element); +extern LIST *list_delete(LIST *root,LIST *element); +extern LIST *list_cons(void *data,LIST *root); +extern LIST *list_reverse(LIST *root); +extern void list_free(LIST *root,pbool free_data); +extern uint list_length(LIST *list); +extern int list_walk(LIST *list,list_walk_action action,gptr argument); + +#define rest(a) ((a)->next) +#define list_push(a,b) (a)=list_cons((b),(a)) +#define list_pop(A) {LIST *old=(A); (A)=list_delete(old,old) ; my_free((gptr) old,MYF(MY_FAE)); } + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ext/mysql/libmysql/my_malloc.c b/ext/mysql/libmysql/my_malloc.c new file mode 100644 index 0000000000..ca44ae4f64 --- /dev/null +++ b/ext/mysql/libmysql/my_malloc.c @@ -0,0 +1,70 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +#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(unsigned int 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 = 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(gptr 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 byte *from, uint length, myf MyFlags) +{ + gptr ptr; + if ((ptr=my_malloc(length,MyFlags)) != 0) + memcpy((byte*) ptr, (byte*) from,(size_t) length); + return(ptr); +} + + +my_string my_strdup(const char *from, myf MyFlags) +{ + gptr ptr; + uint length=(uint) strlen(from)+1; + if ((ptr=my_malloc(length,MyFlags)) != 0) + memcpy((byte*) ptr, (byte*) from,(size_t) length); + return((my_string) ptr); +} diff --git a/ext/mysql/libmysql/my_messnc.c b/ext/mysql/libmysql/my_messnc.c new file mode 100644 index 0000000000..96d90af343 --- /dev/null +++ b/ext/mysql/libmysql/my_messnc.c @@ -0,0 +1,22 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +#include "mysys_priv.h" + +int my_message_no_curses(uint my_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); +} diff --git a/ext/mysql/libmysql/my_net.c b/ext/mysql/libmysql/my_net.c new file mode 100644 index 0000000000..9fb47c50f9 --- /dev/null +++ b/ext/mysql/libmysql/my_net.c @@ -0,0 +1,29 @@ +/* Copyright Abandoned 2000 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* 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> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#endif + +#ifndef THREAD +#define pthread_mutex_lock(A) +#define pthread_mutex_unlock(A) +#endif + +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); +} diff --git a/ext/mysql/libmysql/my_net.h b/ext/mysql/libmysql/my_net.h new file mode 100644 index 0000000000..ac4af6595b --- /dev/null +++ b/ext/mysql/libmysql/my_net.h @@ -0,0 +1,10 @@ +/* thread safe version of some common functions */ + +/* for thread safe my_inet_ntoa */ +#if !defined(MSDOS) && !defined(__WIN32__) +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#endif + +void my_inet_ntoa(struct in_addr in, char *buf); diff --git a/ext/mysql/libmysql/my_once.c b/ext/mysql/libmysql/my_once.c new file mode 100644 index 0000000000..b03f4df529 --- /dev/null +++ b/ext/mysql/libmysql/my_once.c @@ -0,0 +1,74 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* 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) +{ + uint 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 */ diff --git a/ext/mysql/libmysql/my_open.c b/ext/mysql/libmysql/my_open.c new file mode 100644 index 0000000000..10ddb95388 --- /dev/null +++ b/ext/mysql/libmysql/my_open.c @@ -0,0 +1,83 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +#define USES_TYPES +#include "mysys_priv.h" +#include "mysys_err.h" +#include <errno.h> +#if defined(MSDOS) || defined(__WIN32__) +#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__) + if (Flags & O_SHARE) + fd = sopen((my_string) FileName, (Flags & ~O_SHARE) | O_BINARY, SH_DENYNO); + else + fd = open((my_string) FileName, Flags | O_BINARY); +#elif !defined(NO_OPEN_3) + fd = open(FileName, Flags, 0); /* Normal unix */ +#else + fd = open((my_string) FileName, Flags); +#endif + + if ((int) fd >= 0) + { + if ((int) fd >= MY_NFILE) + DBUG_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 = FILE_BY_OPEN; + pthread_mutex_unlock(&THR_LOCK_open); + DBUG_PRINT("exit",("fd: %d",fd)); + DBUG_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(EE_FILENOTFOUND, MYF(ME_BELL+ME_WAITTANG), FileName,my_errno); + DBUG_RETURN(fd); +} /* 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)) != 0) + { + my_errno=errno; + if (MyFlags & (MY_FAE | MY_WME)) + my_error(EE_BADCLOSE, MYF(ME_BELL+ME_WAITTANG),my_filename(fd),errno); + } + if (fd < MY_NFILE && my_file_info[fd].type != UNOPEN) + { + my_file_opened--; + my_free(my_file_info[fd].name, MYF(0)); + my_file_info[fd].type = UNOPEN; + } + pthread_mutex_unlock(&THR_LOCK_open); + DBUG_RETURN(err); +} /* my_close */ diff --git a/ext/mysql/libmysql/my_pthread.c b/ext/mysql/libmysql/my_pthread.c new file mode 100644 index 0000000000..2110437a16 --- /dev/null +++ b/ext/mysql/libmysql/my_pthread.c @@ -0,0 +1,462 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* Functions to get threads more portable */ + +#include "mysys_priv.h" +#ifdef THREAD +#include <signal.h> +#include <m_string.h> +#include <thr_alarm.h> +#include <assert.h> +#if !defined(MSDOS) && !defined(__WIN32__) +#include <netdb.h> +#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(sigset_t *set,int *sig) +{ + int signal=sigwait(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); + memcpy(res,tmp,sizeof(*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) + +#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(&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(&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(&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,NULL); + pthread_cond_init(&COND_sigwait,NULL); + + pthread_attr_init(&thr_attr); + pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_SYSTEM); + 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 + +/***************************************************************************** +** 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) +#undef pthread_mutex_init +#undef pthread_cond_init + +#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 + +/* +** Emulate SOLARIS style calls, not because it's better, but just to make the +** usage of getbostbyname_r simpler. +*/ + +#if !defined(my_gethostbyname_r) && defined(HAVE_GETHOSTBYNAME_R) + +#if defined(HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R) + +struct hostent *my_gethostbyname_r(const char *name, + struct hostent *result, char *buffer, + int buflen, int *h_errnop) +{ + struct hostent *hp; + assert((size_t) buflen >= sizeof(*result)); + if (gethostbyname_r(name,result, buffer, (size_t) buflen, &hp, h_errnop)) + return 0; + return hp; +} + +#elif defined(_HPUX_SOURCE) || (defined(_AIX) && !defined(_AIX32_THREADS)) + +struct hostent *my_gethostbyname_r(const char *name, + struct hostent *result, char *buffer, + int buflen, int *h_errnop) +{ + assert(buflen >= sizeof(struct hostent_data)); + if (gethostbyname_r(name,result,(struct hostent_data *) buffer) == -1) + { + *h_errnop= errno; + return 0; + } + return result; +} + +#else + +struct hostent *my_gethostbyname_r(const char *name, + struct hostent *result, char *buffer, + int buflen, int *h_errnop) +{ + struct hostent *hp; + assert(buflen >= sizeof(struct hostent_data)); + hp= gethostbyname_r(name,result,(struct hostent_data *) buffer); + *h_errnop= errno; + return hp; +} + +#endif /* GLIBC2_STYLE_GETHOSTBYNAME_R */ +#endif + + +/* Some help functions */ + +int pthread_no_free(void *not_used __attribute__((unused))) +{ + return 0; +} + +int pthread_dummy(int ret) +{ + return ret; +} +#endif /* THREAD */ diff --git a/ext/mysql/libmysql/my_pthread.h b/ext/mysql/libmysql/my_pthread.h new file mode 100644 index 0000000000..47a058a65c --- /dev/null +++ b/ext/mysql/libmysql/my_pthread.h @@ -0,0 +1,494 @@ +/* Copyright Abandoned 1999 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* Defines to make different thread packages compatible */ + +#ifndef _my_pthread_h +#define _my_pthread_h + +#include <errno.h> +#ifndef ETIME +#define ETIME ETIMEDOUT // For FreeBSD +#endif + +#if defined(__WIN32__) + +typedef CRITICAL_SECTION pthread_mutex_t; +typedef HANDLE pthread_t; +typedef struct thread_attr { + DWORD dwStackSize ; + DWORD dwCreatingFlag ; + int priority ; +} pthread_attr_t ; + +typedef struct { int dummy; } pthread_condattr_t; + +/* Implementation of posix conditions */ + +typedef struct st_pthread_link { + DWORD thread_id; + struct st_pthread_link *next; +} pthread_link; + +typedef struct { + uint32 waiting; + HANDLE semaphore; +} pthread_cond_t; + + +struct timespec { /* For pthread_cond_timedwait() */ + time_t tv_sec; + long tv_nsec; +}; + +#define win_pthread_self my_thread_var->pthread_self +#define pthread_handler_decl(A,B) unsigned __cdecl A(void *B) +typedef unsigned (__cdecl *pthread_handler)(void *); + +int win_pthread_setspecific(void *A,void *B,uint length); +int pthread_create(pthread_t *,pthread_attr_t *,pthread_handler,void *); +int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr); +int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); +int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, + struct timespec *abstime); +int pthread_cond_signal(pthread_cond_t *cond); +int pthread_cond_broadcast(pthread_cond_t *cond); +int pthread_cond_destroy(pthread_cond_t *cond); +int pthread_attr_init(pthread_attr_t *connect_att); +int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack); +int pthread_attr_setprio(pthread_attr_t *connect_att,int priority); +int pthread_attr_destroy(pthread_attr_t *connect_att); +struct tm *localtime_r(const time_t *timep,struct tm *tmp); + +void pthread_exit(unsigned A); /* was #define pthread_exit(A) ExitThread(A)*/ + +#define ETIMEDOUT 145 /* Win32 doesn't have this */ +#define getpid() GetCurrentThreadId() +#define pthread_self() win_pthread_self +#define HAVE_LOCALTIME_R +#define _REENTRANT +#define HAVE_PTHREAD_ATTR_SETSTACKSIZE + +#ifdef USE_TLS /* For LIBMYSQL.DLL */ +#define pthread_key(T,V) DWORD V +#define pthread_key_create(A,B) ((*A=TlsAlloc())==0xFFFFFFFF) +#define pthread_getspecific(A) (TlsGetValue(A)) +#define my_pthread_getspecific(T,A) ((T) TlsGetValue(A)) +#define my_pthread_getspecific_ptr(T,V) ((T) TlsGetValue(A)) +#define my_pthread_setspecific_ptr(T,V) TlsSetValue(T,V) +#define pthread_setspecific(A,B) TlsSetValue(A,B) +#else +#define pthread_key(T,V) __declspec(thread) T V +#define pthread_key_create(A,B) pthread_dummy(0) +#define pthread_getspecific(A) (&(A)) +#define my_pthread_getspecific(T,A) (&(A)) +#define my_pthread_getspecific_ptr(T,V) (V) +#define my_pthread_setspecific_ptr(T,V) ((T)=(V),0) +#define pthread_setspecific(A,B) win_pthread_setspecific(&(A),(B),sizeof(A)) +#endif /* USE_TLS */ + +#define pthread_equal(A,B) ((A) == (B)) +#define pthread_mutex_init(A,B) InitializeCriticalSection(A) +#define pthread_mutex_lock(A) (EnterCriticalSection(A),0) +#define pthread_mutex_unlock(A) LeaveCriticalSection(A) +#define pthread_mutex_destroy(A) DeleteCriticalSection(A) +#define my_pthread_setprio(A,B) SetThreadPriority(GetCurrentThread(), (B)) +/* Dummy defines for easier code */ +#define pthread_kill(A,B) pthread_dummy(0) +#define pthread_attr_setdetachstate(A,B) pthread_dummy(0) +#define my_pthread_attr_setprio(A,B) pthread_attr_setprio(A,B) +#define pthread_attr_setscope(A,B) +#define pthread_detach_this_thread() +#define pthread_condattr_init(A) +#define pthread_condattr_destroy(A) + +//Irena: compiler does not like this: +//#define my_pthread_getprio(pthread_t thread_id) pthread_dummy(0) +#define my_pthread_getprio(thread_id) pthread_dummy(0) + +#elif defined(HAVE_UNIXWARE7_THREADS) + +#include <thread.h> +#include <synch.h> + +#ifndef _REENTRANT +#define _REENTRANT +#endif + +#define HAVE_NONPOSIX_SIGWAIT +#define pthread_t thread_t +#define pthread_cond_t cond_t +#define pthread_mutex_t mutex_t +#define pthread_key_t thread_key_t +typedef int pthread_attr_t; /* Needed by Unixware 7.0.0 */ + +#define pthread_key_create(A,B) thr_keycreate((A),(B)) + +#define pthread_handler_decl(A,B) void *A(void *B) +#define pthread_key(T,V) pthread_key_t V + +void * my_pthread_getspecific_imp(pthread_key_t key); +#define my_pthread_getspecific(A,B) ((A) my_pthread_getspecific_imp(B)) +#define my_pthread_getspecific_ptr(T,V) my_pthread_getspecific(T,V) + +#define pthread_setspecific(A,B) thr_setspecific(A,B) +#define my_pthread_setspecific_ptr(T,V) pthread_setspecific(T,V) + +#define pthread_create(A,B,C,D) thr_create(NULL,65536L,(C),(D),THR_DETACHED,(A)) +#define pthread_cond_init(a,b) cond_init((a),USYNC_THREAD,NULL) +#define pthread_cond_destroy(a) cond_destroy(a) +#define pthread_cond_signal(a) cond_signal(a) +#define pthread_cond_wait(a,b) cond_wait((a),(b)) +#define pthread_cond_timedwait(a,b,c) cond_timedwait((a),(b),(c)) +#define pthread_cond_broadcast(a) cond_broadcast(a) + +#define pthread_mutex_init(a,b) mutex_init((a),USYNC_THREAD,NULL) +#define pthread_mutex_lock(a) mutex_lock(a) +#define pthread_mutex_unlock(a) mutex_unlock(a) +#define pthread_mutex_destroy(a) mutex_destroy(a) + +#define pthread_self() thr_self() +#define pthread_exit(A) thr_exit(A) +#define pthread_equal(A,B) (((A) == (B)) ? 1 : 0) +#define pthread_kill(A,B) thr_kill((A),(B)) +#define HAVE_PTHREAD_KILL + +#define pthread_sigmask(A,B,C) thr_sigsetmask((A),(B),(C)) + +extern int my_sigwait(sigset_t *set,int *sig); + +#define pthread_detach_this_thread() pthread_dummy(0) + +#define pthread_attr_init(A) pthread_dummy(0) +#define pthread_attr_destroy(A) pthread_dummy(0) +#define pthread_attr_setscope(A,B) pthread_dummy(0) +#define pthread_attr_setdetachstate(A,B) pthread_dummy(0) +#define my_pthread_setprio(A,B) pthread_dummy (0) +#define my_pthread_getprio(A) pthread_dummy (0) +#define my_pthread_attr_setprio(A,B) pthread_dummy(0) + +#else /* Normal threads */ + +#ifdef HAVE_rts_threads +#define sigwait org_sigwait +#include <signal.h> +#undef sigwait +#endif +#undef _REENTRANT /* Fix if _REENTRANT is in pthread.h */ +#include <pthread.h> +#ifndef _REENTRANT +#define _REENTRANT +#endif +#ifdef HAVE_THR_SETCONCURRENCY +#include <thread.h> /* Probably solaris */ +#endif +#ifdef HAVE_SCHED_H +#include <sched.h> +#endif +#if defined(__EMX__) && (!defined(EMX_PTHREAD_REV) || (EMX_PTHREAD_REV < 2)) +#error Requires at least rev 2 of EMX pthreads library. +#endif + +extern int my_pthread_getprio(pthread_t thread_id); + +#define pthread_key(T,V) pthread_key_t V +#define my_pthread_getspecific_ptr(T,V) my_pthread_getspecific(T,(V)) +#define my_pthread_setspecific_ptr(T,V) pthread_setspecific(T,(void*) (V)) +#define pthread_detach_this_thread() +#define pthread_handler_decl(A,B) void *A(void *B) +typedef void *(* pthread_handler)(void *); + +/* safe mutex for debugging */ + +typedef struct st_safe_mutex_t +{ + pthread_mutex_t global,mutex; + char *file; + uint line,count; + pthread_t thread; +} safe_mutex_t; + +int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr); +int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line); +int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line); +int safe_mutex_destroy(safe_mutex_t *mp); +int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file, uint line); +int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp, + struct timespec *abstime, const char *file, uint line); + +#ifdef SAFE_MUTEX +#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_t +#define pthread_mutex_init(A,B) safe_mutex_init((A),(B)) +#define pthread_mutex_lock(A) safe_mutex_lock((A),__FILE__,__LINE__) +#define pthread_mutex_unlock(A) safe_mutex_unlock((A),__FILE__,__LINE__) +#define pthread_mutex_destroy(A) safe_mutex_destroy((A)) +#define pthread_cond_wait(A,B) safe_cond_wait((A),(B),__FILE__,__LINE__) +#define pthread_cond_timedwait(A,B,C) safe_cond_timedwait((A),(B),(C),__FILE__,__LINE__) +#define pthread_mutex_t safe_mutex_t +#endif + +/* Test first for RTS or FSU threads */ + +#if defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM) +#define HAVE_rts_threads +extern int my_pthread_create_detached; +#define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C)) +#define PTHREAD_CREATE_DETACHED &my_pthread_create_detached +#define PTHREAD_SCOPE_SYSTEM PTHREAD_SCOPE_GLOBAL +#define PTHREAD_SCOPE_PROCESS PTHREAD_SCOPE_LOCAL +#define USE_ALARM_THREAD +#elif defined(HAVE_mit_thread) +#define USE_ALARM_THREAD +#undef HAVE_LOCALTIME_R +#define HAVE_LOCALTIME_R +#undef HAVE_PTHREAD_ATTR_SETSCOPE +#define HAVE_PTHREAD_ATTR_SETSCOPE +#undef HAVE_RWLOCK_T +#undef HAVE_RWLOCK_INIT + +#define sigset(A,B) pthread_signal((A),(void (*)(int)) (B)) +#define signal(A,B) pthread_signal((A),(void (*)(int)) (B)) +#define my_pthread_attr_setprio(A,B) +#endif /* defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM) */ + +#if defined(_BSDI_VERSION) && _BSDI_VERSION < 199910 +int sigwait(const sigset_t *set, int *sig); +#endif + +#if defined(HAVE_UNIXWARE7_POSIX) +#undef HAVE_NONPOSIX_SIGWAIT +#define HAVE_NONPOSIX_SIGWAIT /* sigwait takes only 1 argument */ +#endif + +#ifndef HAVE_NONPOSIX_SIGWAIT +#define my_sigwait(A,B) sigwait((A),(B)) +#else +int my_sigwait(sigset_t *set,int *sig); +#endif + +#ifdef HAVE_NONPOSIX_PTHREAD_MUTEX_INIT +#ifndef SAFE_MUTEX +#define pthread_mutex_init(a,b) my_pthread_mutex_init((a),(b)) +extern int my_pthread_mutex_init(pthread_mutex_t *mp, + const pthread_mutexattr_t *attr); +#endif /* SAFE_MUTEX */ +#define pthread_cond_init(a,b) my_pthread_cond_init((a),(b)) +extern int my_pthread_cond_init(pthread_cond_t *mp, + const pthread_condattr_t *attr); +#endif /* HAVE_NONPOSIX_PTHREAD_MUTEX_INIT */ + +#if defined(HAVE_SIGTHREADMASK) && !defined(HAVE_PTHREAD_SIGMASK) +#define pthread_sigmask(A,B,C) sigthreadmask((A),(B),(C)) +#endif + +#if !defined(HAVE_SIGWAIT) && !defined(HAVE_mit_thread) && !defined(HAVE_rts_threads) && !defined(sigwait) && !defined(alpha_linux_port) && !defined(HAVE_NONPOSIX_SIGWAIT) && !defined(HAVE_DEC_3_2_THREADS) && !defined(_AIX) +int sigwait(sigset_t *setp, int *sigp); /* Use our implemention */ +#endif +#if !defined(HAVE_SIGSET) && !defined(HAVE_mit_thread) && !defined(sigset) +#define sigset(A,B) signal((A),(B)) +#endif + +#ifndef my_pthread_setprio +#if defined(HAVE_PTHREAD_SETPRIO_NP) /* FSU threads */ +#define my_pthread_setprio(A,B) pthread_setprio_np((A),(B)) +#elif defined(HAVE_PTHREAD_SETPRIO) +#define my_pthread_setprio(A,B) pthread_setprio((A),(B)) +#else +extern void my_pthread_setprio(pthread_t thread_id,int prior); +#endif +#endif + +#ifndef my_pthread_attr_setprio +#ifdef HAVE_PTHREAD_ATTR_SETPRIO +#define my_pthread_attr_setprio(A,B) pthread_attr_setprio((A),(B)) +#else +extern void my_pthread_attr_setprio(pthread_attr_t *attr, int priority); +#endif +#endif + +#if !defined(HAVE_PTHREAD_ATTR_SETSCOPE) || defined(HAVE_DEC_3_2_THREADS) +#define pthread_attr_setscope(A,B) +#undef HAVE_GETHOSTBYADDR_R /* No definition */ +#endif + +#ifndef HAVE_NONPOSIX_PTHREAD_GETSPECIFIC +#define my_pthread_getspecific(A,B) ((A) pthread_getspecific(B)) +#else +#define my_pthread_getspecific(A,B) ((A) my_pthread_getspecific_imp(B)) +void *my_pthread_getspecific_imp(pthread_key_t key); +#endif + +#ifndef HAVE_LOCALTIME_R +struct tm *localtime_r(const time_t *clock, struct tm *res); +#endif + +#ifdef HAVE_PTHREAD_CONDATTR_CREATE +/* DCE threads on HPUX 10.20 */ +#define pthread_condattr_init pthread_condattr_create +#define pthread_condattr_destroy pthread_condattr_delete +#endif + +#ifdef HAVE_CTHREADS_WRAPPER /* For MacOSX */ +#define pthread_cond_destroy(A) pthread_dummy(0) +#define pthread_mutex_destroy(A) pthread_dummy(0) +#define pthread_attr_delete(A) pthread_dummy(0) +#define pthread_attr_setstacksize(A,B) pthread_dummy(0) +#define pthread_equal(A,B) ((A) == (B)) +#define pthread_cond_timedwait(a,b,c) pthread_cond_wait((a),(b)) +#define pthread_attr_init(A) pthread_attr_create(A) +#define pthread_attr_destroy(A) pthread_attr_delete(A) +#define pthread_attr_setdetachstate(A,B) pthread_dummy(0) +#define pthread_create(A,B,C,D) pthread_create((A),*(B),(C),(D)) +#define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C)) +#define pthread_kill(A,B) pthread_dummy(0) +#undef pthread_detach_this_thread +#define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); } +#endif + +#if ((defined(HAVE_PTHREAD_ATTR_CREATE) && !defined(HAVE_SIGWAIT)) || defined(HAVE_DEC_3_2_THREADS)) && !defined(HAVE_CTHREADS_WRAPPER) +/* This is set on AIX_3_2 and Siemens unix (and DEC OSF/1 3.2 too) */ +#define pthread_key_create(A,B) \ + pthread_keycreate(A,(B) ?\ + (pthread_destructor_t) (B) :\ + (pthread_destructor_t) pthread_dummy) +#define pthread_attr_init(A) pthread_attr_create(A) +#define pthread_attr_destroy(A) pthread_attr_delete(A) +#define pthread_attr_setdetachstate(A,B) pthread_dummy(0) +#define pthread_create(A,B,C,D) pthread_create((A),*(B),(C),(D)) +#ifndef pthread_sigmask +#define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C)) +#endif +#define pthread_kill(A,B) pthread_dummy(0) +#undef pthread_detach_this_thread +#define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); } +#else /* HAVE_PTHREAD_ATTR_CREATE && !HAVE_SIGWAIT */ +#define HAVE_PTHREAD_KILL +#endif + +#if defined(HAVE_PTHREAD_ATTR_CREATE) || defined(_AIX) || defined(HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R) +#if !defined(HPUX) +struct hostent; +#endif /* HPUX */ +struct hostent *my_gethostbyname_r(const char *name, + struct hostent *result, char *buffer, + int buflen, int *h_errnop); +#if defined(HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R) +#define GETHOSTBYNAME_BUFF_SIZE 2048 +#else +#define GETHOSTBYNAME_BUFF_SIZE sizeof(struct hostent_data) +#endif /* defined(HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R) */ + +#else +#define my_gethostbyname_r(A,B,C,D,E) gethostbyname_r((A),(B),(C),(D),(E)) +#define GETHOSTBYNAME_BUFF_SIZE 2048 +#endif /* defined(HAVE_PTHREAD_ATTR_CREATE) || defined(_AIX) || defined(HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R) */ + +#endif /* defined(__WIN32__) */ + +/* READ-WRITE thread locking */ +#ifndef HAVE_RWLOCK_INIT +#if defined(USE_MUTEX_INSTEAD_OF_RW_LOCKS) +/* use these defs for simple mutex locking */ +#define rw_lock_t pthread_mutex_t +#define my_rwlock_init(A,B) pthread_mutex_init((A),(B)) +#define rw_rdlock(A) pthread_mutex_lock((A)) +#define rw_wrlock(A) pthread_mutex_lock((A)) +#define rw_unlock(A) pthread_mutex_unlock((A)) +#define rwlock_destroy(A) pthread_mutex_destroy((A)) +#elif defined(HAVE_PTHREAD_RWLOCK_RDLOCK) +#define rw_lock_t pthread_rwlock_t +#define my_rwlock_init(A,B) pthread_rwlock_init((A),(B)) +#define rw_rdlock(A) pthread_rwlock_rdlock(A) +#define rw_wrlock(A) pthread_rwlock_wrlock(A) +#define rw_unlock(A) pthread_rwlock_unlock(A) +#define rwlock_destroy(A) pthread_rwlock_destroy(A) +#else +typedef struct _my_rw_lock_t { + pthread_mutex_t lock; /* lock for structure */ + pthread_cond_t readers; /* waiting readers */ + pthread_cond_t writers; /* waiting writers */ + int state; /* -1:writer,0:free,>0:readers */ + int waiters; /* number of waiting writers */ +} my_rw_lock_t; + +#define rw_lock_t my_rw_lock_t +#define rw_rdlock(A) my_rw_rdlock((A)) +#define rw_wrlock(A) my_rw_wrlock((A)) +#define rw_unlock(A) my_rw_unlock((A)) +#define rwlock_destroy(A) my_rwlock_destroy((A)) + +extern int my_rwlock_init( rw_lock_t *, void * ); +extern int my_rwlock_destroy( rw_lock_t * ); +extern int my_rw_rdlock( rw_lock_t * ); +extern int my_rw_wrlock( rw_lock_t * ); +extern int my_rw_unlock( rw_lock_t * ); +#endif /* USE_MUTEX_INSTEAD_OF_RW_LOCKS */ +#else +#ifdef HAVE_RWLOCK_T /* For example Solaris 2.6-> */ +#define rw_lock_t rwlock_t +#define my_rwlock_init(A,B) rwlock_init((A),USYNC_THREAD,0) +#endif +#endif /* HAVE_RWLOCK_INIT */ + +#define GETHOSTBYADDR_BUFF_SIZE 2048 + +#ifndef HAVE_THR_SETCONCURRENCY +#define thr_setconcurrency(A) pthread_dummy(0) +#endif +#if !defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) && ! defined(pthread_attr_setstacksize) +#define pthread_attr_setstacksize(A,B) pthread_dummy(0) +#endif + +extern my_bool my_thread_global_init(void); +extern void my_thread_global_end(void); +extern my_bool my_thread_init(void); +extern void my_thread_end(void); +extern char *my_thread_name(void); +extern long my_thread_id(void); +extern int pthread_no_free(void *); +extern int pthread_dummy(int); + +/* All thread specific variables are in the following struct */ + +#define THREAD_NAME_SIZE 10 + +struct st_my_thread_var +{ + int thr_errno; + int cmp_length; + volatile int abort; + long id; + pthread_cond_t suspend, *current_cond; + pthread_mutex_t mutex, *current_mutex; + pthread_t pthread_self; +#ifndef DBUG_OFF + char name[THREAD_NAME_SIZE+1]; + gptr dbug; +#endif +}; + +extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const)); +#define my_thread_var (_my_thread_var()) +#define my_errno my_thread_var->thr_errno + + /* This is only used for not essential statistic */ + +#ifndef thread_safe_increment +#ifdef SAFE_STATISTICS +#define thread_safe_increment(V,L) \ + pthread_mutex_lock((L)); (V)++; pthread_mutex_unlock((L)); +#define thread_safe_add(V,C,L) \ + pthread_mutex_lock((L)); (V)+=(C); pthread_mutex_unlock((L)); +#else +#define thread_safe_increment(V,L) (V)++ +#define thread_safe_add(V,C,L) (V)+=(C) +#endif +#endif /* thread_safe_increment */ + +#endif /* _my_ptread_h */ diff --git a/ext/mysql/libmysql/my_read.c b/ext/mysql/libmysql/my_read.c new file mode 100644 index 0000000000..b112927a3e --- /dev/null +++ b/ext/mysql/libmysql/my_read.c @@ -0,0 +1,52 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +#include "mysys_priv.h" +#include "mysys_err.h" +#include <errno.h> + + + /* Read a chunk of bytes from a file */ + +uint my_read(File Filedes, byte *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 */ diff --git a/ext/mysql/libmysql/my_realloc.c b/ext/mysql/libmysql/my_realloc.c new file mode 100644 index 0000000000..1d26140b01 --- /dev/null +++ b/ext/mysql/libmysql/my_realloc.c @@ -0,0 +1,51 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +#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, uint 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,MyFlags); + 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 = realloc(oldpoint,Size)) == NULL) + { + if (MyFlags & MY_FREE_ON_ERROR) + my_free(oldpoint,MyFLAGS); + 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 */ diff --git a/ext/mysql/libmysql/my_static.c b/ext/mysql/libmysql/my_static.c new file mode 100644 index 0000000000..93c9b15ef1 --- /dev/null +++ b/ext/mysql/libmysql/my_static.c @@ -0,0 +1,86 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* + Static variables for mysys library. All definied here for easy making of + a shared library +*/ + +#ifndef stdin +#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}; +uint my_stream_opened=0,my_file_opened=0; +int NEAR my_umask=0664; +#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 */ +#ifndef HAVE_TEMPNAM +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 */ +long lCurMemory = 0L; /* Current memory usage */ +long lMaxMemory = 0L; /* Maximum memory usage */ +uint cNewCount = 0; /* Number of times NEW() was called */ +byte *sf_min_adress= (byte*) ~(unsigned long) 0L, + *sf_max_adress= (byte*) 0L; + +/* 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 mysys_uses_curses=0; diff --git a/ext/mysql/libmysql/my_static.h b/ext/mysql/libmysql/my_static.h new file mode 100644 index 0000000000..20d43dca55 --- /dev/null +++ b/ext/mysql/libmysql/my_static.h @@ -0,0 +1,68 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* + 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); +}; + +typedef struct sec_link { + struct sec_link *next_hash,**prev_hash;/* Blocks linked acc. to hash-value */ + struct sec_link *next_used,*prev_used; + struct sec_link *next_changed,**prev_changed; + File file; + my_off_t diskpos; + byte *buffer; + my_bool changed; +} SEC_LINK; + +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 my_bool key_cache_inited; + +extern const char *soundex_map; + +extern USED_MEM* my_once_root_block; +extern uint my_once_extra; + +#ifndef HAVE_TEMPNAM +extern int _my_tempnam_used; +#endif + +extern byte *sf_min_adress,*sf_max_adress; +extern uint cNewCount; +extern struct remember *pRememberRoot; + +#if defined(THREAD) && !defined(__WIN32__) +extern sigset_t my_signals; /* signals blocked by mf_brkhant */ +#endif diff --git a/ext/mysql/libmysql/my_sys.h b/ext/mysql/libmysql/my_sys.h new file mode 100644 index 0000000000..d7cf699521 --- /dev/null +++ b/ext/mysql/libmysql/my_sys.h @@ -0,0 +1,504 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +#ifndef _my_sys_h +#define _my_sys_h +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAVE_AIOWAIT +#include <sys/asynch.h> /* Used by record-cache */ +typedef struct my_aio_result { + aio_result_t result; + int pending; +} my_aio_result; +#endif + +#ifndef THREAD +extern int NEAR my_errno; /* Last error in mysys */ +#else +#include <my_pthread.h> +#endif + +#define MYSYS_PROGRAM_USES_CURSES() { error_handler_hook = my_message_curses; mysys_uses_curses=1; } +#define MYSYS_PROGRAM_DONT_USE_CURSES() { error_handler_hook = my_message_no_curses; mysys_uses_curses=0;} +#define MY_INIT(name); { my_progname= name; my_init(); } + +#define MAXMAPS (4) /* Number of error message maps */ +#define ERRMOD (1000) /* Max number of errors in a map */ +#define ERRMSGSIZE (SC_MAXWIDTH) /* Max length of a error message */ +#define NRERRBUFFS (2) /* Buffers for parameters */ +#define MY_FILE_ERROR ((uint) ~0) + + /* General bitmaps for my_func's */ +#define MY_FFNF 1 /* Fatal if file not found */ +#define MY_FNABP 2 /* Fatal if not all bytes read/writen */ +#define MY_NABP 4 /* Error if not all bytes read/writen */ +#define MY_FAE 8 /* Fatal if any error */ +#define MY_WME 16 /* Write message on error */ +#define MY_WAIT_IF_FULL 32 /* Wait and try again if disk full error */ +#define MY_RAID 64 /* Support for RAID (not the "Johnson&Johnson"-s one ;) */ +#define MY_LINK_WARNING 32 /* my_redel() gives warning if links */ +#define MY_COPYTIME 64 /* my_redel() copys time */ +#define MY_HOLD_ORIGINAL_MODES 128 /* my_copy() holds to file modes */ +#define MY_SEEK_NOT_DONE 32 /* my_lock may have to do a seek */ +#define MY_DONT_WAIT 64 /* my_lock() don't wait if can't lock */ +#define MY_ZEROFILL 32 /* my_malloc(), fill array with zero */ +#define MY_ALLOW_ZERO_PTR 64 /* my_realloc() ; zero ptr -> malloc */ +#define MY_FREE_ON_ERROR 128 /* my_realloc() ; Free old ptr on error */ +#define MY_HOLD_ON_ERROR 256 /* my_realloc() ; Return old ptr on error */ + +#define MY_CHECK_ERROR 1 /* Params to my_end; Check open-close */ +#define MY_GIVE_INFO 2 /* Give time info about process*/ + +#define ME_HIGHBYTE 8 /* Shift for colours */ +#define ME_NOCUR 1 /* Don't use curses message */ +#define ME_OLDWIN 2 /* Use old window */ +#define ME_BELL 4 /* Ring bell then printing message */ +#define ME_HOLDTANG 8 /* Don't delete last keys */ +#define ME_WAITTOT 16 /* Wait for errtime secs of for a action */ +#define ME_WAITTANG 32 /* Wait for a user action */ +#define ME_NOREFRESH 64 /* Dont refresh screen */ +#define ME_NOINPUT 128 /* Dont use the input libary */ +#define ME_COLOUR1 ((1 << ME_HIGHBYTE)) /* Possibly error-colours */ +#define ME_COLOUR2 ((2 << ME_HIGHBYTE)) +#define ME_COLOUR3 ((3 << ME_HIGHBYTE)) + + /* My seek flags */ +#define MY_SEEK_SET 0 +#define MY_SEEK_CUR 1 +#define MY_SEEK_END 2 + + /* Some constants */ +#define MY_WAIT_FOR_USER_TO_FIX_PANIC 60 /* in seconds */ +#define MY_WAIT_GIVE_USER_A_MESSAGE 10 /* Every 10 times of prev */ +#define MIN_COMPRESS_LENGTH 50 /* Don't compress small bl. */ + + /* defines when allocating data */ + +#ifdef SAFEMALLOC +#define my_malloc(SZ,FLAG) _mymalloc( SZ, __FILE__, __LINE__, FLAG ) +#define my_realloc(PTR,SZ,FLAG) _myrealloc( PTR, SZ, __FILE__, __LINE__, FLAG ) +#define my_checkmalloc() _sanity( __FILE__, __LINE__ ) +#define my_free(PTR,FLAG) _myfree( PTR, __FILE__, __LINE__,FLAG) +#define my_memdup(A,B,C) _my_memdup(A,B,__FILE__,__LINE__,C) +#define my_strdup(A,C) _my_strdup(A,__FILE__,__LINE__,C) +#define QUICK_SAFEMALLOC sf_malloc_quick=1 +#define NORMAL_SAFEMALLOC sf_malloc_quick=0 +extern uint sf_malloc_prehunc,sf_malloc_endhunc,sf_malloc_quick; +#else +#define my_checkmalloc() (0) +#define TERMINATE(A) {} +#define QUICK_SAFEMALLOC +#define NORMAL_SAFEMALLOC +extern gptr my_malloc(uint Size,myf MyFlags); +extern gptr my_realloc(gptr oldpoint,uint Size,myf MyFlags); +extern void my_no_flags_free(gptr ptr); +extern gptr my_memdup(const byte *from,uint length,myf MyFlags); +extern my_string my_strdup(const char *from,myf MyFlags); +#define my_free(PTR,FG) my_no_flags_free(PTR) +#endif +#ifdef HAVE_ALLOCA +#define my_alloca(SZ) alloca((size_t) (SZ)) +#define my_afree(PTR) {} +#else +#define my_alloca(SZ) my_malloc(SZ,MYF(0)) +#define my_afree(PTR) my_free(PTR,MYF(MY_WME)) +#endif /* HAVE_ALLOCA */ +#ifdef MSDOS +#ifdef __ZTC__ +void * __CDECL halloc(long count,size_t length); +void __CDECL hfree(void *ptr); +#endif +#if defined(USE_HALLOC) +#if defined(_VCM_) || defined(M_IC80386) +#undef USE_HALLOC +#endif +#endif +#ifdef USE_HALLOC +#define malloc(a) halloc((long) (a),1) +#define free(a) hfree(a) +#endif +#endif /* MSDOS */ + +#ifdef HAVE_ERRNO_AS_DEFINE +#include <errno.h> /* errno is a define */ +#else +extern int errno; /* declare errno */ +#endif +extern const char ** NEAR errmsg[]; +extern char NEAR errbuff[NRERRBUFFS][ERRMSGSIZE]; +extern char *home_dir; /* Home directory for user */ +extern char *my_progname; /* program-name (printed in errors) */ +extern char NEAR curr_dir[]; /* Current directory for user */ +extern int (*error_handler_hook)(uint my_err, const char *str,myf MyFlags); +extern int (*fatal_error_handler_hook)(uint my_err, const char *str, + myf MyFlags); + + +/* statisticts */ +extern ulong _my_cache_w_requests,_my_cache_write,_my_cache_r_requests, + _my_cache_read; +extern uint _my_blocks_used,_my_blocks_changed; +extern uint my_file_opened,my_stream_opened; + + /* Point to current my_message() */ +extern void (*my_sigtstp_cleanup)(void), + /* Executed before jump to shell */ + (*my_sigtstp_restart)(void), + (*my_abort_hook)(int); + /* Executed when comming from shell */ +extern int NEAR my_umask, /* Default creation mask */ + NEAR my_recived_signals, /* Signals we have got */ + NEAR my_safe_to_handle_signal, /* Set when allowed to SIGTSTP */ + NEAR my_dont_interrupt; /* call remember_intr when set */ +extern my_bool NEAR mysys_uses_curses; +extern long lCurMemory,lMaxMemory; /* from safemalloc */ + +extern ulong my_default_record_cache_size; +extern my_bool NEAR my_disable_locking,NEAR my_disable_async_io, + NEAR my_disable_flush_key_blocks; +extern char wild_many,wild_one,wild_prefix; + +typedef struct wild_file_pack /* Struct to hold info when selecting files */ +{ + uint wilds; /* How many wildcards */ + uint not_pos; /* Start of not-theese-files */ + my_string *wild; /* Pointer to wildcards */ +} WF_PACK; + +typedef struct st_typelib { /* Different types saved here */ + uint count; /* How many types */ + my_string name; /* Name of typelib */ + my_string *type_names; +} TYPELIB; + +enum cache_type {READ_CACHE,WRITE_CACHE,READ_NET,WRITE_NET}; +enum flush_type { FLUSH_KEEP, FLUSH_RELEASE, FLUSH_IGNORE_CHANGED}; + +typedef struct st_record_cache /* Used when cacheing records */ +{ + File file; + int rc_seek,error,inited; + uint rc_length,read_length,reclength; + my_off_t rc_record_pos,end_of_file; + byte *rc_buff,*rc_buff2,*rc_pos,*rc_end,*rc_request_pos; +#ifdef HAVE_AIOWAIT + int use_async_io; + my_aio_result aio_result; +#endif + enum cache_type type; +} RECORD_CACHE; + +enum file_type { UNOPEN = 0, FILE_BY_OPEN, FILE_BY_CREATE, + STREAM_BY_FOPEN, STREAM_BY_FDOPEN }; + +extern struct my_file_info +{ + my_string name; + enum file_type type; +} my_file_info[MY_NFILE]; + + +typedef struct st_dynamic_array { + char *buffer; + uint elements,max_element; + uint alloc_increment; + uint size_of_element; +} DYNAMIC_ARRAY; + +typedef struct st_dynamic_string { + char *str; + uint length,max_length,alloc_increment; +} DYNAMIC_STRING; + + +typedef struct st_io_cache /* Used when cacheing files */ +{ + byte *rc_pos,*rc_end,*buffer,*rc_request_pos; + File file; + int seek_not_done,error; + uint buffer_length,read_length; + my_off_t pos_in_file,end_of_file; + myf myflags; /* Flags used to my_read/my_write */ +#ifdef HAVE_AIOWAIT + uint inited; + my_off_t aio_read_pos; + my_aio_result aio_result; +#endif + enum cache_type type; + int (*read_function)(struct st_io_cache *,byte *,uint); + char *file_name; /* if used with 'open_cacheed_file' */ +} IO_CACHE; + + /* defines for mf_iocache */ + + /* Test if buffer is inited */ +#define my_b_clear(info) (info)->buffer=0 +#define my_b_inited(info) (info)->buffer +#define my_b_EOF INT_MIN + +#define my_b_read(info,Buffer,Count) \ + ((info)->rc_pos + (Count) <= (info)->rc_end ?\ + (memcpy(Buffer,(info)->rc_pos,(size_t) (Count)), \ + ((info)->rc_pos+=(Count)),0) :\ + (*(info)->read_function)((info),Buffer,Count)) + +#define my_b_get(info) \ + ((info)->rc_pos != (info)->rc_end ?\ + ((info)->rc_pos++, (int) (uchar) (info)->rc_pos[-1]) :\ + _my_b_get(info)) + +#define my_b_write(info,Buffer,Count) \ + ((info)->rc_pos + (Count) <= (info)->rc_end ?\ + (memcpy((info)->rc_pos,Buffer,(size_t) (Count)), \ + ((info)->rc_pos+=(Count)),0) :\ + _my_b_write(info,Buffer,Count)) + + /* my_b_write_byte dosn't have any err-check */ +#define my_b_write_byte(info,chr) \ + (((info)->rc_pos < (info)->rc_end) ?\ + ((*(info)->rc_pos++)=(chr)) :\ + (_my_b_write(info,0,0) , ((*(info)->rc_pos++)=(chr)))) + +#define my_b_fill_cache(info) \ + (((info)->rc_end=(info)->rc_pos),(*(info)->read_function)(info,0,0)) + +#define my_b_tell(info) ((info)->pos_in_file + \ + ((info)->rc_pos - (info)->rc_request_pos)) + +typedef struct st_changeable_var { + const char *name; + long *varptr; + long def_value,min_value,max_value,sub_size,block_size; +} CHANGEABLE_VAR; + + +/* structs for alloc_root */ + +#ifndef ST_USED_MEM_DEFINED +#define ST_USED_MEM_DEFINED +typedef struct st_used_mem { /* struct for once_alloc */ + struct st_used_mem *next; /* Next block in use */ + unsigned int left; /* memory left in block */ + unsigned int size; /* size of block */ +} USED_MEM; + +typedef struct st_mem_root { + USED_MEM *free; + USED_MEM *used; + unsigned int min_malloc; + unsigned int block_size; + void (*error_handler)(void); +} MEM_ROOT; +#endif + + /* Prototypes for mysys and my_func functions */ + +extern int my_copy(const char *from,const char *to,myf MyFlags); +extern int my_append(const char *from,const char *to,myf MyFlags); +extern int my_delete(const char *name,myf MyFlags); +extern int my_getwd(my_string buf,uint size,myf MyFlags); +extern int my_setwd(const char *dir,myf MyFlags); +extern int my_lock(File fd,int op,my_off_t start, my_off_t length,myf MyFlags); +extern gptr my_once_alloc(uint Size,myf MyFlags); +extern void my_once_free(void); +extern my_string my_tempnam(const char *dir,const char *pfx,myf MyFlags); +extern File my_open(const char *FileName,int Flags,myf MyFlags); +extern File my_create(const char *FileName,int CreateFlags, + int AccsesFlags, myf MyFlags); +extern int my_close(File Filedes,myf MyFlags); +extern int my_mkdir(const char *dir, int Flags, myf MyFlags); +extern uint my_read(File Filedes,byte *Buffer,uint Count,myf MyFlags); +extern uint my_pread(File Filedes,byte *Buffer,uint Count,my_off_t offset, + myf MyFlags); +extern int my_rename(const char *from,const char *to,myf MyFlags); +extern my_off_t my_seek(File fd,my_off_t pos,int whence,myf MyFlags); +extern my_off_t my_tell(File fd,myf MyFlags); +extern uint my_write(File Filedes,const byte *Buffer,uint Count, + myf MyFlags); +extern uint my_pwrite(File Filedes,const byte *Buffer,uint Count, + my_off_t offset,myf MyFlags); +extern uint my_fread(FILE *stream,byte *Buffer,uint Count,myf MyFlags); +extern uint my_fwrite(FILE *stream,const byte *Buffer,uint Count, + myf MyFlags); +extern my_off_t my_fseek(FILE *stream,my_off_t pos,int whence,myf MyFlags); +extern my_off_t my_ftell(FILE *stream,myf MyFlags); +extern gptr _mymalloc(uint uSize,const char *sFile, + uint uLine, myf MyFlag); +extern gptr _myrealloc(my_string pPtr,uint uSize,const char *sFile, + uint uLine, myf MyFlag); +extern gptr my_multi_malloc _VARARGS((myf MyFlags, ...)); +extern void _myfree(gptr pPtr,const char *sFile,uint uLine, myf MyFlag); +extern int _sanity(const char *sFile,unsigned int uLine); +extern gptr _my_memdup(const byte *from,uint length, + const char *sFile, uint uLine,myf MyFlag); +extern my_string _my_strdup(const char *from, const char *sFile, uint uLine, + myf MyFlag); +#ifndef TERMINATE +extern void TERMINATE(FILE *file); +#endif +extern void init_glob_errs(void); +extern FILE *my_fopen(const char *FileName,int Flags,myf MyFlags); +extern FILE *my_fdopen(File Filedes,int Flags,myf MyFlags); +extern int my_fclose(FILE *fd,myf MyFlags); +extern int my_chsize(File fd,my_off_t newlength,myf MyFlags); +extern int my_error _VARARGS((int nr,myf MyFlags, ...)); +extern int my_printf_error _VARARGS((uint my_err, const char *format, + myf MyFlags, ...) + __attribute__ ((format (printf, 2, 4)))); +extern int my_message(uint my_err, const char *str,myf MyFlags); +extern int my_message_no_curses(uint my_err, const char *str,myf MyFlags); +extern int my_message_curses(uint my_err, const char *str,myf MyFlags); +extern void my_init(void); +extern void my_end(int infoflag); +extern int my_redel(const char *from, const char *to, int MyFlags); +extern int my_copystat(const char *from, const char *to, int MyFlags); +extern my_string my_filename(File fd); + +extern void dont_break(void); +extern void allow_break(void); +extern void my_remember_signal(int signal_number,sig_handler (*func)(int)); +extern void caseup(my_string str,uint length); +extern void casedn(my_string str,uint length); +extern void caseup_str(my_string str); +extern void casedn_str(my_string str); +extern void case_sort(my_string str,uint length); +extern uint dirname_part(my_string to,const char *name); +extern uint dirname_length(const char *name); +#define base_name(A) (A+dirname_length(A)) +extern int test_if_hard_path(const char *dir_name); +extern void convert_dirname(my_string name); +extern void to_unix_path(my_string name); +extern my_string fn_ext(const char *name); +extern my_string fn_same(my_string toname,const char *name,int flag); +extern my_string fn_format(my_string to,const char *name,const char *dsk, + const char *form,int flag); +extern size_s strlength(const char *str); +extern void pack_dirname(my_string to,const char *from); +extern uint unpack_dirname(my_string to,const char *from); +extern uint cleanup_dirname(my_string to,const char *from); +extern uint system_filename(my_string to,const char *from); +extern my_string unpack_filename(my_string to,const char *from); +extern my_string intern_filename(my_string to,const char *from); +extern my_string directory_file_name(my_string dst, const char *src); +extern int pack_filename(my_string to, const char *name, size_s max_length); +extern my_string my_path(my_string to,const char *progname, + const char *own_pathname_part); +extern my_string my_load_path(my_string to, const char *path, + const char *own_path_prefix); +extern int wild_compare(const char *str,const char *wildstr); +extern my_string strcasestr(const char *src,const char *suffix); +extern int my_strcasecmp(const char *s,const char *t); +extern int my_strsortcmp(const char *s,const char *t); +extern int my_casecmp(const char *s,const char *t,uint length); +extern int my_sortcmp(const char *s,const char *t,uint length); +extern WF_PACK *wf_comp(my_string str); +extern int wf_test(struct wild_file_pack *wf_pack,const char *name); +extern void wf_end(struct wild_file_pack *buffer); +extern size_s stripp_sp(my_string str); +extern void get_date(my_string to,int timeflag,time_t use_time); +extern void soundex(my_string out_pntr, my_string in_pntr,pbool remove_garbage); +extern int init_record_cache(RECORD_CACHE *info,uint cachesize,File file, + uint reclength,enum cache_type type, + pbool use_async_io); +extern int read_cache_record(RECORD_CACHE *info,byte *to); +extern int end_record_cache(RECORD_CACHE *info); +extern int write_cache_record(RECORD_CACHE *info,my_off_t filepos, + const byte *record,uint length); +extern int flush_write_cache(RECORD_CACHE *info); +extern long my_clock(void); +extern sig_handler sigtstp_handler(int signal_number); +extern void handle_recived_signals(void); +extern int init_key_cache(ulong use_mem,ulong leave_this_much_mem); +extern byte *key_cache_read(File file,my_off_t filepos,byte* buff,uint length, + uint block_length,int return_buffer); +extern int key_cache_write(File file,my_off_t filepos,byte* buff,uint length, + uint block_length,int force_write); +extern int flush_key_blocks(int file, enum flush_type type); +extern void end_key_cache(void); +extern sig_handler my_set_alarm_variable(int signo); +extern void my_string_ptr_sort(void *base,uint items,size_s size); +extern void radixsort_for_str_ptr(uchar* base[], uint number_of_elements, + size_s size_of_element,uchar *buffer[]); +extern int init_io_cache(IO_CACHE *info,File file,uint cachesize, + enum cache_type type,my_off_t seek_offset, + pbool use_async_io, myf cache_myflags); +extern my_bool reinit_io_cache(IO_CACHE *info,enum cache_type type, + my_off_t seek_offset,pbool use_async_io, + pbool clear_cache); +extern int _my_b_read(IO_CACHE *info,byte *Buffer,uint Count); +extern int _my_b_net_read(IO_CACHE *info,byte *Buffer,uint Count); +extern int _my_b_get(IO_CACHE *info); +extern int _my_b_async_read(IO_CACHE *info,byte *Buffer,uint Count); +extern int _my_b_write(IO_CACHE *info,const byte *Buffer,uint Count); +extern int flush_io_cache(IO_CACHE *info); +extern int end_io_cache(IO_CACHE *info); +extern my_bool open_cacheed_file(IO_CACHE *cache,const char *dir, + const char *prefix, uint cache_size, + myf cache_myflags); +extern my_bool real_open_cached_file(IO_CACHE *cache); +extern void close_cacheed_file(IO_CACHE *cache); +extern my_bool init_dynamic_array(DYNAMIC_ARRAY *array,uint element_size, + uint init_alloc,uint alloc_increment); +extern my_bool insert_dynamic(DYNAMIC_ARRAY *array,gptr element); +extern byte *alloc_dynamic(DYNAMIC_ARRAY *array); +extern byte *pop_dynamic(DYNAMIC_ARRAY*); +extern my_bool set_dynamic(DYNAMIC_ARRAY *array,gptr element,uint array_index); +extern void get_dynamic(DYNAMIC_ARRAY *array,gptr element,uint array_index); +extern void delete_dynamic(DYNAMIC_ARRAY *array); +extern void delete_dynamic_element(DYNAMIC_ARRAY *array, uint array_index); +extern void freeze_size(DYNAMIC_ARRAY *array); +#define dynamic_array_ptr(array,array_index) ((array)->buffer+(array_index)*(array)->size_of_element) +#define dynamic_element(array,array_index,type) ((type)((array)->buffer) +(array_index)) +#define push_dynamic(A,B) insert_dynamic(A,B) + +extern int find_type(my_string x,TYPELIB *typelib,uint full_name); +extern void make_type(my_string to,uint nr,TYPELIB *typelib); +extern my_string get_type(TYPELIB *typelib,uint nr); +extern my_bool init_dynamic_string(DYNAMIC_STRING *str, const char *init_str, + uint init_alloc,uint alloc_increment); +extern my_bool dynstr_append(DYNAMIC_STRING *str, const char *append); +extern my_bool dynstr_set(DYNAMIC_STRING *str, const char *init_str); +extern my_bool dynstr_realloc(DYNAMIC_STRING *str, ulong additional_size); +extern void dynstr_free(DYNAMIC_STRING *str); +void set_all_changeable_vars(CHANGEABLE_VAR *vars); +my_bool set_changeable_var(my_string str,CHANGEABLE_VAR *vars); +my_bool set_changeable_varval(const char *var, ulong val, + CHANGEABLE_VAR *vars); +#ifdef HAVE_MLOCK +extern byte *my_malloc_lock(uint length,myf flags); +extern void my_free_lock(byte *ptr,myf flags); +#else +#define my_malloc_lock(A,B) my_malloc((A),(B)) +#define my_free_lock(A,B) my_free((A),(B)) +#endif +void init_alloc_root(MEM_ROOT *mem_root,uint block_size); +gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size); +void free_root(MEM_ROOT *root); +char *strdup_root(MEM_ROOT *root,const char *str); +char *memdup_root(MEM_ROOT *root,const char *str,uint len); +void load_defaults(const char *conf_file, const char **groups, + int *argc, char ***argv); +void free_defaults(char **argv); +void print_defaults(const char *conf_file, const char **groups); +my_bool my_compress(byte *, ulong *, ulong *); +my_bool my_uncompress(byte *, ulong *, ulong *); +byte *my_compress_alloc(const byte *packet, ulong *len, ulong *complen); +ulong checksum(const byte *mem, uint count); + +#if defined(_MSC_VER) && !defined(__WIN32__) +extern void sleep(int sec); +#endif +#ifdef __WIN32__ +extern my_bool have_tcpip; /* Is set if tcpip is used */ +#endif + +#ifdef __cplusplus +} +#endif +#if defined(USE_RAID) +#include "raid.h" +#endif +#endif /* _my_sys_h */ diff --git a/ext/mysql/libmysql/my_tempnam.c b/ext/mysql/libmysql/my_tempnam.c new file mode 100644 index 0000000000..a288ecda4f --- /dev/null +++ b/ext/mysql/libmysql/my_tempnam.c @@ -0,0 +1,128 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +#include "mysys_priv.h" +#include <m_string.h> +#include "my_static.h" +#include "mysys_err.h" + +#define TMP_EXT ".tmp" /* Extension of tempfile */ +#if ! defined(P_tmpdir) +#define P_tmpdir "" +#endif + +#ifdef HAVE_TEMPNAM +#ifndef MSDOS +extern char **environ; +#endif +#endif + +/* Make a uniq temp file name by using dir and adding something after + pfx to make name uniq. Name is made by adding a uniq 8 length-string and + TMP_EXT after pfx. + Returns pointer to malloced area for filename. Should be freed by + free(). + The name should be uniq, but it isn't checked if it file allready exists. + Uses tempnam() if function exist on system. + This function fixes that if dir is given it's used. For example + MSDOS tempnam() uses always TMP environment-variable if it exists. +*/ + /* ARGSUSED */ + +my_string my_tempnam(const char *dir, const char *pfx, + myf MyFlags __attribute__((unused))) +{ +#ifdef _MSC_VER + char temp[FN_REFLEN],*end,*res,**old_env,*temp_env[1]; + old_env=environ; + if (dir) + { + end=strend(dir)-1; + if (!dir[0]) + { /* Change empty string to current dir */ + temp[0]= FN_CURLIB; + temp[1]= 0; + dir=temp; + } + else if (*end == FN_DEVCHAR) + { /* Get current dir for drive */ + _fullpath(temp,dir,FN_REFLEN); + dir=temp; + } + else if (*end == FN_LIBCHAR && dir < end && end[-1] != FN_DEVCHAR) + { + strmake(temp,dir,(uint) (end-dir)); /* Copy and remove last '\' */ + dir=temp; + } + environ=temp_env; /* Force use of dir (dir not checked) */ + temp_env[0]=0; + } + res=tempnam((char*) dir,(my_string) pfx); + environ=old_env; + return res; +#else +#ifdef __ZTC__ + if (!dir) + { /* If empty test first if TMP can be used */ + dir=getenv("TMP"); + } + return tempnam((char*) dir,(my_string) pfx); /* Use stand. dir with prefix */ +#else +#ifdef HAVE_TEMPNAM + char temp[2],*res,**old_env,*temp_env[1]; + + if (dir && !dir[0]) + { /* Change empty string to current dir */ + temp[0]= FN_CURLIB; + temp[1]= 0; + dir=temp; + } + old_env=environ; + if (dir) + { /* Don't use TMPDIR if dir is given */ + environ=temp_env; + temp_env[0]=0; + } + res=tempnam((char*) dir,(my_string) pfx); /* Use stand. dir with prefix */ + environ=old_env; + if (!res) + DBUG_PRINT("error",("Got error: %d from tempnam",errno)); + return res; +#else + register long uniq; + register int length; + my_string pos,end_pos; + DBUG_ENTER("my_tempnam"); + /* Make a uniq nummber */ + pthread_mutex_lock(&THR_LOCK_open); + uniq= ((long) getpid() << 20) + (long) _my_tempnam_used++ ; + pthread_mutex_unlock(&THR_LOCK_open); + if (!dir && !(dir=getenv("TMPDIR"))) /* Use this if possibly */ + dir=P_tmpdir; /* Use system default */ + length=strlen(dir)+strlen(pfx)+1; + + DBUG_PRINT("test",("mallocing %d byte",length+8+sizeof(TMP_EXT)+1)); + if (!(pos=(char*) malloc(length+8+sizeof(TMP_EXT)+1))) + { + if (MyFlags & MY_FAE+MY_WME) + my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG), + length+8+sizeof(TMP_EXT)+1); + DBUG_RETURN(NullS); + } + end_pos=strmov(pos,dir); + if (end_pos != pos && end_pos[-1] != FN_LIBCHAR) + *end_pos++=FN_LIBCHAR; + end_pos=strmov(end_pos,pfx); + + for (length=0 ; length < 8 && uniq ; length++) + { + *end_pos++= _dig_vec[(int) (uniq & 31)]; + uniq >>= 5; + } + VOID(strmov(end_pos,TMP_EXT)); + DBUG_PRINT("exit",("tempnam: '%s'",pos)); + DBUG_RETURN(pos); +#endif /* HAVE_TEMPNAM */ +#endif /* __ZTC__ */ +#endif /* _MSC_VER */ +} /* my_tempnam */ diff --git a/ext/mysql/libmysql/my_thr_init.c b/ext/mysql/libmysql/my_thr_init.c new file mode 100644 index 0000000000..c515822468 --- /dev/null +++ b/ext/mysql/libmysql/my_thr_init.c @@ -0,0 +1,177 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* +** Functions to handle initializating and allocationg of all mysys & debug +** thread variables. +*/ + +#include "mysys_priv.h" +#include <m_string.h> + +#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 +pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,THR_LOCK_keycache, + THR_LOCK_lock,THR_LOCK_isam,THR_LOCK_heap,THR_LOCK_net; +#ifndef HAVE_LOCALTIME_R +pthread_mutex_t LOCK_localtime_r; +#endif +#ifdef __WIN32__ +pthread_mutex_t THR_LOCK_thread; +#endif + +/* 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); + } + pthread_mutex_init(&THR_LOCK_malloc,NULL); + pthread_mutex_init(&THR_LOCK_open,NULL); + pthread_mutex_init(&THR_LOCK_keycache,NULL); + pthread_mutex_init(&THR_LOCK_lock,NULL); + pthread_mutex_init(&THR_LOCK_isam,NULL); + pthread_mutex_init(&THR_LOCK_heap,NULL); + pthread_mutex_init(&THR_LOCK_net,NULL); +#ifdef __WIN32__ + pthread_mutex_init(&THR_LOCK_thread,NULL); +#endif +#ifndef HAVE_LOCALTIME_R + pthread_mutex_init(&LOCK_localtime_r,NULL); +#endif + return my_thread_init(); +} + +void my_thread_global_end(void) +{ +#if defined(USE_TLS) + (void) TlsFree(THR_KEY_mysys); +#endif +} + +static long thread_id=0; + +my_bool my_thread_init(void) +{ + struct st_my_thread_var *tmp; + pthread_mutex_lock(&THR_LOCK_lock); +#if !defined(__WIN32__) || defined(USE_TLS) + if (my_pthread_getspecific(struct st_my_thread_var *,THR_KEY_mysys)) + { + pthread_mutex_unlock(&THR_LOCK_lock); + 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)))) + { + pthread_mutex_unlock(&THR_LOCK_lock); + return 1; + } + pthread_setspecific(THR_KEY_mysys,tmp); + +#else + if (THR_KEY_mysys.id) /* Allready initialized */ + { + pthread_mutex_unlock(&THR_LOCK_lock); + return 0; + } + tmp= &THR_KEY_mysys; +#endif + tmp->id= ++thread_id; + pthread_mutex_init(&tmp->mutex,NULL); + pthread_cond_init(&tmp->suspend, NULL); + pthread_mutex_unlock(&THR_LOCK_lock); + return 0; +} + +void my_thread_end(void) +{ + struct st_my_thread_var *tmp=my_thread_var; + if (tmp) + { +#if !defined(DBUG_OFF) + if (tmp->dbug) + { + 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); +#if !defined(__WIN32__) || defined(USE_TLS) + free(tmp); +#endif + } +#if !defined(__WIN32__) || defined(USE_TLS) + pthread_setspecific(THR_KEY_mysys,0); +#endif +} + +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) + /* This can only happen in a .DLL */ + 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__) + return pthread_self(); +#else + return my_thread_var->id; +#endif +} + +#ifdef DBUG_OFF +char *my_thread_name(void) +{ + return "no_name"; +} + +#else + +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; +} +#endif /* DBUG_OFF */ + +#endif /* THREAD */ diff --git a/ext/mysql/libmysql/my_write.c b/ext/mysql/libmysql/my_write.c new file mode 100644 index 0000000000..6ac221c194 --- /dev/null +++ b/ext/mysql/libmysql/my_write.c @@ -0,0 +1,63 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +#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 byte *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",writenbytes)); +#ifndef NO_BACKGROUND +#ifdef THREAD + if (my_thread_var->abort) + MyFlags&= ~ MY_WAIT_IF_FULL; /* End if aborted by user */ +#endif + if (my_errno == ENOSPC && (MyFlags & MY_WAIT_IF_FULL)) + { + if (!(errors++ % MY_WAIT_GIVE_USER_A_MESSAGE)) + my_error(EE_DISK_FULL,MYF(ME_BELL | ME_NOREFRESH), + my_filename(Filedes)); + VOID(sleep(MY_WAIT_FOR_USER_TO_FIX_PANIC)); + continue; + } + if ((writenbytes == 0 && my_errno == EINTR) || + (writenbytes > 0 && (uint) writenbytes != (uint) -1)) + continue; /* Retry */ +#endif + if (MyFlags & (MY_NABP | MY_FNABP)) + { + if (MyFlags & (MY_WME | MY_FAE | MY_FNABP)) + { + my_error(EE_WRITE, MYF(ME_BELL+ME_WAITTANG), + my_filename(Filedes),my_errno); + } + DBUG_RETURN(MY_FILE_ERROR); /* Error on read */ + } + else + break; /* Return bytes written */ + } + if (MyFlags & (MY_NABP | MY_FNABP)) + DBUG_RETURN(0); /* Want only errors */ + DBUG_RETURN(writenbytes+written); +} /* my_write */ diff --git a/ext/mysql/libmysql/mysql.h b/ext/mysql/libmysql/mysql.h new file mode 100644 index 0000000000..6f358da110 --- /dev/null +++ b/ext/mysql/libmysql/mysql.h @@ -0,0 +1,257 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* defines for the libmysql library */ + +#ifndef _mysql_h +#define _mysql_h + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _global_h /* If not standard header */ +#include <sys/types.h> +typedef char my_bool; +#if !defined(WIN32) +#define STDCALL +#else +#define STDCALL __stdcall +#endif +typedef char * gptr; + +#ifndef ST_USED_MEM_DEFINED +#define ST_USED_MEM_DEFINED +typedef struct st_used_mem { /* struct for once_alloc */ + struct st_used_mem *next; /* Next block in use */ + unsigned int left; /* memory left in block */ + unsigned int size; /* size of block */ +} USED_MEM; +typedef struct st_mem_root { + USED_MEM *free; + USED_MEM *used; + unsigned int min_malloc; + unsigned int block_size; + void (*error_handler)(void); +} MEM_ROOT; +#endif + +#ifndef my_socket_defined +#ifdef WIN32 +#define my_socket SOCKET +#else +typedef int my_socket; +#endif +#endif +#endif +#include "mysql_com.h" +#include "mysql_version.h" + +extern unsigned int mysql_port; +extern char *mysql_unix_port; + +#define IS_PRI_KEY(n) ((n) & PRI_KEY_FLAG) +#define IS_NOT_NULL(n) ((n) & NOT_NULL_FLAG) +#define IS_BLOB(n) ((n) & BLOB_FLAG) +#define IS_NUM(t) ((t) <= FIELD_TYPE_INT24 || (t) == FIELD_TYPE_YEAR) + +typedef struct st_mysql_field { + char *name; /* Name of column */ + char *table; /* Table of column if column was a field */ + char *def; /* Default value (set by mysql_list_fields) */ + enum enum_field_types type; /* Type of field. Se mysql_com.h for types */ + unsigned int length; /* Width of column */ + unsigned int max_length; /* Max width of selected set */ + unsigned int flags; /* Div flags */ + unsigned int decimals; /* Number of decimals in field */ +} MYSQL_FIELD; + +typedef char **MYSQL_ROW; /* return data as array of strings */ +typedef unsigned int MYSQL_FIELD_OFFSET; /* offset to current field */ + +#if defined(NO_CLIENT_LONG_LONG) +typedef unsigned long my_ulonglong; +#elif defined (WIN32) +typedef unsigned __int64 my_ulonglong; +#else +typedef unsigned long long my_ulonglong; +#endif + +#define MYSQL_COUNT_ERROR (~(my_ulonglong) 0) + +typedef struct st_mysql_rows { + struct st_mysql_rows *next; /* list of rows */ + MYSQL_ROW data; +} MYSQL_ROWS; + +typedef MYSQL_ROWS *MYSQL_ROW_OFFSET; /* offset to current row */ + +typedef struct st_mysql_data { + my_ulonglong rows; + unsigned int fields; + MYSQL_ROWS *data; + MEM_ROOT alloc; +} MYSQL_DATA; + +struct st_mysql_options { + unsigned int connect_timeout,client_flag; + my_bool compress,named_pipe; + unsigned int port; + char *host,*init_command,*user,*password,*unix_socket,*db; + char *my_cnf_file,*my_cnf_group; + my_bool use_ssl; /* if to use SSL or not */ + char *ssl_key; /* PEM key file */ + char *ssl_cert; /* PEM cert file */ + char *ssl_ca; /* PEM CA file */ + char *ssl_capath; /* PEM directory of CA-s? */ +}; + +enum mysql_option { MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS, + MYSQL_OPT_NAMED_PIPE, MYSQL_INIT_COMMAND, + MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP }; + +enum mysql_status { MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT, + MYSQL_STATUS_USE_RESULT}; + +typedef struct st_mysql { + NET net; /* Communication parameters */ + gptr connector_fd; /* ConnectorFd for SSL */ + char *host,*user,*passwd,*unix_socket,*server_version,*host_info, + *info,*db; + unsigned int port,client_flag,server_capabilities; + unsigned int protocol_version; + unsigned int field_count; + unsigned long thread_id; /* Id for connection in server */ + my_ulonglong affected_rows; + my_ulonglong insert_id; /* id if insert on table with NEXTNR */ + my_ulonglong extra_info; /* Used by mysqlshow */ + unsigned long packet_length; + enum mysql_status status; + MYSQL_FIELD *fields; + MEM_ROOT field_alloc; + my_bool free_me; /* If free in mysql_close */ + my_bool reconnect; /* set to 1 if automatic reconnect */ + struct st_mysql_options options; + char scramble_buff[9]; +} MYSQL; + + +typedef struct st_mysql_res { + my_ulonglong row_count; + unsigned int field_count, current_field; + MYSQL_FIELD *fields; + MYSQL_DATA *data; + MYSQL_ROWS *data_cursor; + MEM_ROOT field_alloc; + MYSQL_ROW row; /* If unbuffered read */ + MYSQL_ROW current_row; /* buffer to current row */ + unsigned long *lengths; /* column lengths of current row */ + MYSQL *handle; /* for unbuffered reads */ + my_bool eof; /* Used my mysql_fetch_row */ +} MYSQL_RES; + +/* Functions to get information from the MYSQL and MYSQL_RES structures */ +/* Should definitely be used if one uses shared libraries */ + +my_ulonglong mysql_num_rows(MYSQL_RES *res); +unsigned int mysql_num_fields(MYSQL_RES *res); +my_bool mysql_eof(MYSQL_RES *res); +MYSQL_FIELD *mysql_fetch_field_direct(MYSQL_RES *res,unsigned int fieldnr); +MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res); +MYSQL_ROWS *mysql_row_tell(MYSQL_RES *res); +unsigned int mysql_field_tell(MYSQL_RES *res); + +unsigned int mysql_field_count(MYSQL *mysql); +my_ulonglong mysql_affected_rows(MYSQL *mysql); +my_ulonglong mysql_insert_id(MYSQL *mysql); +unsigned int mysql_errno(MYSQL *mysql); +char *mysql_error(MYSQL *mysql); +char *mysql_info(MYSQL *mysql); +unsigned long mysql_thread_id(MYSQL *mysql); + +MYSQL * STDCALL mysql_init(MYSQL *mysql); +#ifdef HAVE_OPENSSL +int STDCALL mysql_ssl_set(MYSQL *mysql, const char *key, + const char *cert, const char *ca, + const char *capath); +char * STDCALL mysql_ssl_cipher(MYSQL *mysql); +int STDCALL mysql_ssl_clear(MYSQL *mysql); +#endif /* HAVE_OPENSSL */ +MYSQL * STDCALL mysql_connect(MYSQL *mysql, const char *host, + const char *user, const char *passwd); +my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, + const char *passwd, const char *db); +#if MYSQL_VERSION_ID >= 32200 +MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host, + const char *user, + const char *passwd, + const char *db, + unsigned int port, + const char *unix_socket, + unsigned int clientflag); +#else +MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host, + const char *user, + const char *passwd, + unsigned int port, + const char *unix_socket, + unsigned int clientflag); +#endif +void STDCALL mysql_close(MYSQL *sock); +int STDCALL mysql_select_db(MYSQL *mysql, const char *db); +int STDCALL mysql_query(MYSQL *mysql, const char *q); +int STDCALL mysql_real_query(MYSQL *mysql, const char *q, + unsigned int length); +int STDCALL mysql_create_db(MYSQL *mysql, const char *DB); +int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB); +int STDCALL mysql_shutdown(MYSQL *mysql); +int STDCALL mysql_dump_debug_info(MYSQL *mysql); +int STDCALL mysql_refresh(MYSQL *mysql, + unsigned int refresh_options); +int STDCALL mysql_kill(MYSQL *mysql,unsigned long pid); +int STDCALL mysql_ping(MYSQL *mysql); +char * STDCALL mysql_stat(MYSQL *mysql); +char * STDCALL mysql_get_server_info(MYSQL *mysql); +char * STDCALL mysql_get_client_info(void); +char * STDCALL mysql_get_host_info(MYSQL *mysql); +unsigned int STDCALL mysql_get_proto_info(MYSQL *mysql); +MYSQL_RES * STDCALL mysql_list_dbs(MYSQL *mysql,const char *wild); +MYSQL_RES * STDCALL mysql_list_tables(MYSQL *mysql,const char *wild); +MYSQL_RES * STDCALL mysql_list_fields(MYSQL *mysql, const char *table, + const char *wild); +MYSQL_RES * STDCALL mysql_list_processes(MYSQL *mysql); +MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql); +MYSQL_RES * STDCALL mysql_use_result(MYSQL *mysql); +int STDCALL mysql_options(MYSQL *mysql,enum mysql_option option, + const char *arg); +void STDCALL mysql_free_result(MYSQL_RES *result); +void STDCALL mysql_data_seek(MYSQL_RES *result, + my_ulonglong offset); +MYSQL_ROW_OFFSET STDCALL mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET); +MYSQL_FIELD_OFFSET STDCALL mysql_field_seek(MYSQL_RES *result, + MYSQL_FIELD_OFFSET offset); +MYSQL_ROW STDCALL mysql_fetch_row(MYSQL_RES *result); +unsigned long * STDCALL mysql_fetch_lengths(MYSQL_RES *result); +MYSQL_FIELD * STDCALL mysql_fetch_field(MYSQL_RES *result); +unsigned long STDCALL mysql_escape_string(char *to,const char *from, + unsigned long from_length); +void STDCALL mysql_debug(const char *debug); +char * STDCALL mysql_odbc_escape_string(char *to, unsigned long to_length, + const char *from, + unsigned long from_length, + void *param, + char * + (*extend_buffer) + (void *, char *to, + unsigned long *length)); + +#define mysql_reload(mysql) mysql_refresh((mysql),REFRESH_GRANT) + +/* new api functions */ + +#define HAVE_MYSQL_REAL_CONNECT + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ext/mysql/libmysql/mysql_com.h b/ext/mysql/libmysql/mysql_com.h new file mode 100644 index 0000000000..e652ff6e60 --- /dev/null +++ b/ext/mysql/libmysql/mysql_com.h @@ -0,0 +1,211 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* +** Common definition between mysql server & client +*/ + +#ifndef _mysql_com_h +#define _mysql_com_h + +#ifdef __cplusplus +extern "C" { +#endif + +#define NAME_LEN 64 /* Field/table name length */ +#define HOSTNAME_LENGTH 60 +#define USERNAME_LENGTH 16 + +#define LOCAL_HOST "localhost" +#define LOCAL_HOST_NAMEDPIPE "." + +#define MYSQL_PORT 3306 /* Alloced by ISI for MySQL */ +#define MYSQL_UNIX_ADDR "/var/tmp/mysql.sock" +#if defined(__EMX__) || defined(__OS2__) +#undef MYSQL_UNIX_ADDR +#define MYSQL_OS2_ADDR "\\socket\\MySQL" +#define MYSQL_UNIX_ADDR MYSQL_OS2_ADDR +#endif +#ifdef WIN32 +#define MYSQL_NAMEDPIPE "MySQL" +#define MYSQL_SERVICENAME "MySql" +#endif + +enum enum_server_command {COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY, + COM_FIELD_LIST,COM_CREATE_DB,COM_DROP_DB,COM_REFRESH, + COM_SHUTDOWN,COM_STATISTICS, + COM_PROCESS_INFO,COM_CONNECT,COM_PROCESS_KILL, + COM_DEBUG,COM_PING,COM_TIME,COM_DELAYED_INSERT, + COM_CHANGE_USER}; + +#define NOT_NULL_FLAG 1 /* Field can't be NULL */ +#define PRI_KEY_FLAG 2 /* Field is part of a primary key */ +#define UNIQUE_KEY_FLAG 4 /* Field is part of a unique key */ +#define MULTIPLE_KEY_FLAG 8 /* Field is part of a key */ +#define BLOB_FLAG 16 /* Field is a blob */ +#define UNSIGNED_FLAG 32 /* Field is unsigned */ +#define ZEROFILL_FLAG 64 /* Field is zerofill */ +#define BINARY_FLAG 128 +/* The following are only sent to new clients */ +#define ENUM_FLAG 256 /* field is an enum */ +#define AUTO_INCREMENT_FLAG 512 /* field is a autoincrement field */ +#define TIMESTAMP_FLAG 1024 /* Field is a timestamp */ +#define SET_FLAG 2048 /* field is a set */ +#define PART_KEY_FLAG 16384 /* Intern; Part of some key */ +#define GROUP_FLAG 32768 /* Intern: Group field */ +#define UNIQUE_FLAG 65536 /* Intern: Used by sql_yacc */ + +#define REFRESH_GRANT 1 /* Refresh grant tables */ +#define REFRESH_LOG 2 /* Start on new log file */ +#define REFRESH_TABLES 4 /* close all tables */ +#define REFRESH_HOSTS 8 /* Flush host cache */ +#define REFRESH_STATUS 16 /* Flush status variables */ +#define REFRESH_FAST 32768 /* Intern flag */ + +#define CLIENT_LONG_PASSWORD 1 /* new more secure passwords */ +#define CLIENT_FOUND_ROWS 2 /* Found instead of affected rows */ +#define CLIENT_LONG_FLAG 4 /* Get all column flags */ +#define CLIENT_CONNECT_WITH_DB 8 /* One can specify db on connect */ +#define CLIENT_NO_SCHEMA 16 /* Don't allow database.table.column */ +#define CLIENT_COMPRESS 32 /* Can use compression protocol */ +#define CLIENT_ODBC 64 /* Odbc client */ +#define CLIENT_LOCAL_FILES 128 /* Can use LOAD DATA LOCAL */ +#define CLIENT_IGNORE_SPACE 256 /* Ignore spaces before '(' */ +#define CLIENT_CHANGE_USER 512 /* Support the mysql_change_user() */ +#define CLIENT_INTERACTIVE 1024 /* This is an interactive client */ +#define CLIENT_SSL 2048 /* Switch to SSL after handshake */ +#define CLIENT_IGNORE_SIGPIPE 4096 /* IGNORE sigpipes */ + +#define MYSQL_ERRMSG_SIZE 200 +#define NET_READ_TIMEOUT 30 /* Timeout on read */ +#define NET_WRITE_TIMEOUT 60 /* Timeout on write */ +#define NET_WAIT_TIMEOUT 8*60*60 /* Wait for new query */ + +#ifndef Vio_defined +#define Vio_defined +#ifdef HAVE_VIO +class Vio; /* Fill Vio class in C++ */ +#else +struct st_vio; /* Only C */ +typedef struct st_vio Vio; +#endif +#endif + +typedef struct st_net { + Vio* vio; + my_socket fd; /* For Perl DBI/dbd */ + int fcntl; + unsigned char *buff,*buff_end,*write_pos,*read_pos; + char last_error[MYSQL_ERRMSG_SIZE]; + unsigned int last_errno,max_packet,timeout,pkt_nr; + my_bool error,return_errno,compress; + + unsigned long remain_in_buf,length, buf_length, where_b; + my_bool more; + char save_char; +} NET; + +#define packet_error ((unsigned int) -1) + +enum enum_field_types { FIELD_TYPE_DECIMAL, FIELD_TYPE_TINY, + FIELD_TYPE_SHORT, FIELD_TYPE_LONG, + FIELD_TYPE_FLOAT, FIELD_TYPE_DOUBLE, + FIELD_TYPE_NULL, FIELD_TYPE_TIMESTAMP, + FIELD_TYPE_LONGLONG,FIELD_TYPE_INT24, + FIELD_TYPE_DATE, FIELD_TYPE_TIME, + FIELD_TYPE_DATETIME, FIELD_TYPE_YEAR, + FIELD_TYPE_NEWDATE, + FIELD_TYPE_ENUM=247, + FIELD_TYPE_SET=248, + FIELD_TYPE_TINY_BLOB=249, + FIELD_TYPE_MEDIUM_BLOB=250, + FIELD_TYPE_LONG_BLOB=251, + FIELD_TYPE_BLOB=252, + FIELD_TYPE_VAR_STRING=253, + FIELD_TYPE_STRING=254 +}; + +#define FIELD_TYPE_CHAR FIELD_TYPE_TINY /* For compability */ +#define FIELD_TYPE_INTERVAL FIELD_TYPE_ENUM /* For compability */ + +extern unsigned long max_allowed_packet; +extern unsigned long net_buffer_length; + +#define net_new_transaction(net) ((net)->pkt_nr=0) + +int my_net_init(NET *net, Vio* vio); +void net_end(NET *net); +void net_clear(NET *net); +int net_flush(NET *net); +int my_net_write(NET *net,const char *packet,unsigned long len); +int net_write_command(NET *net,unsigned char command,const char *packet, + unsigned long len); +int net_real_write(NET *net,const char *packet,unsigned long len); +unsigned int my_net_read(NET *net); + +struct rand_struct { + unsigned long seed1,seed2,max_value; + double max_value_dbl; +}; + + /* The following is for user defined functions */ + +enum Item_result {STRING_RESULT,REAL_RESULT,INT_RESULT}; + +typedef struct st_udf_args +{ + unsigned int arg_count; /* Number of arguments */ + enum Item_result *arg_type; /* Pointer to item_results */ + char **args; /* Pointer to argument */ + unsigned long *lengths; /* Length of string arguments */ + char *maybe_null; /* Set to 1 for all maybe_null args */ +} UDF_ARGS; + + /* This holds information about the result */ + +typedef struct st_udf_init +{ + my_bool maybe_null; /* 1 if function can return NULL */ + unsigned int decimals; /* for real functions */ + unsigned int max_length; /* For string functions */ + char *ptr; /* free pointer for function data */ + my_bool const_item; /* 0 if result is independent of arguments */ +} UDF_INIT; + + /* Constants when using compression */ +#define NET_HEADER_SIZE 4 /* standard header size */ +#define COMP_HEADER_SIZE 3 /* compression header extra size */ + + /* Prototypes to password functions */ + +void randominit(struct rand_struct *,unsigned long seed1, + unsigned long seed2); +double rnd(struct rand_struct *); +void make_scrambled_password(char *to,const char *password); +void get_salt_from_password(unsigned long *res,const char *password); +void make_password_from_salt(char *to, unsigned long *hash_res); +char *scramble(char *to,const char *message,const char *password, + my_bool old_ver); +my_bool check_scramble(const char *, const char *message, + unsigned long *salt,my_bool old_ver); +char *get_tty_password(char *opt_message); +void hash_password(unsigned long *result, const char *password); + +/* Some other useful functions */ + +void my_init(void); +void load_defaults(const char *conf_file, const char **groups, + int *argc, char ***argv); + +#define NULL_LENGTH ((unsigned long) ~0) /* For net_store_length */ + +#ifdef WIN32 +#define socket_errno WSAGetLastError() +#else +#define socket_errno errno +#endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ext/mysql/libmysql/mysql_version.h b/ext/mysql/libmysql/mysql_version.h new file mode 100644 index 0000000000..b07e587aff --- /dev/null +++ b/ext/mysql/libmysql/mysql_version.h @@ -0,0 +1,10 @@ +/* Copyright Abandoned 1996,1999 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* Version numbers for protocol & mysqld */ + +#define MYSQL_SERVER_VERSION "3.23.10-alpha" +#define FRM_VER 6 +#define MYSQL_VERSION_ID 32310 +/* mysqld compile time options */ +#define MYSQL_CHARSET "latin1" diff --git a/ext/mysql/libmysql/mysqld_error.h b/ext/mysql/libmysql/mysqld_error.h new file mode 100644 index 0000000000..da19af6138 --- /dev/null +++ b/ext/mysql/libmysql/mysqld_error.h @@ -0,0 +1,179 @@ +/* Definefile for errormessagenumbers */ + +#define ER_HASHCHK 1000 +#define ER_NISAMCHK 1001 +#define ER_NO 1002 +#define ER_YES 1003 +#define ER_CANT_CREATE_FILE 1004 +#define ER_CANT_CREATE_TABLE 1005 +#define ER_CANT_CREATE_DB 1006 +#define ER_DB_CREATE_EXISTS 1007 +#define ER_DB_DROP_EXISTS 1008 +#define ER_DB_DROP_DELETE 1009 +#define ER_DB_DROP_RMDIR 1010 +#define ER_CANT_DELETE_FILE 1011 +#define ER_CANT_FIND_SYSTEM_REC 1012 +#define ER_CANT_GET_STAT 1013 +#define ER_CANT_GET_WD 1014 +#define ER_CANT_LOCK 1015 +#define ER_CANT_OPEN_FILE 1016 +#define ER_FILE_NOT_FOUND 1017 +#define ER_CANT_READ_DIR 1018 +#define ER_CANT_SET_WD 1019 +#define ER_CHECKREAD 1020 +#define ER_DISK_FULL 1021 +#define ER_DUP_KEY 1022 +#define ER_ERROR_ON_CLOSE 1023 +#define ER_ERROR_ON_READ 1024 +#define ER_ERROR_ON_RENAME 1025 +#define ER_ERROR_ON_WRITE 1026 +#define ER_FILE_USED 1027 +#define ER_FILSORT_ABORT 1028 +#define ER_FORM_NOT_FOUND 1029 +#define ER_GET_ERRNO 1030 +#define ER_ILLEGAL_HA 1031 +#define ER_KEY_NOT_FOUND 1032 +#define ER_NOT_FORM_FILE 1033 +#define ER_NOT_KEYFILE 1034 +#define ER_OLD_KEYFILE 1035 +#define ER_OPEN_AS_READONLY 1036 +#define ER_OUTOFMEMORY 1037 +#define ER_OUT_OF_SORTMEMORY 1038 +#define ER_UNEXPECTED_EOF 1039 +#define ER_CON_COUNT_ERROR 1040 +#define ER_OUT_OF_RESOURCES 1041 +#define ER_BAD_HOST_ERROR 1042 +#define ER_HANDSHAKE_ERROR 1043 +#define ER_DBACCESS_DENIED_ERROR 1044 +#define ER_ACCESS_DENIED_ERROR 1045 +#define ER_NO_DB_ERROR 1046 +#define ER_UNKNOWN_COM_ERROR 1047 +#define ER_BAD_NULL_ERROR 1048 +#define ER_BAD_DB_ERROR 1049 +#define ER_TABLE_EXISTS_ERROR 1050 +#define ER_BAD_TABLE_ERROR 1051 +#define ER_NON_UNIQ_ERROR 1052 +#define ER_SERVER_SHUTDOWN 1053 +#define ER_BAD_FIELD_ERROR 1054 +#define ER_WRONG_FIELD_WITH_GROUP 1055 +#define ER_WRONG_GROUP_FIELD 1056 +#define ER_WRONG_SUM_SELECT 1057 +#define ER_WRONG_VALUE_COUNT 1058 +#define ER_TOO_LONG_IDENT 1059 +#define ER_DUP_FIELDNAME 1060 +#define ER_DUP_KEYNAME 1061 +#define ER_DUP_ENTRY 1062 +#define ER_WRONG_FIELD_SPEC 1063 +#define ER_PARSE_ERROR 1064 +#define ER_EMPTY_QUERY 1065 +#define ER_NONUNIQ_TABLE 1066 +#define ER_INVALID_DEFAULT 1067 +#define ER_MULTIPLE_PRI_KEY 1068 +#define ER_TOO_MANY_KEYS 1069 +#define ER_TOO_MANY_KEY_PARTS 1070 +#define ER_TOO_LONG_KEY 1071 +#define ER_KEY_COLUMN_DOES_NOT_EXITS 1072 +#define ER_BLOB_USED_AS_KEY 1073 +#define ER_TOO_BIG_FIELDLENGTH 1074 +#define ER_WRONG_AUTO_KEY 1075 +#define ER_READY 1076 +#define ER_NORMAL_SHUTDOWN 1077 +#define ER_GOT_SIGNAL 1078 +#define ER_SHUTDOWN_COMPLETE 1079 +#define ER_FORCING_CLOSE 1080 +#define ER_IPSOCK_ERROR 1081 +#define ER_NO_SUCH_INDEX 1082 +#define ER_WRONG_FIELD_TERMINATORS 1083 +#define ER_BLOBS_AND_NO_TERMINATED 1084 +#define ER_TEXTFILE_NOT_READABLE 1085 +#define ER_FILE_EXISTS_ERROR 1086 +#define ER_LOAD_INFO 1087 +#define ER_ALTER_INFO 1088 +#define ER_WRONG_SUB_KEY 1089 +#define ER_CANT_REMOVE_ALL_FIELDS 1090 +#define ER_CANT_DROP_FIELD_OR_KEY 1091 +#define ER_INSERT_INFO 1092 +#define ER_INSERT_TABLE_USED 1093 +#define ER_NO_SUCH_THREAD 1094 +#define ER_KILL_DENIED_ERROR 1095 +#define ER_NO_TABLES_USED 1096 +#define ER_TOO_BIG_SET 1097 +#define ER_NO_UNIQUE_LOGFILE 1098 +#define ER_TABLE_NOT_LOCKED_FOR_WRITE 1099 +#define ER_TABLE_NOT_LOCKED 1100 +#define ER_BLOB_CANT_HAVE_DEFAULT 1101 +#define ER_WRONG_DB_NAME 1102 +#define ER_WRONG_TABLE_NAME 1103 +#define ER_TOO_BIG_SELECT 1104 +#define ER_UNKNOWN_ERROR 1105 +#define ER_UNKNOWN_PROCEDURE 1106 +#define ER_WRONG_PARAMCOUNT_TO_PROCEDURE 1107 +#define ER_WRONG_PARAMETERS_TO_PROCEDURE 1108 +#define ER_UNKNOWN_TABLE 1109 +#define ER_FIELD_SPECIFIED_TWICE 1110 +#define ER_INVALID_GROUP_FUNC_USE 1111 +#define ER_UNSUPPORTED_EXTENSION 1112 +#define ER_TABLE_MUST_HAVE_COLUMNS 1113 +#define ER_RECORD_FILE_FULL 1114 +#define ER_UNKNOWN_CHARACTER_SET 1115 +#define ER_TOO_MANY_TABLES 1116 +#define ER_TOO_MANY_FIELDS 1117 +#define ER_TOO_BIG_ROWSIZE 1118 +#define ER_STACK_OVERRUN 1119 +#define ER_WRONG_OUTER_JOIN 1120 +#define ER_NULL_COLUMN_IN_INDEX 1121 +#define ER_CANT_FIND_UDF 1122 +#define ER_CANT_INITIALIZE_UDF 1123 +#define ER_UDF_NO_PATHS 1124 +#define ER_UDF_EXISTS 1125 +#define ER_CANT_OPEN_LIBRARY 1126 +#define ER_CANT_FIND_DL_ENTRY 1127 +#define ER_FUNCTION_NOT_DEFINED 1128 +#define ER_HOST_IS_BLOCKED 1129 +#define ER_HOST_NOT_PRIVILEGED 1130 +#define ER_PASSWORD_ANONYMOUS_USER 1131 +#define ER_PASSWORD_NOT_ALLOWED 1132 +#define ER_PASSWORD_NO_MATCH 1133 +#define ER_UPDATE_INFO 1134 +#define ER_CANT_CREATE_THREAD 1135 +#define ER_WRONG_VALUE_COUNT_ON_ROW 1136 +#define ER_CANT_REOPEN_TABLE 1137 +#define ER_INVALID_USE_OF_NULL 1138 +#define ER_REGEXP_ERROR 1139 +#define ER_MIX_OF_GROUP_FUNC_AND_FIELDS 1140 +#define ER_NONEXISTING_GRANT 1141 +#define ER_TABLEACCESS_DENIED_ERROR 1142 +#define ER_COLUMNACCESS_DENIED_ERROR 1143 +#define ER_ILLEGAL_GRANT_FOR_TABLE 1144 +#define ER_GRANT_WRONG_HOST_OR_USER 1145 +#define ER_NO_SUCH_TABLE 1146 +#define ER_NONEXISTING_TABLE_GRANT 1147 +#define ER_NOT_ALLOWED_COMMAND 1148 +#define ER_SYNTAX_ERROR 1149 +#define ER_DELAYED_CANT_CHANGE_LOCK 1150 +#define ER_TOO_MANY_DELAYED_THREADS 1151 +#define ER_ABORTING_CONNECTION 1152 +#define ER_NET_PACKET_TOO_LARGE 1153 +#define ER_NET_READ_ERROR_FROM_PIPE 1154 +#define ER_NET_FCNTL_ERROR 1155 +#define ER_NET_PACKETS_OUT_OF_ORDER 1156 +#define ER_NET_UNCOMPRESS_ERROR 1157 +#define ER_NET_READ_ERROR 1158 +#define ER_NET_READ_INTERRUPTED 1159 +#define ER_NET_ERROR_ON_WRITE 1160 +#define ER_NET_WRITE_INTERRUPTED 1161 +#define ER_TOO_LONG_STRING 1162 +#define ER_TABLE_CANT_HANDLE_BLOB 1163 +#define ER_TABLE_CANT_HANDLE_AUTO_INCREMENT 1164 +#define ER_DELAYED_INSERT_TABLE_LOCKED 1165 +#define ER_WRONG_COLUMN_NAME 1166 +#define ER_WRONG_KEY_COLUMN 1167 +#define ER_WRONG_MRG_TABLE 1168 +#define ER_DUP_UNIQUE 1169 +#define ER_BLOB_KEY_WITHOUT_LENGTH 1170 +#define ER_PRIMARY_CANT_HAVE_NULL 1171 +#define ER_TOO_MANY_ROWS 1172 +#define ER_REQUIRES_PRIMARY_KEY 1173 +#define ER_NO_RAID_COMPILED 1174 +#define ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE 1175 +#define ER_ERROR_MESSAGES 176 diff --git a/ext/mysql/libmysql/mysys_err.h b/ext/mysql/libmysql/mysys_err.h new file mode 100644 index 0000000000..7264f21906 --- /dev/null +++ b/ext/mysql/libmysql/mysys_err.h @@ -0,0 +1,42 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +#ifndef _mysys_err_h +#define _mysys_err_h +#ifdef __cplusplus +extern "C" { +#endif + +#define GLOB 0 /* Error maps */ +#define GLOBERRS 22 /* Max number of error messages in map's */ +#define EE(X) globerrs[ X ] /* Defines to add error to right map */ + +extern const char * NEAR globerrs[]; /* my_error_messages is here */ + +/* Error message numbers in global map */ +#define EE_FILENOTFOUND 0 +#define EE_CANTCREATEFILE 1 +#define EE_READ 2 +#define EE_WRITE 3 +#define EE_BADCLOSE 4 +#define EE_OUTOFMEMORY 5 +#define EE_DELETE 6 +#define EE_LINK 7 +#define EE_EOFERR 9 +#define EE_CANTLOCK 10 +#define EE_CANTUNLOCK 11 +#define EE_DIR 12 +#define EE_STAT 13 +#define EE_CANT_CHSIZE 14 +#define EE_CANT_OPEN_STREAM 15 +#define EE_GETWD 16 +#define EE_SETWD 17 +#define EE_LINK_WARNING 18 +#define EE_OPEN_WARNING 19 +#define EE_DISK_FULL 20 +#define EE_CANT_MKDIR 21 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ext/mysql/libmysql/mysys_priv.h b/ext/mysql/libmysql/mysys_priv.h new file mode 100644 index 0000000000..86bc74f38b --- /dev/null +++ b/ext/mysql/libmysql/mysys_priv.h @@ -0,0 +1,13 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +#include <global.h> +#include <my_sys.h> + +#ifdef THREAD +extern pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,THR_LOCK_keycache, + THR_LOCK_lock,THR_LOCK_isam,THR_LOCK_net; +#else /* THREAD */ +#define pthread_mutex_lock(A) +#define pthread_mutex_unlock(A) +#endif diff --git a/ext/mysql/libmysql/safemalloc.c b/ext/mysql/libmysql/safemalloc.c new file mode 100644 index 0000000000..5a44745bed --- /dev/null +++ b/ext/mysql/libmysql/safemalloc.c @@ -0,0 +1,503 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* + * [This posting refers to an article entitled "oops, corrupted memory + * again!" in net.lang.c. I am posting it here because it is source.] + * + * My tool for approaching this problem is to build another level of data + * abstraction on top of malloc() and free() that implements some checking. + * This does a number of things for you: + * - Checks for overruns and underruns on allocated data + * - Keeps track of where in the program the memory was malloc'ed + * - Reports on pieces of memory that were not free'ed + * - Records some statistics such as maximum memory used + * - Marks newly malloc'ed and newly free'ed memory with special values + * You can use this scheme to: + * - Find bugs such as overrun, underrun, etc because you know where + * a piece of data was malloc'ed and where it was free'ed + * - Find bugs where memory was not free'ed + * - Find bugs where newly malloc'ed memory is used without initializing + * - Find bugs where newly free'ed memory is still used + * - Determine how much memory your program really uses + * - and other things + */ + +/* + * To implement my scheme you must have a C compiler that has __LINE__ and + * __FILE__ macros. If your compiler doesn't have these then (a) buy another: + * compilers that do are available on UNIX 4.2bsd based systems and the PC, + * and probably on other machines; or (b) change my scheme somehow. I have + * recomendations on both these points if you would like them (e-mail please). + * + * There are 4 functions in my package: + * char *NEW( uSize ) Allocate memory of uSize bytes + * (equivalent to malloc()) + * char *REA( pPtr, uSize) Allocate memory of uSize bytes, move data and + * free pPtr. + * (equivalent to realloc()) + * FREE( pPtr ) Free memory allocated by NEW + * (equivalent to free()) + * TERMINATE(file) End system, report errors and stats on file + * I personally use two more functions, but have not included them here: + * char *STRSAVE( sPtr ) Save a copy of the string in dynamic memory + * char *RENEW( pPtr, uSize ) + * (equivalent to realloc()) + */ + +/* + * Memory sub-system, written by Bjorn Benson + Fixed to use my_sys scheme by Michael Widenius + */ + +#ifndef SAFEMALLOC +#define SAFEMALLOC /* Get protos from my_sys */ +#endif + +#include "mysys_priv.h" +#include <m_string.h> +#include "my_static.h" +#include "mysys_err.h" + +#define pNext tInt._pNext +#define pPrev tInt._pPrev +#define sFileName tInt._sFileName +#define uLineNum tInt._uLineNum +#define uDataSize tInt._uDataSize +#define lSpecialValue tInt._lSpecialValue + + /* Static functions prototypes */ + +static int check_ptr(const char *where, byte *ptr, const char *sFile, + uint uLine); +static int _checkchunk(struct remember *pRec, const char *sFile, uint uLine); + +/* + * Note: both these refer to the NEW'ed + * data only. They do not include + * malloc() roundoff or the extra + * space required by the remember + * structures. + */ + +#define ALLOC_VAL (uchar) 0xA5 /* NEW'ed memory is filled with this */ + /* value so that references to it will */ + /* end up being very strange. */ +#define FREE_VAL (uchar) 0x8F /* FREE'ed memory is filled with this */ + /* value so that references to it will */ + /* also end up being strange. */ + +#define MAGICKEY 0x14235296 /* A magic value for underrun key */ +#define MAGICEND0 0x68 /* Magic values for overrun keys */ +#define MAGICEND1 0x34 /* " */ +#define MAGICEND2 0x7A /* " */ +#define MAGICEND3 0x15 /* " */ + + /* Warning: do not change the MAGICEND? values to */ + /* something with the high bit set. Various C */ + /* compilers (like the 4.2bsd one) do not do the */ + /* sign extension right later on in this code and */ + /* you will get erroneous errors. */ + + +/* + * gptr _mymalloc( uint uSize, my_string sFile, uint uLine, MyFlags ) + * Allocate some memory. + */ + +gptr _mymalloc (uint uSize, const char *sFile, uint uLine, myf MyFlags) +{ + struct remember *pTmp; + DBUG_ENTER("_mymalloc"); + DBUG_PRINT("enter",("Size: %u",uSize)); + + if (!sf_malloc_quick) + (void) _sanity (sFile, uLine); + + /* Allocate the physical memory */ + pTmp = (struct remember *) malloc ( + sizeof (struct irem) /* remember data */ + + sf_malloc_prehunc + + uSize /* size requested */ + + 4 /* overrun mark */ + + sf_malloc_endhunc + ); + + /* Check if there isn't anymore memory avaiable */ + if (pTmp == NULL) + { + if (MyFlags & MY_FAE) + error_handler_hook=fatal_error_handler_hook; + if (MyFlags & (MY_FAE+MY_WME)) + { + char buff[SC_MAXWIDTH]; + my_errno=errno; + sprintf(buff,"Out of memory at line %d, '%s'", uLine, sFile); + my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG)); + sprintf(buff,"needed %d byte (%ldk), memory in use: %ld bytes (%ldk)", + uSize, (uSize + 1023L) / 1024L, + lMaxMemory, (lMaxMemory + 1023L) / 1024L); + my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG)); + } + DBUG_PRINT("error",("Out of memory, in use: %ld at line %d, '%s'", + lMaxMemory,uLine, sFile)); + if (MyFlags & MY_FAE) + exit(1); + DBUG_RETURN ((gptr) NULL); + } + + /* Fill up the structure */ + *((long*) ((char*) &pTmp -> lSpecialValue+sf_malloc_prehunc)) = MAGICKEY; + pTmp -> aData[uSize + sf_malloc_prehunc+0] = MAGICEND0; + pTmp -> aData[uSize + sf_malloc_prehunc+1] = MAGICEND1; + pTmp -> aData[uSize + sf_malloc_prehunc+2] = MAGICEND2; + pTmp -> aData[uSize + sf_malloc_prehunc+3] = MAGICEND3; + pTmp -> sFileName = (my_string) sFile; + pTmp -> uLineNum = uLine; + pTmp -> uDataSize = uSize; + pTmp -> pPrev = NULL; + + /* Add this remember structure to the linked list */ + pthread_mutex_lock(&THR_LOCK_malloc); + if ((pTmp->pNext=pRememberRoot)) + { + pRememberRoot -> pPrev = pTmp; + } + pRememberRoot = pTmp; + + /* Keep the statistics */ + lCurMemory += uSize; + if (lCurMemory > lMaxMemory) { + lMaxMemory = lCurMemory; + } + cNewCount++; + pthread_mutex_unlock(&THR_LOCK_malloc); + + /* Set the memory to the aribtrary wierd value */ +#ifdef HAVE_purify + if (MyFlags & MY_ZEROFILL) +#endif + bfill(&pTmp -> aData[sf_malloc_prehunc],uSize, + (char) (MyFlags & MY_ZEROFILL ? 0 : ALLOC_VAL)); + /* Return a pointer to the real data */ + DBUG_PRINT("exit",("ptr: %lx",&(pTmp -> aData[sf_malloc_prehunc]))); + if (sf_min_adress > &(pTmp -> aData[sf_malloc_prehunc])) + sf_min_adress = &(pTmp -> aData[sf_malloc_prehunc]); + if (sf_max_adress < &(pTmp -> aData[sf_malloc_prehunc])) + sf_max_adress = &(pTmp -> aData[sf_malloc_prehunc]); + DBUG_RETURN ((gptr) &(pTmp -> aData[sf_malloc_prehunc])); +} + +/* + * Allocate some new memory and move old memoryblock there. + * Free then old memoryblock + */ + +gptr _myrealloc (register my_string pPtr, register uint uSize, + const char *sFile, uint uLine, myf MyFlags) +{ + struct remember *pRec; + gptr ptr; + DBUG_ENTER("_myrealloc"); + + if (!pPtr && (MyFlags & MY_ALLOW_ZERO_PTR)) + DBUG_RETURN(_mymalloc(uSize,sFile,uLine,MyFlags)); + + if (!sf_malloc_quick) + (void) _sanity (sFile, uLine); + + if (check_ptr("Reallocating",(byte*) pPtr,sFile,uLine)) + DBUG_RETURN((gptr) NULL); + + pRec = (struct remember *) (pPtr - sizeof (struct irem)-sf_malloc_prehunc); + if (*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc)) + != MAGICKEY) + { + fprintf (stderr, "Reallocating unallocated data at line %d, '%s'\n", + uLine, sFile); + DBUG_PRINT("safe",("Reallocating unallocated data at line %d, '%s'", + uLine, sFile)); + (void) fflush(stderr); + DBUG_RETURN((gptr) NULL); + } + + if ((ptr=_mymalloc(uSize,sFile,uLine,MyFlags))) /* Allocate new area */ + { + uSize=min(uSize,pRec-> uDataSize); /* Move as much as possibly */ + memcpy((byte*) ptr,pPtr,(size_t) uSize); /* Copy old data */ + _myfree(pPtr,sFile,uLine,0); /* Free not needed area */ + } + else + { + if (MyFlags & MY_HOLD_ON_ERROR) + DBUG_RETURN(pPtr); + if (MyFlags & MY_FREE_ON_ERROR) + _myfree(pPtr,sFile,uLine,0); + } + DBUG_RETURN(ptr); +} /* _myrealloc */ + + +/* + * void _myfree( my_string pPtr, my_string sFile, uint uLine, myf myflags) + * Deallocate some memory. + */ + +void _myfree (gptr pPtr, const char *sFile, uint uLine, myf myflags) +{ + struct remember *pRec; + DBUG_ENTER("_myfree"); + DBUG_PRINT("enter",("ptr: %lx",pPtr)); + + if (!sf_malloc_quick) + (void) _sanity (sFile, uLine); + + if ((!pPtr && (myflags & MY_ALLOW_ZERO_PTR)) || + check_ptr("Freeing",(byte*) pPtr,sFile,uLine)) + DBUG_VOID_RETURN; + + /* Calculate the address of the remember structure */ + pRec = (struct remember *) ((byte*) pPtr-sizeof(struct irem)- + sf_malloc_prehunc); + + /* Check to make sure that we have a real remember structure */ + /* Note: this test could fail for four reasons: */ + /* (1) The memory was already free'ed */ + /* (2) The memory was never new'ed */ + /* (3) There was an underrun */ + /* (4) A stray pointer hit this location */ + + if (*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc)) + != MAGICKEY) + { + fprintf (stderr, "Freeing unallocated data at line %d, '%s'\n", + uLine, sFile); + DBUG_PRINT("safe",("Unallocated data at line %d, '%s'",uLine,sFile)); + (void) fflush(stderr); + DBUG_VOID_RETURN; + } + + /* Remove this structure from the linked list */ + pthread_mutex_lock(&THR_LOCK_malloc); + if (pRec -> pPrev) { + pRec -> pPrev -> pNext = pRec -> pNext; + } else { + pRememberRoot = pRec -> pNext; + } + if (pRec -> pNext) { + pRec -> pNext -> pPrev = pRec -> pPrev; + } + /* Handle the statistics */ + lCurMemory -= pRec -> uDataSize; + cNewCount--; + pthread_mutex_unlock(&THR_LOCK_malloc); + +#ifndef HAVE_purify + /* Mark this data as free'ed */ + bfill(&pRec->aData[sf_malloc_prehunc],pRec->uDataSize,(pchar) FREE_VAL); +#endif + *((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc)) = ~MAGICKEY; + + /* Actually free the memory */ + free ((my_string ) pRec); + DBUG_VOID_RETURN; +} + + /* Check if we have a wrong pointer */ + +static int check_ptr(const char *where, byte *ptr, const char *sFile, + uint uLine) +{ + if (!ptr) + { + fprintf (stderr, "%s NULL pointer at line %d, '%s'\n", + where,uLine, sFile); + DBUG_PRINT("safe",("Null pointer at line %d '%s'", uLine, sFile)); + (void) fflush(stderr); + return 1; + } +#ifndef _MSC_VER + if ((long) ptr & (MY_ALIGN(1,sizeof(char *))-1)) + { + fprintf (stderr, "%s wrong aligned pointer at line %d, '%s'\n", + where,uLine, sFile); + DBUG_PRINT("safe",("Wrong aligned pointer at line %d, '%s'", + uLine,sFile)); + (void) fflush(stderr); + return 1; + } +#endif + if (ptr < sf_min_adress || ptr > sf_max_adress) + { + fprintf (stderr, "%s pointer out of range at line %d, '%s'\n", + where,uLine, sFile); + DBUG_PRINT("safe",("Pointer out of range at line %d '%s'", + uLine,sFile)); + (void) fflush(stderr); + return 1; + } + return 0; +} + + +/* + * TERMINATE(FILE *file) + * Report on all the memory pieces that have not been + * free'ed as well as the statistics. + */ + +void TERMINATE (FILE *file) +{ + struct remember *pPtr; + DBUG_ENTER("TERMINATE"); + pthread_mutex_lock(&THR_LOCK_malloc); + + /* Report the difference between number of calls to */ + /* NEW and the number of calls to FREE. >0 means more */ + /* NEWs than FREEs. <0, etc. */ + + if (cNewCount) + { + if (file) + { + fprintf (file, "cNewCount: %d\n", cNewCount); + (void) fflush(file); + } + DBUG_PRINT("safe",("cNewCount: %d",cNewCount)); + } + + /* Report on all the memory that was allocated with NEW */ + /* but not free'ed with FREE. */ + + if ((pPtr=pRememberRoot)) + { + if (file) + { + fprintf(file, "Memory that was not free'ed (%ld bytes):\n",lCurMemory); + (void) fflush(file); + } + DBUG_PRINT("safe",("Memory that was not free'ed (%ld bytes):",lCurMemory)); + while (pPtr) + { + if (file) + { + fprintf (file, + "\t%6u bytes at 0x%09lx, allocated at line %4u in '%s'\n", + pPtr -> uDataSize, + (ulong) &(pPtr -> aData[sf_malloc_prehunc]), + pPtr -> uLineNum, pPtr -> sFileName); + (void) fflush(file); + } + DBUG_PRINT("safe", + ("%6u bytes at 0x%09lx, allocated at line %4d in '%s'", + pPtr -> uDataSize, &(pPtr -> aData[sf_malloc_prehunc]), + pPtr -> uLineNum, pPtr -> sFileName)); + pPtr = pPtr -> pNext; + } + } + /* Report the memory usage statistics */ + if (file) + { + fprintf (file, "Maximum memory usage: %ld bytes (%ldk)\n", + lMaxMemory, (lMaxMemory + 1023L) / 1024L); + (void) fflush(file); + } + DBUG_PRINT("safe",("Maximum memory usage: %ld bytes (%ldk)", + lMaxMemory, (lMaxMemory + 1023L) / 1024L)); + pthread_mutex_unlock(&THR_LOCK_malloc); + DBUG_VOID_RETURN; +} + + + /* Returns 0 if chunk is ok */ + +static int _checkchunk (register struct remember *pRec, const char *sFile, + uint uLine) +{ + reg1 uint uSize; + reg2 my_string magicp; + reg3 int flag=0; + + /* Check for a possible underrun */ + if (*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc)) + != MAGICKEY) + { + fprintf (stderr, "Memory allocated at %s:%d was underrun,", + pRec -> sFileName, pRec -> uLineNum); + fprintf (stderr, " discovered at %s:%d\n", sFile, uLine); + (void) fflush(stderr); + DBUG_PRINT("safe",("Underrun at %lx, allocated at %s:%d", + &(pRec -> aData[sf_malloc_prehunc]), + pRec -> sFileName, + pRec -> uLineNum)); + flag=1; + } + + /* Check for a possible overrun */ + uSize = pRec -> uDataSize; + magicp = &(pRec -> aData[uSize+sf_malloc_prehunc]); + if (*magicp++ != MAGICEND0 || + *magicp++ != MAGICEND1 || + *magicp++ != MAGICEND2 || + *magicp++ != MAGICEND3) + { + fprintf (stderr, "Memory allocated at %s:%d was overrun,", + pRec -> sFileName, pRec -> uLineNum); + fprintf (stderr, " discovered at '%s:%d'\n", sFile, uLine); + (void) fflush(stderr); + DBUG_PRINT("safe",("Overrun at %lx, allocated at %s:%d", + &(pRec -> aData[sf_malloc_prehunc]), + pRec -> sFileName, + pRec -> uLineNum)); + flag=1; + } + return(flag); +} + + + /* Returns how many wrong chunks */ + +int _sanity (const char *sFile, uint uLine) +{ + reg1 struct remember *pTmp; + reg2 int flag=0; + uint count=0; + + pthread_mutex_lock(&THR_LOCK_malloc); + count=cNewCount; + for (pTmp = pRememberRoot; pTmp != NULL && count-- ; pTmp = pTmp -> pNext) + flag+=_checkchunk (pTmp, sFile, uLine); + if (count || pTmp) + { + const char *format="Safemalloc link list destroyed, discovered at '%s:%d'"; + fprintf (stderr, format, sFile, uLine); fputc('\n',stderr); + (void) fflush(stderr); + DBUG_PRINT("safe",(format, sFile, uLine)); + flag=1; + } + pthread_mutex_unlock(&THR_LOCK_malloc); + return flag; +} /* _sanity */ + + + /* malloc and copy */ + +gptr _my_memdup(const byte *from, uint length, const char *sFile, uint uLine, + myf MyFlags) +{ + gptr ptr; + if ((ptr=_mymalloc(length,sFile,uLine,MyFlags)) != 0) + memcpy((byte*) ptr, (byte*) from,(size_t) length); + return(ptr); +} /*_my_memdup */ + + +my_string _my_strdup(const char *from, const char *sFile, uint uLine, + myf MyFlags) +{ + gptr ptr; + uint length=(uint) strlen(from)+1; + if ((ptr=_mymalloc(length,sFile,uLine,MyFlags)) != 0) + memcpy((byte*) ptr, (byte*) from,(size_t) length); + return((my_string) ptr); +} /* _my_strdup */ diff --git a/ext/mysql/libmysql/str2int.c b/ext/mysql/libmysql/str2int.c new file mode 100644 index 0000000000..c6de1a436a --- /dev/null +++ b/ext/mysql/libmysql/str2int.c @@ -0,0 +1,185 @@ +/* + 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 <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 */ diff --git a/ext/mysql/libmysql/strcend.c b/ext/mysql/libmysql/strcend.c new file mode 100644 index 0000000000..f65eb16837 --- /dev/null +++ b/ext/mysql/libmysql/strcend.c @@ -0,0 +1,39 @@ +/* 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 <global.h> +#include "m_string.h" + +#if defined(MC68000) && defined(DS90) + +char *strcend(const char *s, pchar c) +{ +asm(" movl 4(a7),a0 "); +asm(" movl 8(a7),d1 "); +asm(".L2: movb (a0)+,d0 "); +asm(" cmpb d0,d1 "); +asm(" beq .L1 "); +asm(" tstb d0 "); +asm(" bne .L2 "); +asm(".L1: movl a0,d0 "); +asm(" subql #1,d0 "); +} + +#else + +char *strcend(register const char *s, register pchar c) +{ + for (;;) + { + if (*s == (char) c) return (char*) s; + if (!*s++) return (char*) s-1; + } +} + +#endif diff --git a/ext/mysql/libmysql/strcont.c b/ext/mysql/libmysql/strcont.c new file mode 100644 index 0000000000..5ed0738dec --- /dev/null +++ b/ext/mysql/libmysql/strcont.c @@ -0,0 +1,32 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* 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 <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 */ diff --git a/ext/mysql/libmysql/strend.c b/ext/mysql/libmysql/strend.c new file mode 100644 index 0000000000..18b9d1fbd0 --- /dev/null +++ b/ext/mysql/libmysql/strend.c @@ -0,0 +1,33 @@ +/* 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 <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 */ diff --git a/ext/mysql/libmysql/strfill.c b/ext/mysql/libmysql/strfill.c new file mode 100644 index 0000000000..6a718db9c1 --- /dev/null +++ b/ext/mysql/libmysql/strfill.c @@ -0,0 +1,22 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* 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 <global.h> +#include "m_string.h" + +my_string strfill(my_string s,uint len,pchar fill) +{ + while (len--) *s++ = fill; + *(s) = '\0'; + return(s); +} /* strfill */ diff --git a/ext/mysql/libmysql/string.c b/ext/mysql/libmysql/string.c new file mode 100644 index 0000000000..a14cc138fa --- /dev/null +++ b/ext/mysql/libmysql/string.c @@ -0,0 +1,103 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* + 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, + uint init_alloc, uint alloc_increment) +{ + uint length; + DBUG_ENTER("init_dynamic_string"); + + if (!alloc_increment) + alloc_increment=128; + length=1; + if (init_str && (length=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=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, ulong 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) +{ + char *new_ptr; + uint length=(uint) strlen(append)+1; + if (str->length+length > str->max_length) + { + uint new_length=(str->length+length+str->alloc_increment-1)/ + 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-1; + return FALSE; +} + +void dynstr_free(DYNAMIC_STRING *str) +{ + if (str->str) + { + my_free(str->str,MYF(MY_WME)); + str->str=0; + } +} diff --git a/ext/mysql/libmysql/strinstr.c b/ext/mysql/libmysql/strinstr.c new file mode 100644 index 0000000000..459cfbc3e6 --- /dev/null +++ b/ext/mysql/libmysql/strinstr.c @@ -0,0 +1,36 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* 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 <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); +} diff --git a/ext/mysql/libmysql/strmake.c b/ext/mysql/libmysql/strmake.c new file mode 100644 index 0000000000..65792625ae --- /dev/null +++ b/ext/mysql/libmysql/strmake.c @@ -0,0 +1,39 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* 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. + strmake() returns pointer to closing null; +*/ + +#include <global.h> +#include "m_string.h" + +#ifdef BAD_STRING_COMPILER + +char *strmake(char *dst,const char *src,uint 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, uint length) +{ + while (length--) + if (! (*dst++ = *src++)) + return dst-1; + *dst=0; + return dst; +} diff --git a/ext/mysql/libmysql/strmov.c b/ext/mysql/libmysql/strmov.c new file mode 100644 index 0000000000..b41470aef4 --- /dev/null +++ b/ext/mysql/libmysql/strmov.c @@ -0,0 +1,38 @@ +/* + 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 <global.h> +#include "m_string.h" + +#ifdef BAD_STRING_COMPILER +#undef strmov +#define strmov strmov_overlapp +#endif + +#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 diff --git a/ext/mysql/libmysql/strnmov.c b/ext/mysql/libmysql/strnmov.c new file mode 100644 index 0000000000..2e93908524 --- /dev/null +++ b/ext/mysql/libmysql/strnmov.c @@ -0,0 +1,19 @@ +/* + 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 <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; +} diff --git a/ext/mysql/libmysql/strtoll.c b/ext/mysql/libmysql/strtoll.c new file mode 100644 index 0000000000..3b8f9bf368 --- /dev/null +++ b/ext/mysql/libmysql/strtoll.c @@ -0,0 +1,11 @@ +/* Copyright (C) 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + For a more info consult the file COPYRIGHT distributed with this file */ + +/* This is defines strtoll() if neaded */ + +#include <global.h> +#include <m_string.h> +#if !defined(HAVE_STRTOULL) && defined(HAVE_LONG_LONG) +#define LONGLONG +#include "strto.c" +#endif diff --git a/ext/mysql/libmysql/strtoull.c b/ext/mysql/libmysql/strtoull.c new file mode 100644 index 0000000000..fbb23e0f20 --- /dev/null +++ b/ext/mysql/libmysql/strtoull.c @@ -0,0 +1,12 @@ +/* Copyright (C) 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + For a more info consult the file COPYRIGHT distributed with this file */ + +/* This is defines strtoull() */ + +#include <global.h> +#include <m_string.h> +#if !defined(HAVE_STRTOULL) && defined(HAVE_LONG_LONG) +#define UNSIGNED +#define LONGLONG +#include "strto.c" +#endif diff --git a/ext/mysql/libmysql/strxmov.c b/ext/mysql/libmysql/strxmov.c new file mode 100644 index 0000000000..13811d043f --- /dev/null +++ b/ext/mysql/libmysql/strxmov.c @@ -0,0 +1,33 @@ +/* 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 <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; +} diff --git a/ext/mysql/libmysql/thr_mutex.c b/ext/mysql/libmysql/thr_mutex.c new file mode 100644 index 0000000000..3ac2013efd --- /dev/null +++ b/ext/mysql/libmysql/thr_mutex.c @@ -0,0 +1,198 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* This makes a wrapper for mutex handling to make it easier to debug mutex */ + +#include <global.h> +#ifdef HAVE_LINUXTHREADS /* Some extra safety */ +#define __USE_UNIX98 +#endif +#include <m_string.h> +#if defined(THREAD) && defined(SAFE_MUTEX) +#undef SAFE_MUTEX /* Avoid safe_mutex redefinitions */ +#include <my_pthread.h> + + +/* 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 + +int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr) +{ + bzero((char*) mp,sizeof(*mp)); +#ifdef HAVE_LINUXTHREADS /* Some extra safety */ + { + pthread_mutexattr_t tmp; + pthread_mutexattr_init(&tmp); + pthread_mutexattr_settype(&tmp,PTHREAD_MUTEX_ERRORCHECK_NP); + pthread_mutex_init(&mp->global,&tmp); + pthread_mutex_init(&mp->mutex, &tmp); + pthread_mutexattr_destroy(&tmp); + } +#else + pthread_mutex_init(&mp->global,NULL); + pthread_mutex_init(&mp->mutex,attr); +#endif + 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); + 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); + 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); + 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); + 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); + abort(); + } + mp->count--; + 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); + abort(); + } + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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) +{ + if (mp->count != 0) + { + fprintf(stderr,"safe_mutex: Trying to destroy a mutex that was locked at %s, line %d\n", + mp->file,mp->line); + abort(); + } + pthread_mutex_destroy(&mp->global); + return pthread_mutex_destroy(&mp->mutex); +} + +#endif /* SAFE_MUTEX */ diff --git a/ext/mysql/libmysql/typelib.c b/ext/mysql/libmysql/typelib.c new file mode 100644 index 0000000000..2612d2c9a0 --- /dev/null +++ b/ext/mysql/libmysql/typelib.c @@ -0,0 +1,91 @@ +/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* 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 hole 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; + reg1 my_string i,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) + { + 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 */ + +my_string get_type(TYPELIB *typelib, uint nr) +{ + if (nr < (uint) typelib->count && typelib->type_names) + return(typelib->type_names[nr]); + return((char*) "?"); +} diff --git a/ext/mysql/libmysql/violite.h b/ext/mysql/libmysql/violite.h new file mode 100644 index 0000000000..476e0ea16f --- /dev/null +++ b/ext/mysql/libmysql/violite.h @@ -0,0 +1,101 @@ +/* Copyright Abandoned 2000 Monty Program KB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* + * Vio Lite. + * Purpose: include file for Vio that will work with C and C++ + */ + +#ifndef vio_violite_h_ +#define vio_violite_h_ + +#include "my_net.h" /* needed because of struct in_addr */ + +#ifdef HAVE_VIO +#include <Vio.h> /* Full VIO interface */ +#else + +/* Simple vio interface in C; The functions are implemented in violite.c */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef Vio_defined +#define Vio_defined +struct st_vio; /* Only C */ +typedef struct st_vio Vio; +#endif + +enum enum_vio_type { VIO_CLOSED, VIO_TYPE_TCPIP, VIO_TYPE_SOCKET, + VIO_TYPE_NAMEDPIPE, VIO_TYPE_SSL}; + +Vio* vio_new(my_socket sd, + enum enum_vio_type type, + my_bool localhost); +#ifdef __WIN32__ +Vio* vio_new_win32pipe(HANDLE hPipe); +#endif +void vio_delete(Vio* vio); + +/* + * vio_read and vio_write should have the same semantics + * as read(2) and write(2). + */ +int vio_read( Vio* vio, + gptr buf, int size); +int vio_write( Vio* vio, + const gptr buf, + int size); +/* + * Whenever the socket is set to blocking mode or not. + */ +int vio_blocking( Vio* vio, + my_bool onoff); +my_bool vio_is_blocking( Vio* vio); +/* + * setsockopt TCP_NODELAY at IPPROTO_TCP level, when possible. + */ +int vio_fastsend( Vio* vio, + my_bool onoff); +/* + * setsockopt SO_KEEPALIVE at SOL_SOCKET level, when possible. + */ +int vio_keepalive( Vio* vio, + my_bool onoff); +/* + * Whenever we should retry the last read/write operation. + */ +my_bool vio_should_retry( Vio* vio); +/* + * When the workday is over... + */ +int vio_close( Vio* vio); +/* + * Short text description of the socket for those, who are curious.. + */ +const char* vio_description( Vio* vio); + +/* Return the type of the connection */ + enum enum_vio_type vio_type(Vio* vio); + +/* Return last error number */ +int vio_errno(Vio *vio); + +/* Get socket number */ +my_socket vio_fd(Vio *vio); + +/* + * Remote peer's address and name in text form. + */ +my_bool vio_peer_addr(Vio * vio, char *buf); + +/* Remotes in_addr */ + +void vio_in_addr(Vio *vio, struct in_addr *in); + +#ifdef __cplusplus +} +#endif +#endif /* HAVE_VIO */ +#endif /* vio_violite_h_ */ |