summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndi Gutmans <andi@php.net>2000-02-19 10:10:46 +0000
committerAndi Gutmans <andi@php.net>2000-02-19 10:10:46 +0000
commit0cda28f77bcea25a35b2d55ee1bb52c5fdb34f2a (patch)
tree11e6fbfcc15fe72ed98e6736d84b47ac9250fcc0
parentfe9abd3219b097e0c0f2c9106751d35b2bede2d6 (diff)
downloadphp-git-0cda28f77bcea25a35b2d55ee1bb52c5fdb34f2a.tar.gz
- Add libmysql to the tree
-rw-r--r--ext/mysql/libmysql/Makefile8
-rw-r--r--ext/mysql/libmysql/array.c163
-rw-r--r--ext/mysql/libmysql/bchange.c25
-rw-r--r--ext/mysql/libmysql/bmove.c63
-rw-r--r--ext/mysql/libmysql/bmove_upp.c37
-rw-r--r--ext/mysql/libmysql/config-win32.h174
-rw-r--r--ext/mysql/libmysql/configure.in180
-rw-r--r--ext/mysql/libmysql/ct_init.c6
-rw-r--r--ext/mysql/libmysql/ctype-latin1.c139
-rw-r--r--ext/mysql/libmysql/dbug.c2074
-rw-r--r--ext/mysql/libmysql/dbug.h75
-rw-r--r--ext/mysql/libmysql/default.c345
-rw-r--r--ext/mysql/libmysql/errmsg.h33
-rw-r--r--ext/mysql/libmysql/errors.c68
-rw-r--r--ext/mysql/libmysql/global.h786
-rw-r--r--ext/mysql/libmysql/int2str.c97
-rw-r--r--ext/mysql/libmysql/is_prefix.c20
-rw-r--r--ext/mysql/libmysql/list.c100
-rw-r--r--ext/mysql/libmysql/longlong2str.c81
-rw-r--r--ext/mysql/libmysql/m_ctype.h231
-rw-r--r--ext/mysql/libmysql/m_string.h209
-rw-r--r--ext/mysql/libmysql/mf_casecnv.c195
-rw-r--r--ext/mysql/libmysql/mf_dirname.c92
-rw-r--r--ext/mysql/libmysql/mf_fn_ext.c31
-rw-r--r--ext/mysql/libmysql/mf_format.c132
-rw-r--r--ext/mysql/libmysql/mf_loadpath.c39
-rw-r--r--ext/mysql/libmysql/mf_pack.c472
-rw-r--r--ext/mysql/libmysql/mf_path.c106
-rw-r--r--ext/mysql/libmysql/mf_unixpath.c19
-rw-r--r--ext/mysql/libmysql/mf_wcomp.c54
-rw-r--r--ext/mysql/libmysql/mulalloc.c39
-rw-r--r--ext/mysql/libmysql/my_alarm.h46
-rw-r--r--ext/mysql/libmysql/my_alloc.c115
-rw-r--r--ext/mysql/libmysql/my_compress.c73
-rw-r--r--ext/mysql/libmysql/my_config.h650
-rw-r--r--ext/mysql/libmysql/my_create.c66
-rw-r--r--ext/mysql/libmysql/my_delete.c22
-rw-r--r--ext/mysql/libmysql/my_dir.h85
-rw-r--r--ext/mysql/libmysql/my_div.c17
-rw-r--r--ext/mysql/libmysql/my_error.c105
-rw-r--r--ext/mysql/libmysql/my_fopen.c150
-rw-r--r--ext/mysql/libmysql/my_getwd.c168
-rw-r--r--ext/mysql/libmysql/my_init.c282
-rw-r--r--ext/mysql/libmysql/my_list.h33
-rw-r--r--ext/mysql/libmysql/my_malloc.c70
-rw-r--r--ext/mysql/libmysql/my_messnc.c22
-rw-r--r--ext/mysql/libmysql/my_net.c29
-rw-r--r--ext/mysql/libmysql/my_net.h10
-rw-r--r--ext/mysql/libmysql/my_once.c74
-rw-r--r--ext/mysql/libmysql/my_open.c83
-rw-r--r--ext/mysql/libmysql/my_pthread.c462
-rw-r--r--ext/mysql/libmysql/my_pthread.h494
-rw-r--r--ext/mysql/libmysql/my_read.c52
-rw-r--r--ext/mysql/libmysql/my_realloc.c51
-rw-r--r--ext/mysql/libmysql/my_static.c86
-rw-r--r--ext/mysql/libmysql/my_static.h68
-rw-r--r--ext/mysql/libmysql/my_sys.h504
-rw-r--r--ext/mysql/libmysql/my_tempnam.c128
-rw-r--r--ext/mysql/libmysql/my_thr_init.c177
-rw-r--r--ext/mysql/libmysql/my_write.c63
-rw-r--r--ext/mysql/libmysql/mysql.h257
-rw-r--r--ext/mysql/libmysql/mysql_com.h211
-rw-r--r--ext/mysql/libmysql/mysql_version.h10
-rw-r--r--ext/mysql/libmysql/mysqld_error.h179
-rw-r--r--ext/mysql/libmysql/mysys_err.h42
-rw-r--r--ext/mysql/libmysql/mysys_priv.h13
-rw-r--r--ext/mysql/libmysql/safemalloc.c503
-rw-r--r--ext/mysql/libmysql/str2int.c185
-rw-r--r--ext/mysql/libmysql/strcend.c39
-rw-r--r--ext/mysql/libmysql/strcont.c32
-rw-r--r--ext/mysql/libmysql/strend.c33
-rw-r--r--ext/mysql/libmysql/strfill.c22
-rw-r--r--ext/mysql/libmysql/string.c103
-rw-r--r--ext/mysql/libmysql/strinstr.c36
-rw-r--r--ext/mysql/libmysql/strmake.c39
-rw-r--r--ext/mysql/libmysql/strmov.c38
-rw-r--r--ext/mysql/libmysql/strnmov.c19
-rw-r--r--ext/mysql/libmysql/strtoll.c11
-rw-r--r--ext/mysql/libmysql/strtoull.c12
-rw-r--r--ext/mysql/libmysql/strxmov.c33
-rw-r--r--ext/mysql/libmysql/thr_mutex.c198
-rw-r--r--ext/mysql/libmysql/typelib.c91
-rw-r--r--ext/mysql/libmysql/violite.h101
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_ */